open-mem 0.14.0 → 0.14.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/README.md +58 -1
- package/dist/claude-code.js +88 -87
- package/dist/cursor.js +88 -87
- package/dist/daemon/manager.d.ts +33 -5
- package/dist/daemon/manager.d.ts.map +1 -1
- package/dist/daemon/pid.d.ts +23 -0
- package/dist/daemon/pid.d.ts.map +1 -1
- package/dist/daemon.js +35 -34
- package/dist/db/advisory-lock.d.ts +40 -0
- package/dist/db/advisory-lock.d.ts.map +1 -0
- package/dist/db/database.d.ts +37 -4
- package/dist/db/database.d.ts.map +1 -1
- package/dist/doctor.js +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +99 -98
- package/dist/maintenance.js +48 -45
- package/dist/mcp.js +72 -71
- package/dist/platform-worker.d.ts.map +1 -1
- package/dist/runtime/queue-runtime.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
var H2=Object.create;var{getPrototypeOf:F2,defineProperty:QS,getOwnPropertyNames:T2}=Object;var u2=Object.prototype.hasOwnProperty;var x2=(S,M,f)=>{f=S!=null?H2(F2(S)):{};let $=M||!S||!S.__esModule?QS(f,"default",{value:S,enumerable:!0}):f;for(let A of T2(S))if(!u2.call($,A))QS($,A,{get:()=>S[A],enumerable:!0});return $};var U1=(S,M)=>{for(var f in M)QS(S,f,{get:M[f],enumerable:!0,configurable:!0,set:($)=>M[f]=()=>$})};var C0=(S,M)=>()=>(S&&(M=S(S=0)),M);var m=import.meta.require;import{existsSync as d2,readdirSync as s2,readFileSync as a2}from"fs";import{join as e2}from"path";function n(S){return{...S,observationTypes:[...S.observationTypes],conceptVocabulary:[...S.conceptVocabulary],entityTypes:[...S.entityTypes],relationshipTypes:[...S.relationshipTypes],promptOverrides:S.promptOverrides?{...S.promptOverrides}:void 0}}function o2(S){if(!S||typeof S!=="object")return!1;let M=S,f=(A)=>Array.isArray(A)&&A.every((O)=>typeof O==="string"),$=(A)=>typeof A==="object"&&A!==null&&!Array.isArray(A)&&Object.values(A).every((O)=>typeof O==="string");return typeof M.id==="string"&&(M.extends===void 0||typeof M.extends==="string")&&(M.locale===void 0||typeof M.locale==="string")&&(M.name===void 0||typeof M.name==="string")&&(M.description===void 0||typeof M.description==="string")&&(M.observationTypes===void 0||f(M.observationTypes))&&(M.conceptVocabulary===void 0||f(M.conceptVocabulary))&&(M.entityTypes===void 0||f(M.entityTypes))&&(M.relationshipTypes===void 0||f(M.relationshipTypes))&&(M.promptOverrides===void 0||$(M.promptOverrides))}function Sf(S){return typeof S.name==="string"&&typeof S.description==="string"&&Array.isArray(S.observationTypes)&&Array.isArray(S.conceptVocabulary)&&Array.isArray(S.entityTypes)&&Array.isArray(S.relationshipTypes)}function p1(S,M){return{...S,...M,id:M.id,name:M.name??S.name,description:M.description??S.description,observationTypes:M.observationTypes??S.observationTypes,conceptVocabulary:M.conceptVocabulary??S.conceptVocabulary,entityTypes:M.entityTypes??S.entityTypes,relationshipTypes:M.relationshipTypes??S.relationshipTypes,promptOverrides:{...S.promptOverrides??{},...M.promptOverrides??{}}}}class US{modesDir;constructor(S){this.modesDir=S}loadAllRaw(){let S=new Map;if(!d2(this.modesDir))return S;for(let M of s2(this.modesDir)){if(!M.endsWith(".json"))continue;let f=e2(this.modesDir,M);try{let $=a2(f,"utf-8"),A=JSON.parse($);if(!o2(A))continue;if(S.has(A.id))console.warn(`[open-mem] Duplicate mode id "${A.id}" in ${f}; overriding previous definition.`);S.set(A.id,A)}catch{}}return S}resolveById(S,M){let f=new Set,$=!1,A=(y)=>{if(f.has(y))return $=!0,n(f0);f.add(y);let N=M.get(y);if(!N)return n(f0);if(!N.extends){if(!Sf(N))return n(f0);return p1(n(f0),N)}let V=A(N.extends);if($)return n(f0);return p1(V,N)},O=A(S);return $?n(f0):n(O)}}var f0;var n1=C0(()=>{f0={id:"code",name:"Code",description:"Default coding workflow mode",observationTypes:["decision","bugfix","feature","refactor","discovery","change"],conceptVocabulary:["how-it-works","why-it-exists","what-changed","problem-solution","gotcha","pattern","trade-off"],entityTypes:["technology","library","pattern","concept","file","person","project","other"],relationshipTypes:["uses","depends_on","implements","extends","related_to","replaces","configures"]}});import{join as Mf}from"path";function t1(){if(m0)return m0;return m0=r1.loadAllRaw(),m0}function i1(S){return r1.resolveById(S,t1())}function h0(){return[...t1().keys()].sort()}var ff,r1,m0=null;var DS=C0(()=>{n1();ff=Mf(import.meta.dir,"."),r1=new US(ff)});import{existsSync as $f,readFileSync as Af}from"fs";function Of(){let S={};if(process.env.OPEN_MEM_DB_PATH)S.dbPath=process.env.OPEN_MEM_DB_PATH;if(process.env.OPEN_MEM_PROVIDER)S.provider=process.env.OPEN_MEM_PROVIDER;if(process.env.OPEN_MEM_MODEL)S.model=process.env.OPEN_MEM_MODEL;if(process.env.OPEN_MEM_MAX_CONTEXT_TOKENS)S.maxContextTokens=Number.parseInt(process.env.OPEN_MEM_MAX_CONTEXT_TOKENS,10);if(process.env.OPEN_MEM_COMPRESSION==="false")S.compressionEnabled=!1;if(process.env.OPEN_MEM_CONTEXT_INJECTION==="false")S.contextInjectionEnabled=!1;if(process.env.OPEN_MEM_IGNORED_TOOLS)S.ignoredTools=process.env.OPEN_MEM_IGNORED_TOOLS.split(",").map((M)=>M.trim());if(process.env.OPEN_MEM_BATCH_SIZE)S.batchSize=Number.parseInt(process.env.OPEN_MEM_BATCH_SIZE,10);if(process.env.OPEN_MEM_RETENTION_DAYS)S.retentionDays=Number.parseInt(process.env.OPEN_MEM_RETENTION_DAYS,10);if(process.env.OPEN_MEM_LOG_LEVEL)S.logLevel=process.env.OPEN_MEM_LOG_LEVEL;if(process.env.OPEN_MEM_CONTEXT_SHOW_TOKEN_COSTS==="false")S.contextShowTokenCosts=!1;if(process.env.OPEN_MEM_CONTEXT_TYPES)S.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)S.contextFullObservationCount=Number.parseInt(process.env.OPEN_MEM_CONTEXT_FULL_COUNT,10);if(process.env.OPEN_MEM_MAX_OBSERVATIONS)S.maxObservations=Number.parseInt(process.env.OPEN_MEM_MAX_OBSERVATIONS,10);if(process.env.OPEN_MEM_CONTEXT_SHOW_LAST_SUMMARY==="false")S.contextShowLastSummary=!1;if(process.env.OPEN_MEM_RATE_LIMITING==="false")S.rateLimitingEnabled=!1;if(process.env.OPEN_MEM_FOLDER_CONTEXT==="false")S.folderContextEnabled=!1;if(process.env.OPEN_MEM_FOLDER_CONTEXT_MAX_DEPTH)S.folderContextMaxDepth=Number.parseInt(process.env.OPEN_MEM_FOLDER_CONTEXT_MAX_DEPTH,10);if(process.env.OPEN_MEM_FOLDER_CONTEXT_MODE==="single")S.folderContextMode="single";if(process.env.OPEN_MEM_FOLDER_CONTEXT_MODE==="dispersed")S.folderContextMode="dispersed";if(process.env.OPEN_MEM_FOLDER_CONTEXT_FILENAME)S.folderContextFilename=process.env.OPEN_MEM_FOLDER_CONTEXT_FILENAME;if(process.env.OPEN_MEM_DAEMON==="true")S.daemonEnabled=!0;if(process.env.OPEN_MEM_DASHBOARD==="true")S.dashboardEnabled=!0;if(process.env.OPEN_MEM_DASHBOARD_PORT)S.dashboardPort=Number.parseInt(process.env.OPEN_MEM_DASHBOARD_PORT,10);if(process.env.OPEN_MEM_PLATFORM_OPENCODE==="false")S.platformOpenCodeEnabled=!1;if(process.env.OPEN_MEM_PLATFORM_CLAUDE_CODE==="true")S.platformClaudeCodeEnabled=!0;if(process.env.OPEN_MEM_PLATFORM_CURSOR==="true")S.platformCursorEnabled=!0;if(process.env.OPEN_MEM_MCP_PROTOCOL_VERSION)S.mcpProtocolVersion=process.env.OPEN_MEM_MCP_PROTOCOL_VERSION;if(process.env.OPEN_MEM_MCP_SUPPORTED_PROTOCOLS)S.mcpSupportedProtocolVersions=process.env.OPEN_MEM_MCP_SUPPORTED_PROTOCOLS.split(",").map((M)=>M.trim()).filter(Boolean);if(process.env.OPEN_MEM_EMBEDDING_DIMENSION)S.embeddingDimension=Number.parseInt(process.env.OPEN_MEM_EMBEDDING_DIMENSION,10);if(process.env.OPEN_MEM_CONFLICT_RESOLUTION==="true")S.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))S.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))S.conflictSimilarityBandHigh=M}if(process.env.OPEN_MEM_USER_MEMORY==="true")S.userMemoryEnabled=!0;if(process.env.OPEN_MEM_USER_MEMORY_DB_PATH)S.userMemoryDbPath=process.env.OPEN_MEM_USER_MEMORY_DB_PATH;if(process.env.OPEN_MEM_USER_MEMORY_MAX_TOKENS)S.userMemoryMaxContextTokens=Number.parseInt(process.env.OPEN_MEM_USER_MEMORY_MAX_TOKENS,10);if(process.env.OPEN_MEM_RERANKING==="true")S.rerankingEnabled=!0;if(process.env.OPEN_MEM_RERANKING_MAX_CANDIDATES)S.rerankingMaxCandidates=Number.parseInt(process.env.OPEN_MEM_RERANKING_MAX_CANDIDATES,10);if(process.env.OPEN_MEM_ENTITY_EXTRACTION==="true")S.entityExtractionEnabled=!0;if(process.env.OPEN_MEM_FALLBACK_PROVIDERS)S.fallbackProviders=process.env.OPEN_MEM_FALLBACK_PROVIDERS.split(",").map((M)=>M.trim()).filter(Boolean);if(process.env.OPEN_MEM_MODE)S.mode=process.env.OPEN_MEM_MODE;return S}function yf(S){let M=`${S}/.open-mem/config.json`;if(!$f(M))return{};try{let f=Af(M,"utf-8"),$=JSON.parse(f);if(!$||typeof $!=="object"||Array.isArray($))return{};return $}catch{return{}}}function Ef(S){switch(S){case"google":return 768;case"openai":return 1536;case"bedrock":return 1024;case"anthropic":return 0;case"openrouter":return 0;default:return 768}}function R0(S,M){let f=yf(S),$=Of(),A={...d1,...f,...$,...M};if(!A.dbPath.startsWith("/"))A.dbPath=`${S}/${A.dbPath}`;if(!process.env.OPEN_MEM_PROVIDER&&!M?.provider){if(process.env.GOOGLE_GENERATIVE_AI_API_KEY||process.env.GEMINI_API_KEY)A.provider="google";else if(process.env.ANTHROPIC_API_KEY)A.provider="anthropic";else if(process.env.AWS_BEARER_TOKEN_BEDROCK||process.env.AWS_ACCESS_KEY_ID||process.env.AWS_PROFILE)A.provider="bedrock";else if(process.env.OPENROUTER_API_KEY)A.provider="openrouter"}if(!A.apiKey)switch(A.provider){case"google":A.apiKey=process.env.GOOGLE_GENERATIVE_AI_API_KEY||process.env.GEMINI_API_KEY;break;case"anthropic":A.apiKey=process.env.ANTHROPIC_API_KEY;break;case"openai":A.apiKey=process.env.OPENAI_API_KEY;break;case"openrouter":A.apiKey=process.env.OPENROUTER_API_KEY;break;case"bedrock":break}if(A.provider==="openrouter"&&A.model==="gemini-2.5-flash-lite")A.model="google/gemini-2.5-flash-lite";if(A.embeddingDimension===void 0)A.embeddingDimension=Ef(A.provider);if(A.mode&&!h0().includes(A.mode))A.mode="code";return A}function s1(S){let M=[],f=S.provider!=="bedrock";if(S.compressionEnabled&&f&&!S.apiKey)M.push("AI compression enabled but no API key found. Get a free Gemini API key at https://aistudio.google.com/apikey and set GOOGLE_GENERATIVE_AI_API_KEY, or set OPEN_MEM_PROVIDER and the appropriate API key for your provider.");if(S.maxContextTokens<500)M.push("maxContextTokens must be at least 500");if(S.batchSize<1)M.push("batchSize must be at least 1");if(S.minOutputLength<0)M.push("minOutputLength must be non-negative");return M}function LS(){return{...d1}}async function a1(S){let M=S.dbPath.substring(0,S.dbPath.lastIndexOf("/")),{mkdir:f}=await import("fs/promises");await f(M,{recursive:!0})}var d1;var GS=C0(()=>{DS();d1={dbPath:".open-mem/memory.db",provider:"google",apiKey:void 0,model:"gemini-2.5-flash-lite",maxTokensPerCompression:1024,compressionEnabled:!0,contextInjectionEnabled:!0,maxContextTokens:4000,batchSize:5,batchIntervalMs:30000,ignoredTools:[],minOutputLength:50,maxIndexEntries:20,sensitivePatterns:[],retentionDays:90,maxDatabaseSizeMb:500,logLevel:"warn",contextShowTokenCosts:!0,contextObservationTypes:"all",contextFullObservationCount:3,maxObservations:50,contextShowLastSummary:!0,rateLimitingEnabled:!0,folderContextEnabled:!0,folderContextMaxDepth:5,folderContextMode:"dispersed",folderContextFilename:"AGENTS.md",daemonEnabled:!1,dashboardEnabled:!1,dashboardPort:3737,platformOpenCodeEnabled:!0,platformClaudeCodeEnabled:!1,platformCursorEnabled:!1,mcpProtocolVersion:"2024-11-05",mcpSupportedProtocolVersions:["2024-11-05"],embeddingDimension:void 0,conflictResolutionEnabled:!1,conflictSimilarityBandLow:0.7,conflictSimilarityBandHigh:0.92,userMemoryEnabled:!1,userMemoryDbPath:"~/.config/open-mem/user-memory.db",userMemoryMaxContextTokens:1000,rerankingEnabled:!1,rerankingMaxCandidates:20,entityExtractionEnabled:!1,fallbackProviders:void 0,mode:"code"}});var fM={};U1(fM,{writeProjectConfig:()=>MM,validatePatch:()=>HS,readProjectConfig:()=>t,previewConfig:()=>FS,patchConfig:()=>q0,getEffectiveConfig:()=>r,getConfigSchema:()=>CS});import{existsSync as Nf}from"fs";import{mkdir as Vf,readFile as Jf,writeFile as Qf}from"fs/promises";import{dirname as _f,join as Bf}from"path";function o1(S){return Bf(S,".open-mem","config.json")}function SM(S){return e1.find((M)=>M.key===S)}function Xf(S,M){let f=SM(S);if(!f)return null;if(f.type==="string"&&typeof M!=="string")return`${String(S)} must be a string`;if(f.type==="number"&&typeof M!=="number")return`${String(S)} must be a number`;if(f.type==="boolean"&&typeof M!=="boolean")return`${String(S)} must be a boolean`;if(f.type==="array"&&!Array.isArray(M))return`${String(S)} must be an array`;if(f.enum&&typeof M==="string"&&!f.enum.includes(M))return`${String(S)} must be one of: ${f.enum.join(", ")}`;if(typeof M==="number"){if(f.min!==void 0&&M<f.min)return`${String(S)} must be >= ${f.min}`;if(f.max!==void 0&&M>f.max)return`${String(S)} must be <= ${f.max}`}return null}function CS(){return e1}async function t(S){let M=o1(S);if(!Nf(M))return{};try{let f=await Jf(M,"utf-8"),$=JSON.parse(f);if(!$||typeof $!=="object"||Array.isArray($))return{};return $}catch{return{}}}async function MM(S,M){let f=o1(S),A={...await t(S),...M};await Vf(_f(f),{recursive:!0}),await Qf(f,JSON.stringify(A,null,2),"utf-8")}function HS(S){let M=[];for(let[f,$]of Object.entries(S)){let O=Xf(f,$);if(O)M.push(O)}return M}async function r(S){let M=LS(),f=await t(S),$=R0(S),A=[],O={};for(let[y,N]of Object.entries(M)){let V=y,E=SM(V),Q=(Wf[V]??[]).some((X)=>typeof process.env[X]==="string"),_=Object.hasOwn(f,V),B="default";if(_)B="file";if(Q)B="env";if(O[V]={source:B,locked:Q,restartRequired:E?.restartRequired??!1,liveApply:E?.liveApply??!1},B==="env"&&_)A.push(`${String(V)} is overridden by environment variable.`);if($[V]===void 0&&N!==void 0)A.push(`${String(V)} resolved to undefined unexpectedly.`)}return{config:$,meta:O,warnings:A}}async function FS(S,M){let f=HS(M);if(f.length>0)return{...await r(S),warnings:f};let $=LS(),A=await t(S),O={...$,...A,...M},N={...R0(S,M),...O},V=(await r(S)).meta;return{config:N,meta:V,warnings:[]}}async function q0(S,M){let f=HS(M);if(f.length>0)return{...await r(S),warnings:f};return await MM(S,M),r(S)}var e1,Wf;var TS=C0(()=>{GS();e1=[{key:"dbPath",label:"Database Path",type:"string",group:"Storage",liveApply:!1,restartRequired:!0},{key:"provider",label:"Provider",type:"string",group:"AI",liveApply:!1,restartRequired:!0,enum:["google","anthropic","openai","bedrock"]},{key:"model",label:"Model",type:"string",group:"AI",liveApply:!1,restartRequired:!0},{key:"maxTokensPerCompression",label:"Max Tokens Per Compression",type:"number",group:"AI",liveApply:!0,restartRequired:!1,min:128,max:8192},{key:"compressionEnabled",label:"Compression Enabled",type:"boolean",group:"Behavior",liveApply:!0,restartRequired:!1},{key:"contextInjectionEnabled",label:"Context Injection Enabled",type:"boolean",group:"Behavior",liveApply:!0,restartRequired:!1},{key:"maxContextTokens",label:"Max Context Tokens",type:"number",group:"Behavior",liveApply:!0,restartRequired:!1,min:500,max:64000},{key:"batchSize",label:"Batch Size",type:"number",group:"Behavior",liveApply:!0,restartRequired:!1,min:1,max:100},{key:"batchIntervalMs",label:"Batch Interval (ms)",type:"number",group:"Behavior",liveApply:!0,restartRequired:!1,min:1000,max:300000},{key:"ignoredTools",label:"Ignored Tools",type:"array",group:"Filtering",liveApply:!0,restartRequired:!1},{key:"minOutputLength",label:"Min Output Length",type:"number",group:"Filtering",liveApply:!0,restartRequired:!1,min:0,max:1e4},{key:"maxObservations",label:"Max Observations",type:"number",group:"Progressive Disclosure",liveApply:!0,restartRequired:!1,min:1,max:200},{key:"contextFullObservationCount",label:"Full Observation Count",type:"number",group:"Progressive Disclosure",liveApply:!0,restartRequired:!1,min:0,max:20},{key:"contextShowTokenCosts",label:"Show Token Costs",type:"boolean",group:"Progressive Disclosure",liveApply:!0,restartRequired:!1},{key:"sensitivePatterns",label:"Sensitive Patterns",type:"array",group:"Privacy",liveApply:!0,restartRequired:!1},{key:"retentionDays",label:"Retention Days",type:"number",group:"Data Retention",liveApply:!1,restartRequired:!0,min:0,max:3650},{key:"maxDatabaseSizeMb",label:"Max Database Size (MB)",type:"number",group:"Data Retention",liveApply:!1,restartRequired:!0,min:0,max:1e5},{key:"dashboardEnabled",label:"Dashboard Enabled",type:"boolean",group:"Dashboard",liveApply:!1,restartRequired:!0},{key:"dashboardPort",label:"Dashboard Port",type:"number",group:"Dashboard",liveApply:!1,restartRequired:!0,min:1,max:65535},{key:"platformOpenCodeEnabled",label:"OpenCode Adapter",type:"boolean",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"platformClaudeCodeEnabled",label:"Claude Code Adapter",type:"boolean",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"platformCursorEnabled",label:"Cursor Adapter",type:"boolean",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"mcpProtocolVersion",label:"MCP Protocol Version",type:"string",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"mcpSupportedProtocolVersions",label:"MCP Supported Protocols",type:"array",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"rerankingEnabled",label:"Reranking Enabled",type:"boolean",group:"Advanced",liveApply:!0,restartRequired:!1},{key:"entityExtractionEnabled",label:"Entity Extraction Enabled",type:"boolean",group:"Advanced",liveApply:!0,restartRequired:!1},{key:"userMemoryEnabled",label:"User Memory Enabled",type:"boolean",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"userMemoryMaxContextTokens",label:"User Memory Max Context Tokens",type:"number",group:"Advanced",liveApply:!0,restartRequired:!1,min:0,max:8000}],Wf={dbPath:["OPEN_MEM_DB_PATH"],provider:["OPEN_MEM_PROVIDER"],model:["OPEN_MEM_MODEL"],compressionEnabled:["OPEN_MEM_COMPRESSION"],contextInjectionEnabled:["OPEN_MEM_CONTEXT_INJECTION"],maxContextTokens:["OPEN_MEM_MAX_CONTEXT_TOKENS"],ignoredTools:["OPEN_MEM_IGNORED_TOOLS"],batchSize:["OPEN_MEM_BATCH_SIZE"],retentionDays:["OPEN_MEM_RETENTION_DAYS"],contextShowTokenCosts:["OPEN_MEM_CONTEXT_SHOW_TOKEN_COSTS"],contextFullObservationCount:["OPEN_MEM_CONTEXT_FULL_COUNT"],maxObservations:["OPEN_MEM_MAX_OBSERVATIONS"],dashboardEnabled:["OPEN_MEM_DASHBOARD"],dashboardPort:["OPEN_MEM_DASHBOARD_PORT"],platformOpenCodeEnabled:["OPEN_MEM_PLATFORM_OPENCODE"],platformClaudeCodeEnabled:["OPEN_MEM_PLATFORM_CLAUDE_CODE"],platformCursorEnabled:["OPEN_MEM_PLATFORM_CURSOR"],mcpProtocolVersion:["OPEN_MEM_MCP_PROTOCOL_VERSION"],mcpSupportedProtocolVersions:["OPEN_MEM_MCP_SUPPORTED_PROTOCOLS"],rerankingEnabled:["OPEN_MEM_RERANKING"],userMemoryEnabled:["OPEN_MEM_USER_MEMORY"]}});var U2={};U1(U2,{createOpenCodeBridge:()=>NA});function NA(S){let M=S;if(!M?.session?.create||!M?.session?.prompt)return null;let f=null,$=null;async function A(){if(f)return f;if($)return $;return $=(async()=>{try{let V=(await M.session.create({body:{title:"[open-mem] AI compression"}}))?.data?.id;if(!V)throw Error("No session ID returned");return f=V,V}finally{$=null}})(),$}async function O(N){let V=await A(),E=N.prompt||"";return{text:((await M.session.prompt({path:{id:V},body:{parts:[{type:"text",text:E}],system:N.system,tools:{},noReply:!1}}))?.data?.parts||[]).filter((B)=>B.type==="text").map((B)=>B.text||"").join(""),finishReason:"stop",usage:{promptTokens:0,completionTokens:0,totalTokens:0}}}async function y(){if(f){try{await M.session.delete({path:{id:f}})}catch{}f=null}}return{generateText:O,cleanup:y}}import{existsSync as VA}from"fs";import{dirname as JA,join as o}from"path";import{fileURLToPath as QA}from"url";var j2=new Set(["127.0.0.1","::1","localhost"]);function k2(S){return S.trim().toLowerCase()}function I2(S){return j2.has(k2(S))}function D1(S,M){if(I2(S))return;throw Error(`[open-mem] ${M} must bind to loopback only (127.0.0.1, ::1, localhost). Received "${S}".`)}import{randomUUID as Z0}from"crypto";import{normalize as Kf,resolve as kS,sep as $M}from"path";import{fileURLToPath as Yf}from"url";var _S=(S,M,f)=>{return($,A)=>{let O=-1;return y(0);async function y(N){if(N<=O)throw Error("next() called multiple times");O=N;let V,E=!1,J;if(S[N])J=S[N][0][0],$.req.routeIndex=N;else J=N===S.length&&A||void 0;if(J)try{V=await J($,()=>y(N+1))}catch(Q){if(Q instanceof Error&&M)$.error=Q,V=await M(Q,$),E=!0;else throw Q}else if($.finalized===!1&&f)V=await f($);if(V&&($.finalized===!1||E))$.res=V;return $}}};var L1=Symbol();var G1=async(S,M=Object.create(null))=>{let{all:f=!1,dot:$=!1}=M,O=(S instanceof H0?S.raw.headers:S.headers).get("Content-Type");if(O?.startsWith("multipart/form-data")||O?.startsWith("application/x-www-form-urlencoded"))return w2(S,{all:f,dot:$});return{}};async function w2(S,M){let f=await S.formData();if(f)return g2(f,M);return{}}function g2(S,M){let f=Object.create(null);if(S.forEach(($,A)=>{if(!(M.all||A.endsWith("[]")))f[A]=$;else m2(f,A,$)}),M.dot)Object.entries(f).forEach(([$,A])=>{if($.includes("."))h2(f,$,A),delete f[$]});return f}var m2=(S,M,f)=>{if(S[M]!==void 0)if(Array.isArray(S[M]))S[M].push(f);else S[M]=[S[M],f];else if(!M.endsWith("[]"))S[M]=f;else S[M]=[f]},h2=(S,M,f)=>{let $=S,A=M.split(".");A.forEach((O,y)=>{if(y===A.length-1)$[O]=f;else{if(!$[O]||typeof $[O]!=="object"||Array.isArray($[O])||$[O]instanceof File)$[O]=Object.create(null);$=$[O]}})};var WS=(S)=>{let M=S.split("/");if(M[0]==="")M.shift();return M},C1=(S)=>{let{groups:M,path:f}=q2(S),$=WS(f);return P2($,M)},q2=(S)=>{let M=[];return S=S.replace(/\{[^}]+\}/g,(f,$)=>{let A=`@${$}`;return M.push([A,f]),A}),{groups:M,path:S}},P2=(S,M)=>{for(let f=M.length-1;f>=0;f--){let[$]=M[f];for(let A=S.length-1;A>=0;A--)if(S[A].includes($)){S[A]=S[A].replace($,M[f][1]);break}}return S},F0={},H1=(S,M)=>{if(S==="*")return"*";let f=S.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);if(f){let $=`${S}#${M}`;if(!F0[$])if(f[2])F0[$]=M&&M[0]!==":"&&M[0]!=="*"?[$,f[1],new RegExp(`^${f[2]}(?=/${M})`)]:[S,f[1],new RegExp(`^${f[2]}$`)];else F0[$]=[S,f[1],!0];return F0[$]}return null},T0=(S,M)=>{try{return M(S)}catch{return S.replace(/(?:%[0-9A-Fa-f]{2})+/g,(f)=>{try{return M(f)}catch{return f}})}},v2=(S)=>T0(S,decodeURI),XS=(S)=>{let M=S.url,f=M.indexOf("/",M.indexOf(":")+4),$=f;for(;$<M.length;$++){let A=M.charCodeAt($);if(A===37){let O=M.indexOf("?",$),y=M.slice(f,O===-1?void 0:O);return v2(y.includes("%25")?y.replace(/%25/g,"%2525"):y)}else if(A===63)break}return M.slice(f,$)};var F1=(S)=>{let M=XS(S);return M.length>1&&M.at(-1)==="/"?M.slice(0,-1):M},b=(S,M,...f)=>{if(f.length)M=b(M,...f);return`${S?.[0]==="/"?"":"/"}${S}${M==="/"?"":`${S?.at(-1)==="/"?"":"/"}${M?.[0]==="/"?M.slice(1):M}`}`},u0=(S)=>{if(S.charCodeAt(S.length-1)!==63||!S.includes(":"))return null;let M=S.split("/"),f=[],$="";return M.forEach((A)=>{if(A!==""&&!/\:/.test(A))$+="/"+A;else if(/\:/.test(A))if(/\?/.test(A)){if(f.length===0&&$==="")f.push("/");else f.push($);let O=A.replace("?","");$+="/"+O,f.push($)}else $+="/"+A}),f.filter((A,O,y)=>y.indexOf(A)===O)},BS=(S)=>{if(!/[%+]/.test(S))return S;if(S.indexOf("+")!==-1)S=S.replace(/\+/g," ");return S.indexOf("%")!==-1?T0(S,RS):S},T1=(S,M,f)=>{let $;if(!f&&M&&!/[%+]/.test(M)){let y=S.indexOf("?",8);if(y===-1)return;if(!S.startsWith(M,y+1))y=S.indexOf(`&${M}`,y+1);while(y!==-1){let N=S.charCodeAt(y+M.length+1);if(N===61){let V=y+M.length+2,E=S.indexOf("&",V);return BS(S.slice(V,E===-1?void 0:E))}else if(N==38||isNaN(N))return"";y=S.indexOf(`&${M}`,y+1)}if($=/[%+]/.test(S),!$)return}let A={};$??=/[%+]/.test(S);let O=S.indexOf("?",8);while(O!==-1){let y=S.indexOf("&",O+1),N=S.indexOf("=",O);if(N>y&&y!==-1)N=-1;let V=S.slice(O+1,N===-1?y===-1?void 0:y:N);if($)V=BS(V);if(O=y,V==="")continue;let E;if(N===-1)E="";else if(E=S.slice(N+1,y===-1?void 0:y),$)E=BS(E);if(f){if(!(A[V]&&Array.isArray(A[V])))A[V]=[];A[V].push(E)}else A[V]??=E}return M?A[M]:A},u1=T1,x1=(S,M)=>{return T1(S,M,!0)},RS=decodeURIComponent;var j1=(S)=>T0(S,RS),H0=class{raw;#S;#M;routeIndex=0;path;bodyCache={};constructor(S,M="/",f=[[]]){this.raw=S,this.path=M,this.#M=f,this.#S={}}param(S){return S?this.#f(S):this.#O()}#f(S){let M=this.#M[0][this.routeIndex][1][S],f=this.#A(M);return f&&/\%/.test(f)?j1(f):f}#O(){let S={},M=Object.keys(this.#M[0][this.routeIndex][1]);for(let f of M){let $=this.#A(this.#M[0][this.routeIndex][1][f]);if($!==void 0)S[f]=/\%/.test($)?j1($):$}return S}#A(S){return this.#M[1]?this.#M[1][S]:S}query(S){return u1(this.url,S)}queries(S){return x1(this.url,S)}header(S){if(S)return this.raw.headers.get(S)??void 0;let M={};return this.raw.headers.forEach((f,$)=>{M[$]=f}),M}async parseBody(S){return this.bodyCache.parsedBody??=await G1(this,S)}#$=(S)=>{let{bodyCache:M,raw:f}=this,$=M[S];if($)return $;let A=Object.keys(M)[0];if(A)return M[A].then((O)=>{if(A==="json")O=JSON.stringify(O);return new Response(O)[S]()});return M[S]=f[S]()};json(){return this.#$("text").then((S)=>JSON.parse(S))}text(){return this.#$("text")}arrayBuffer(){return this.#$("arrayBuffer")}blob(){return this.#$("blob")}formData(){return this.#$("formData")}addValidatedData(S,M){this.#S[S]=M}valid(S){return this.#S[S]}get url(){return this.raw.url}get method(){return this.raw.method}get[L1](){return this.#M}get matchedRoutes(){return this.#M[0].map(([[,S]])=>S)}get routePath(){return this.#M[0].map(([[,S]])=>S)[this.routeIndex].path}};var x0={Stringify:1,BeforeStream:2,Stream:3},l2=(S,M)=>{let f=new String(S);return f.isEscaped=!0,f.callbacks=M,f};var Q0=async(S,M,f,$,A)=>{if(typeof S==="object"&&!(S instanceof String)){if(!(S instanceof Promise))S=S.toString();if(S instanceof Promise)S=await S}let O=S.callbacks;if(!O?.length)return Promise.resolve(S);if(A)A[0]+=S;else A=[S];let y=Promise.all(O.map((N)=>N({phase:M,buffer:A,context:$}))).then((N)=>Promise.all(N.filter(Boolean).map((V)=>Q0(V,M,!1,$,A))).then(()=>A[0]));if(f)return l2(await y,O);else return y};var k1="text/plain; charset=UTF-8",ZS=(S,M)=>{return{"Content-Type":S,...M}},I1=class{#S;#M;env={};#f;finalized=!1;error;#O;#A;#$;#J;#N;#V;#E;#Q;#_;constructor(S,M){if(this.#S=S,M)this.#A=M.executionCtx,this.env=M.env,this.#V=M.notFoundHandler,this.#_=M.path,this.#Q=M.matchResult}get req(){return this.#M??=new H0(this.#S,this.#_,this.#Q),this.#M}get event(){if(this.#A&&"respondWith"in this.#A)return this.#A;else throw Error("This context has no FetchEvent")}get executionCtx(){if(this.#A)return this.#A;else throw Error("This context has no ExecutionContext")}get res(){return this.#$||=new Response(null,{headers:this.#E??=new Headers})}set res(S){if(this.#$&&S){S=new Response(S.body,S);for(let[M,f]of this.#$.headers.entries()){if(M==="content-type")continue;if(M==="set-cookie"){let $=this.#$.headers.getSetCookie();S.headers.delete("set-cookie");for(let A of $)S.headers.append("set-cookie",A)}else S.headers.set(M,f)}}this.#$=S,this.finalized=!0}render=(...S)=>{return this.#N??=(M)=>this.html(M),this.#N(...S)};setLayout=(S)=>this.#J=S;getLayout=()=>this.#J;setRenderer=(S)=>{this.#N=S};header=(S,M,f)=>{if(this.finalized)this.#$=new Response(this.#$.body,this.#$);let $=this.#$?this.#$.headers:this.#E??=new Headers;if(M===void 0)$.delete(S);else if(f?.append)$.append(S,M);else $.set(S,M)};status=(S)=>{this.#O=S};set=(S,M)=>{this.#f??=new Map,this.#f.set(S,M)};get=(S)=>{return this.#f?this.#f.get(S):void 0};get var(){if(!this.#f)return{};return Object.fromEntries(this.#f)}#y(S,M,f){let $=this.#$?new Headers(this.#$.headers):this.#E??new Headers;if(typeof M==="object"&&"headers"in M){let O=M.headers instanceof Headers?M.headers:new Headers(M.headers);for(let[y,N]of O)if(y.toLowerCase()==="set-cookie")$.append(y,N);else $.set(y,N)}if(f)for(let[O,y]of Object.entries(f))if(typeof y==="string")$.set(O,y);else{$.delete(O);for(let N of y)$.append(O,N)}let A=typeof M==="number"?M:M?.status??this.#O;return new Response(S,{status:A,headers:$})}newResponse=(...S)=>this.#y(...S);body=(S,M,f)=>this.#y(S,M,f);text=(S,M,f)=>{return!this.#E&&!this.#O&&!M&&!f&&!this.finalized?new Response(S):this.#y(S,M,ZS(k1,f))};json=(S,M,f)=>{return this.#y(JSON.stringify(S),M,ZS("application/json",f))};html=(S,M,f)=>{let $=(A)=>this.#y(A,M,ZS("text/html; charset=UTF-8",f));return typeof S==="object"?Q0(S,x0.Stringify,!1,{}).then($):$(S)};redirect=(S,M)=>{let f=String(S);return this.header("Location",!/[^\x00-\xFF]/.test(f)?f:encodeURI(f)),this.newResponse(null,M??302)};notFound=()=>{return this.#V??=()=>new Response,this.#V(this)}};var C="ALL",w1="all",g1=["get","post","put","delete","options","patch"],j0="Can not add a route since the matcher is already built.",k0=class extends Error{};var m1="__COMPOSED_HANDLER";var c2=(S)=>{return S.text("404 Not Found",404)},h1=(S,M)=>{if("getResponse"in S){let f=S.getResponse();return M.newResponse(f.body,f)}return console.error(S),M.text("Internal Server Error",500)},q1=class S{get;post;put;delete;options;patch;all;on;use;router;getPath;_basePath="/";#S="/";routes=[];constructor(M={}){[...g1,w1].forEach((O)=>{this[O]=(y,...N)=>{if(typeof y==="string")this.#S=y;else this.#O(O,this.#S,y);return N.forEach((V)=>{this.#O(O,this.#S,V)}),this}}),this.on=(O,y,...N)=>{for(let V of[y].flat()){this.#S=V;for(let E of[O].flat())N.map((J)=>{this.#O(E.toUpperCase(),this.#S,J)})}return this},this.use=(O,...y)=>{if(typeof O==="string")this.#S=O;else this.#S="*",y.unshift(O);return y.forEach((N)=>{this.#O(C,this.#S,N)}),this};let{strict:$,...A}=M;Object.assign(this,A),this.getPath=$??!0?M.getPath??XS:F1}#M(){let M=new S({router:this.router,getPath:this.getPath});return M.errorHandler=this.errorHandler,M.#f=this.#f,M.routes=this.routes,M}#f=c2;errorHandler=h1;route(M,f){let $=this.basePath(M);return f.routes.map((A)=>{let O;if(f.errorHandler===h1)O=A.handler;else O=async(y,N)=>(await _S([],f.errorHandler)(y,()=>A.handler(y,N))).res,O[m1]=A.handler;$.#O(A.method,A.path,O)}),this}basePath(M){let f=this.#M();return f._basePath=b(this._basePath,M),f}onError=(M)=>{return this.errorHandler=M,this};notFound=(M)=>{return this.#f=M,this};mount(M,f,$){let A,O;if($)if(typeof $==="function")O=$;else if(O=$.optionHandler,$.replaceRequest===!1)A=(V)=>V;else A=$.replaceRequest;let y=O?(V)=>{let E=O(V);return Array.isArray(E)?E:[E]}:(V)=>{let E=void 0;try{E=V.executionCtx}catch{}return[V.env,E]};A||=(()=>{let V=b(this._basePath,M),E=V==="/"?0:V.length;return(J)=>{let Q=new URL(J.url);return Q.pathname=Q.pathname.slice(E)||"/",new Request(Q,J)}})();let N=async(V,E)=>{let J=await f(A(V.req.raw),...y(V));if(J)return J;await E()};return this.#O(C,b(M,"*"),N),this}#O(M,f,$){M=M.toUpperCase(),f=b(this._basePath,f);let A={basePath:this._basePath,path:f,method:M,handler:$};this.router.add(M,f,[$,A]),this.routes.push(A)}#A(M,f){if(M instanceof Error)return this.errorHandler(M,f);throw M}#$(M,f,$,A){if(A==="HEAD")return(async()=>new Response(null,await this.#$(M,f,$,"GET")))();let O=this.getPath(M,{env:$}),y=this.router.match(A,O),N=new I1(M,{path:O,matchResult:y,env:$,executionCtx:f,notFoundHandler:this.#f});if(y[0].length===1){let E;try{E=y[0][0][0][0](N,async()=>{N.res=await this.#f(N)})}catch(J){return this.#A(J,N)}return E instanceof Promise?E.then((J)=>J||(N.finalized?N.res:this.#f(N))).catch((J)=>this.#A(J,N)):E??this.#f(N)}let V=_S(y[0],this.errorHandler,this.#f);return(async()=>{try{let E=await V(N);if(!E.finalized)throw Error("Context is not finalized. Did you forget to return a Response object or `await next()`?");return E.res}catch(E){return this.#A(E,N)}})()}fetch=(M,...f)=>{return this.#$(M,f[1],f[0],M.method)};request=(M,f,$,A)=>{if(M instanceof Request)return this.fetch(f?new Request(M,f):M,$,A);return M=M.toString(),this.fetch(new Request(/^https?:\/\//.test(M)?M:`http://localhost${b("/",M)}`,f),$,A)};fire=()=>{addEventListener("fetch",(M)=>{M.respondWith(this.#$(M.request,M,void 0,M.request.method))})}};var _0=[];function I0(S,M){let f=this.buildAllMatchers(),$=(A,O)=>{let y=f[A]||f[C],N=y[2][O];if(N)return N;let V=O.match(y[0]);if(!V)return[[],_0];let E=V.indexOf("",1);return[y[1][E],V]};return this.match=$,$(S,M)}var w0="[^/]+",B0=".*",W0="(?:|/.*)",p=Symbol(),b2=new Set(".\\+*[^]$()");function p2(S,M){if(S.length===1)return M.length===1?S<M?-1:1:-1;if(M.length===1)return 1;if(S===B0||S===W0)return 1;else if(M===B0||M===W0)return-1;if(S===w0)return 1;else if(M===w0)return-1;return S.length===M.length?S<M?-1:1:M.length-S.length}var P1=class S{#S;#M;#f=Object.create(null);insert(M,f,$,A,O){if(M.length===0){if(this.#S!==void 0)throw p;if(O)return;this.#S=f;return}let[y,...N]=M,V=y==="*"?N.length===0?["","",B0]:["","",w0]:y==="/*"?["","",W0]:y.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/),E;if(V){let J=V[1],Q=V[2]||w0;if(J&&V[2]){if(Q===".*")throw p;if(Q=Q.replace(/^\((?!\?:)(?=[^)]+\)$)/,"(?:"),/\((?!\?:)/.test(Q))throw p}if(E=this.#f[Q],!E){if(Object.keys(this.#f).some((_)=>_!==B0&&_!==W0))throw p;if(O)return;if(E=this.#f[Q]=new S,J!=="")E.#M=A.varIndex++}if(!O&&J!=="")$.push([J,E.#M])}else if(E=this.#f[y],!E){if(Object.keys(this.#f).some((J)=>J.length>1&&J!==B0&&J!==W0))throw p;if(O)return;E=this.#f[y]=new S}E.insert(N,f,$,A,O)}buildRegExpStr(){let f=Object.keys(this.#f).sort(p2).map(($)=>{let A=this.#f[$];return(typeof A.#M==="number"?`(${$})@${A.#M}`:b2.has($)?`\\${$}`:$)+A.buildRegExpStr()});if(typeof this.#S==="number")f.unshift(`#${this.#S}`);if(f.length===0)return"";if(f.length===1)return f[0];return"(?:"+f.join("|")+")"}};var v1=class{#S={varIndex:0};#M=new P1;insert(S,M,f){let $=[],A=[];for(let y=0;;){let N=!1;if(S=S.replace(/\{[^}]+\}/g,(V)=>{let E=`@\\${y}`;return A[y]=[E,V],y++,N=!0,E}),!N)break}let O=S.match(/(?::[^\/]+)|(?:\/\*$)|./g)||[];for(let y=A.length-1;y>=0;y--){let[N]=A[y];for(let V=O.length-1;V>=0;V--)if(O[V].indexOf(N)!==-1){O[V]=O[V].replace(N,A[y][1]);break}}return this.#M.insert(O,M,$,this.#S,f),$}buildRegExp(){let S=this.#M.buildRegExpStr();if(S==="")return[/^$/,[],[]];let M=0,f=[],$=[];return S=S.replace(/#(\d+)|@(\d+)|\.\*\$/g,(A,O,y)=>{if(O!==void 0)return f[++M]=Number(O),"$()";if(y!==void 0)return $[Number(y)]=++M,"";return""}),[new RegExp(`^${S}`),f,$]}};var n2=[/^$/,[],Object.create(null)],l1=Object.create(null);function c1(S){return l1[S]??=new RegExp(S==="*"?"":`^${S.replace(/\/\*$|([.\\+*[^\]$()])/g,(M,f)=>f?`\\${f}`:"(?:|/.*)")}$`)}function r2(){l1=Object.create(null)}function t2(S){let M=new v1,f=[];if(S.length===0)return n2;let $=S.map((E)=>[!/\*|\/:/.test(E[0]),...E]).sort(([E,J],[Q,_])=>E?1:Q?-1:J.length-_.length),A=Object.create(null);for(let E=0,J=-1,Q=$.length;E<Q;E++){let[_,B,X]=$[E];if(_)A[B]=[X.map(([R])=>[R,Object.create(null)]),_0];else J++;let W;try{W=M.insert(B,J,_)}catch(R){throw R===p?new k0(B):R}if(_)continue;f[J]=X.map(([R,Y])=>{let L=Object.create(null);Y-=1;for(;Y>=0;Y--){let[G,U]=W[Y];L[G]=U}return[R,L]})}let[O,y,N]=M.buildRegExp();for(let E=0,J=f.length;E<J;E++)for(let Q=0,_=f[E].length;Q<_;Q++){let B=f[E][Q]?.[1];if(!B)continue;let X=Object.keys(B);for(let W=0,R=X.length;W<R;W++)B[X[W]]=N[B[X[W]]]}let V=[];for(let E in y)V[E]=f[y[E]];return[O,V,A]}function M0(S,M){if(!S)return;for(let f of Object.keys(S).sort(($,A)=>A.length-$.length))if(c1(f).test(M))return[...S[f]];return}var g0=class{name="RegExpRouter";#S;#M;constructor(){this.#S={[C]:Object.create(null)},this.#M={[C]:Object.create(null)}}add(S,M,f){let $=this.#S,A=this.#M;if(!$||!A)throw Error(j0);if(!$[S])[$,A].forEach((N)=>{N[S]=Object.create(null),Object.keys(N[C]).forEach((V)=>{N[S][V]=[...N[C][V]]})});if(M==="/*")M="*";let O=(M.match(/\/:/g)||[]).length;if(/\*$/.test(M)){let N=c1(M);if(S===C)Object.keys($).forEach((V)=>{$[V][M]||=M0($[V],M)||M0($[C],M)||[]});else $[S][M]||=M0($[S],M)||M0($[C],M)||[];Object.keys($).forEach((V)=>{if(S===C||S===V)Object.keys($[V]).forEach((E)=>{N.test(E)&&$[V][E].push([f,O])})}),Object.keys(A).forEach((V)=>{if(S===C||S===V)Object.keys(A[V]).forEach((E)=>N.test(E)&&A[V][E].push([f,O]))});return}let y=u0(M)||[M];for(let N=0,V=y.length;N<V;N++){let E=y[N];Object.keys(A).forEach((J)=>{if(S===C||S===J)A[J][E]||=[...M0($[J],E)||M0($[C],E)||[]],A[J][E].push([f,O-V+N+1])})}}match=I0;buildAllMatchers(){let S=Object.create(null);return Object.keys(this.#M).concat(Object.keys(this.#S)).forEach((M)=>{S[M]||=this.#f(M)}),this.#S=this.#M=void 0,r2(),S}#f(S){let M=[],f=S===C;if([this.#S,this.#M].forEach(($)=>{let A=$[S]?Object.keys($[S]).map((O)=>[O,$[S][O]]):[];if(A.length!==0)f||=!0,M.push(...A);else if(S!==C)M.push(...Object.keys($[C]).map((O)=>[O,$[C][O]]))}),!f)return null;else return t2(M)}};var i2=class{name="PreparedRegExpRouter";#S;#M;constructor(S,M){this.#S=S,this.#M=M}#f(S,M){let f=this.#S[S];f[1].forEach(($)=>$&&$.push(M)),Object.values(f[2]).forEach(($)=>$[0].push(M))}#O(S,M,f,$,A){let O=this.#S[S];if(!A)O[2][M][0].push([f,{}]);else $.forEach((y)=>{if(typeof y==="number")O[1][y].push([f,A]);else O[2][y||M][0].push([f,A])})}add(S,M,f){if(!this.#S[S]){let A=this.#S[C],O={};for(let y in A[2])O[y]=[A[2][y][0].slice(),_0];this.#S[S]=[A[0],A[1].map((y)=>Array.isArray(y)?y.slice():0),O]}if(M==="/*"||M==="*"){let A=[f,{}];if(S===C)for(let O in this.#S)this.#f(O,A);else this.#f(S,A);return}let $=this.#M[M];if(!$)throw Error(`Path ${M} is not registered`);for(let[A,O]of $)if(S===C)for(let y in this.#S)this.#O(y,M,f,A,O);else this.#O(S,M,f,A,O)}buildAllMatchers(){return this.#S}match=I0};var KS=class{name="SmartRouter";#S=[];#M=[];constructor(S){this.#S=S.routers}add(S,M,f){if(!this.#M)throw Error(j0);this.#M.push([S,M,f])}match(S,M){if(!this.#M)throw Error("Fatal error");let f=this.#S,$=this.#M,A=f.length,O=0,y;for(;O<A;O++){let N=f[O];try{for(let V=0,E=$.length;V<E;V++)N.add(...$[V]);y=N.match(S,M)}catch(V){if(V instanceof k0)continue;throw V}this.match=N.match.bind(N),this.#S=[N],this.#M=void 0;break}if(O===A)throw Error("Fatal error");return this.name=`SmartRouter + ${this.activeRouter.name}`,y}get activeRouter(){if(this.#M||this.#S.length!==1)throw Error("No active router has been determined yet.");return this.#S[0]}};var X0=Object.create(null),b1=class S{#S;#M;#f;#O=0;#A=X0;constructor(M,f,$){if(this.#M=$||Object.create(null),this.#S=[],M&&f){let A=Object.create(null);A[M]={handler:f,possibleKeys:[],score:0},this.#S=[A]}this.#f=[]}insert(M,f,$){this.#O=++this.#O;let A=this,O=C1(f),y=[];for(let N=0,V=O.length;N<V;N++){let E=O[N],J=O[N+1],Q=H1(E,J),_=Array.isArray(Q)?Q[0]:E;if(_ in A.#M){if(A=A.#M[_],Q)y.push(Q[1]);continue}if(A.#M[_]=new S,Q)A.#f.push(Q),y.push(Q[1]);A=A.#M[_]}return A.#S.push({[M]:{handler:$,possibleKeys:y.filter((N,V,E)=>E.indexOf(N)===V),score:this.#O}}),A}#$(M,f,$,A){let O=[];for(let y=0,N=M.#S.length;y<N;y++){let V=M.#S[y],E=V[f]||V[C],J={};if(E!==void 0){if(E.params=Object.create(null),O.push(E),$!==X0||A&&A!==X0)for(let Q=0,_=E.possibleKeys.length;Q<_;Q++){let B=E.possibleKeys[Q],X=J[E.score];E.params[B]=A?.[B]&&!X?A[B]:$[B]??A?.[B],J[E.score]=!0}}}return O}search(M,f){let $=[];this.#A=X0;let O=[this],y=WS(f),N=[];for(let V=0,E=y.length;V<E;V++){let J=y[V],Q=V===E-1,_=[];for(let B=0,X=O.length;B<X;B++){let W=O[B],R=W.#M[J];if(R)if(R.#A=W.#A,Q){if(R.#M["*"])$.push(...this.#$(R.#M["*"],M,W.#A));$.push(...this.#$(R,M,W.#A))}else _.push(R);for(let Y=0,L=W.#f.length;Y<L;Y++){let G=W.#f[Y],U=W.#A===X0?{}:{...W.#A};if(G==="*"){let g=W.#M["*"];if(g)$.push(...this.#$(g,M,W.#A)),g.#A=U,_.push(g);continue}let[k,w,x]=G;if(!J&&!(x instanceof RegExp))continue;let u=W.#M[k],L0=y.slice(V).join("/");if(x instanceof RegExp){let g=x.exec(L0);if(g){if(U[w]=g[0],$.push(...this.#$(u,M,W.#A,U)),Object.keys(u.#M).length){u.#A=U;let OS=g[0].match(/\//)?.length??0;(N[OS]||=[]).push(u)}continue}}if(x===!0||x.test(J))if(U[w]=J,Q){if($.push(...this.#$(u,M,U,W.#A)),u.#M["*"])$.push(...this.#$(u.#M["*"],M,U,W.#A))}else u.#A=U,_.push(u)}}O=_.concat(N.shift()??[])}if($.length>1)$.sort((V,E)=>{return V.score-E.score});return[$.map(({handler:V,params:E})=>[V,E])]}};var YS=class{name="TrieRouter";#S;constructor(){this.#S=new b1}add(S,M,f){let $=u0(M);if($){for(let A=0,O=$.length;A<O;A++)this.#S.insert(S,$[A],f);return}this.#S.insert(S,M,f)}match(S,M){return this.#S.search(S,M)}};var zS=class extends q1{constructor(S={}){super(S);this.router=S.router??new KS({routers:[new g0,new YS]})}};TS();import{z as Z}from"zod";var P0="1.0.0",i=Z.enum(["decision","bugfix","feature","refactor","discovery","change"]),F={find:Z.object({query:Z.string().min(1),scope:Z.enum(["project","user","all"]).optional().default("project"),types:Z.array(i).optional(),limit:Z.number().int().min(1).max(50).optional().default(10),cursor:Z.string().optional(),include:Z.object({snippets:Z.boolean().optional(),scores:Z.boolean().optional(),relations:Z.boolean().optional()}).optional()}),history:Z.object({limit:Z.number().int().min(1).max(20).optional().default(5),cursor:Z.string().optional(),sessionId:Z.string().optional(),anchor:Z.string().optional().describe("Observation ID to center the timeline around"),depthBefore:Z.number().int().min(0).max(20).optional().default(5),depthAfter:Z.number().int().min(0).max(20).optional().default(5)}),get:Z.object({ids:Z.array(Z.string()).min(1),includeHistory:Z.boolean().optional().default(!1),limit:Z.number().int().min(1).max(50).optional().default(10)}),create:Z.object({title:Z.string(),type:i,narrative:Z.string(),concepts:Z.array(Z.string()).optional(),files:Z.array(Z.string()).optional(),importance:Z.number().int().min(1).max(5).optional(),scope:Z.enum(["project","user"]).optional().default("project")}),revise:Z.object({id:Z.string(),title:Z.string().optional(),narrative:Z.string().optional(),type:i.optional(),concepts:Z.array(Z.string()).optional(),importance:Z.number().int().min(1).max(5).optional(),reason:Z.string().optional()}),remove:Z.object({id:Z.string(),reason:Z.string().optional()}),transferExport:Z.object({scope:Z.enum(["project"]).optional().default("project"),type:i.optional(),limit:Z.number().int().min(1).optional(),format:Z.enum(["json"]).optional().default("json")}),transferImport:Z.object({payload:Z.string(),mode:Z.enum(["skip","merge","replace"]).optional().default("skip")}),maintenance:Z.object({action:Z.enum(["folderContextDryRun","folderContextClean","folderContextRebuild","folderContextPurge"])}),help:Z.object({})},v0=[{name:"mem-find",schema:"find",description:"Search past memories \u2014 decisions, discoveries, gotchas, and session history. Use to recall context from previous sessions before starting work."},{name:"mem-history",schema:"history",description:"Browse session timeline and summaries. Use to understand what happened in recent sessions or drill into a specific session."},{name:"mem-get",schema:"get",description:"Fetch full memory details by ID. Use after mem-find or mem-history to get complete narratives, facts, and file lists."},{name:"mem-create",schema:"create",description:"Save an important observation to memory. Use for decisions + rationale, non-obvious gotchas, user preferences, or cross-session plans that auto-capture wouldn't understand the significance of."},{name:"mem-revise",schema:"revise",description:"Update an existing memory with a new revision. Use when a previous decision changed, a gotcha was resolved, or information became outdated."},{name:"mem-remove",schema:"remove",description:"Tombstone an obsolete or incorrect memory. Use to clean up memories that are no longer accurate or relevant."},{name:"mem-export",schema:"transferExport",description:"Export project memories as portable JSON for backup or transfer between machines."},{name:"mem-import",schema:"transferImport",description:"Import memories from a JSON export. Skips duplicates by default."},{name:"mem-maintenance",schema:"maintenance",description:"Run folder context maintenance \u2014 clean, rebuild, purge, or dry-run AGENTS.md files."},{name:"mem-help",schema:"help",description:"Show detailed memory workflow guidance including when to save, what to save, and memory type reference."}];function uS(S){return v0.find((M)=>M.name===S)??null}function K(S,M={}){return{data:S,error:null,meta:M}}function z(S,M,f){return{data:null,error:{code:S,message:M,details:f},meta:{}}}DS();class xS{evaluate(S){let M=[];if(!S.adapterStatuses.some((f)=>f.enabled))M.push("No platform adapters are enabled.");if(S.config.compressionEnabled&&S.config.provider!=="bedrock"&&!S.config.apiKey)M.push("Compression is enabled but no provider API key is configured.");if(S.runtime.status==="degraded")M.push("Runtime status is degraded.");if(S.runtime.queue.lastError)M.push(`Queue reported an error: ${S.runtime.queue.lastError}`);if(M.length===0)return{ready:!0,status:"ready",reasons:[]};return{ready:!1,status:S.runtime.status==="degraded"?"degraded":"initializing",reasons:M}}}import{existsSync as Rf}from"fs";import{dirname as Zf}from"path";class jS{run(S){let M=[];return M.push(this.checkDbDir(S)),M.push(this.checkProviderConfig(S)),M.push(this.checkVectorSupport(S)),M.push(this.checkAdapters(S)),M.push(this.checkDashboardPort(S)),{ok:M.every(($)=>$.status!=="fail"),checks:M}}checkDbDir(S){let M=Zf(S.dbPath);return Rf(M)?{id:"db-dir",status:"pass",message:"Database directory exists.",details:{dir:M}}:{id:"db-dir",status:"warn",message:"Database directory does not exist yet. It will be created on first run.",details:{dir:M}}}checkProviderConfig(S){if(!S.compressionEnabled)return{id:"provider-config",status:"pass",message:"Compression is disabled; provider API key is optional."};if(S.provider==="bedrock")return{id:"provider-config",status:"pass",message:"Bedrock provider selected; API key is not required."};if(!S.apiKey)return{id:"provider-config",status:"fail",message:"Compression is enabled but no provider API key is configured.",details:{provider:S.provider}};return{id:"provider-config",status:"pass",message:"Provider API key is configured.",details:{provider:S.provider}}}checkVectorSupport(S){if(!(S.provider==="google"||S.provider==="openai"||S.provider==="bedrock"))return{id:"vector-support",status:"warn",message:"Provider does not support embeddings; search will use FTS-only fallback.",details:{provider:S.provider}};return{id:"vector-support",status:"pass",message:"Provider supports embeddings.",details:{provider:S.provider,dimension:S.embeddingDimension}}}checkAdapters(S){let M=[["opencode",S.platformOpenCodeEnabled!==!1],["claude-code",S.platformClaudeCodeEnabled===!0],["cursor",S.platformCursorEnabled===!0]].filter(([,f])=>f);if(M.length===0)return{id:"adapters",status:"fail",message:"No platform adapters are enabled."};return{id:"adapters",status:"pass",message:`Enabled adapters: ${M.map(([f])=>f).join(", ")}`}}checkDashboardPort(S){if(!S.dashboardEnabled)return{id:"dashboard",status:"pass",message:"Dashboard is disabled."};if(S.dashboardPort<1||S.dashboardPort>65535)return{id:"dashboard",status:"fail",message:"Dashboard port is outside the valid range (1-65535).",details:{dashboardPort:S.dashboardPort}};return{id:"dashboard",status:"pass",message:"Dashboard port configuration looks valid.",details:{dashboardPort:S.dashboardPort}}}}var zf=new Set(i.options);function IS(S,M,f=100){if(!S)return M;let $=Number.parseInt(S,10);if(Number.isNaN($))return M;return Math.max(1,Math.min($,f))}function Uf(S){if(!S)return 0;let M=Number.parseInt(S,10);if(Number.isNaN(M))return 0;return Math.max(0,M)}function AM(S){if(!S)return;if(zf.has(S))return S;return}function l0(S){let M={};for(let[f,$]of Object.entries(S)){let A=f.toLowerCase();M[f]=typeof $==="string"&&(A.includes("key")||A.includes("api"))?"***REDACTED***":$}return M}function c0(S){return{status:S.status,timestamp:S.timestamp,uptimeMs:process.uptime()*1000,queue:{mode:"in-process",running:!1,processing:!1,pending:0,lastBatchDurationMs:0,lastProcessedAt:null,lastFailedAt:null,lastError:null},batches:{total:0,processedItems:0,failedItems:0,avgDurationMs:0},enqueueCount:0}}function OM(S){let{projectPath:M,memoryEngine:f,runtimeStatusProvider:$,dashboardDir:A}=S,O=new zS,y=new xS,N=new jS;O.get("/v1/memory/observations",(E)=>{let J=IS(E.req.query("limit"),50),Q=Uf(E.req.query("offset")),_=AM(E.req.query("type")),B=E.req.query("sessionId"),X=E.req.query("state"),W=X==="current"||X==="superseded"||X==="tombstoned"?X:void 0,R=f.listObservations({limit:J,offset:Q,type:_,sessionId:B,state:W});return E.json(K(R,{limit:J,offset:Q}))}),O.post("/v1/memory/observations",async(E)=>{try{let J=await E.req.json(),Q=await f.save({...J,sessionId:J.sessionId??`http-${Date.now()}`});if(!Q)return E.json(z("CONFLICT","Unable to create observation"),409);return E.json(K(Q),201)}catch{return E.json(z("VALIDATION_ERROR","Invalid JSON body"),400)}}),O.get("/v1/memory/observations/:id",(E)=>{let J=E.req.param("id"),Q=f.getObservation(J);if(!Q)return E.json(z("NOT_FOUND","Observation not found"),404);return E.json(K(Q))}),O.get("/v1/memory/observations/:id/lineage",(E)=>{let J=E.req.param("id"),Q=f.getLineage(J);if(!Q)return E.json(z("NOT_FOUND","Observation not found"),404);return E.json(K({observationId:J,lineage:Q}))}),O.get("/v1/memory/observations/:id/revision-diff",(E)=>{let J=E.req.param("id"),Q=E.req.query("against");if(!Q)return E.json(z("VALIDATION_ERROR","Query parameter 'against' is required"),400);let _=f.getRevisionDiff(J,Q);if(!_)return E.json(z("NOT_FOUND","One or both observations not found"),404);return E.json(K(_))}),O.post("/v1/memory/observations/:id/revisions",async(E)=>{let J=E.req.param("id");try{let Q=await E.req.json(),_=await f.update({id:J,...Q});if(!_)return E.json(z("NOT_FOUND","Observation not found"),404);return E.json(K({previousId:J,newId:_.id,observation:_}))}catch{return E.json(z("VALIDATION_ERROR","Invalid JSON body"),400)}}),O.post("/v1/memory/observations/:id/tombstone",async(E)=>{let J=E.req.param("id");if(await f.delete([J])===0)return E.json(z("NOT_FOUND","Observation not found"),404);return E.json(K({id:J,tombstoned:!0}))}),O.get("/v1/memory/sessions",(E)=>{let J=IS(E.req.query("limit"),20),Q=E.req.query("projectPath")||M;return E.json(K(f.listSessions({limit:J,projectPath:Q}),{limit:J}))}),O.get("/v1/memory/sessions/:id",(E)=>{let J=E.req.param("id"),Q=f.getSession(J);if(!Q)return E.json(z("NOT_FOUND","Session not found"),404);return E.json(K({...Q.session,observations:Q.observations,summary:Q.summary}))}),O.get("/v1/memory/search",async(E)=>{let J=E.req.query("q");if(!J)return E.json(z("VALIDATION_ERROR","Query parameter 'q' is required"),400);let Q=AM(E.req.query("type")),_=IS(E.req.query("limit"),20);try{let B=await f.search(J,{type:Q,limit:_});return E.json(K(B,{limit:_}))}catch{return E.json(K([],{limit:_}))}}),O.post("/v1/memory/recall",async(E)=>{try{let J=await E.req.json(),Q=await f.recall(J.ids??[],J.limit??10);return E.json(K(Q))}catch{return E.json(z("VALIDATION_ERROR","Invalid JSON body"),400)}}),O.post("/v1/memory/export",async(E)=>{try{let J=await E.req.json().catch(()=>({})),Q=await f.export("project",{type:J.type,limit:J.limit});return E.json(K(Q))}catch(J){return E.json(z("INTERNAL_ERROR",String(J)),500)}}),O.post("/v1/memory/import",async(E)=>{try{let J=await E.req.json(),Q=J.mode==="replace"?"overwrite":"skip-duplicates",_=await f.import(J.payload,{mode:Q});return E.json(K(_))}catch{return E.json(z("VALIDATION_ERROR","Invalid import payload"),400)}}),O.get("/v1/memory/stats",(E)=>{return E.json(K(f.stats()))}),O.get("/v1/health",(E)=>{let J=f.getHealth(),Q=f.getMetrics(),B=$?.()??c0(J);return E.json(K({status:B.status,timestamp:B.timestamp,uptimeMs:B.uptimeMs,queue:B.queue,memory:{totalObservations:Q.memory.totalObservations,totalSessions:Q.memory.totalSessions}}))}),O.get("/v1/readiness",(E)=>{let J=f.getHealth(),Q=$?.()??c0(J),_=y.evaluate({config:S.config,adapterStatuses:f.getAdapterStatuses().map((B)=>({name:B.name,enabled:B.enabled})),runtime:{status:Q.status,queue:{lastError:Q.queue.lastError}}});return E.json(K(_),_.ready?200:503)}),O.get("/v1/diagnostics",(E)=>{let J=N.run(S.config);return E.json(K(J),J.ok?200:503)}),O.get("/v1/tools/guide",(E)=>{return E.json(K({contractVersion:P0,workflow:{recommended:["mem-find","mem-history","mem-get"],description:"Start with compact discovery, then timeline context, then full detail fetch by IDs."},tools:v0}))}),O.get("/v1/queue",(E)=>{let J=f.getHealth(),Q=$?.()??c0(J);return E.json(K({contractVersion:P0,queue:Q.queue,batches:Q.batches,enqueueCount:Q.enqueueCount}))}),O.post("/v1/queue/process",async(E)=>{let J=await f.processPending();return E.json(K({processed:J}))}),O.get("/v1/metrics",(E)=>{let J=f.getHealth(),_=$?.()??c0(J);return E.json(K(_))}),O.get("/v1/platforms",(E)=>{let J=f.getAdapterStatuses();return E.json(K({platforms:J.map((Q)=>({name:Q.name,version:Q.version,enabled:Q.enabled,capabilities:Q.capabilities}))}))}),O.get("/v1/adapters/status",(E)=>{return E.json(K(f.getAdapterStatuses()))}),O.get("/v1/config/schema",(E)=>E.json(K(CS()))),O.get("/v1/config/effective",async(E)=>{let J=await r(M);return E.json(K({config:l0(J.config),meta:J.meta,warnings:J.warnings}))}),O.post("/v1/config/preview",async(E)=>{try{let J=await E.req.json(),Q=await FS(M,J);return E.json(K({config:l0(Q.config),meta:Q.meta,warnings:Q.warnings}))}catch{return E.json(z("VALIDATION_ERROR","Invalid JSON body"),400)}}),O.patch("/v1/config",async(E)=>{let J;try{J=await E.req.json()}catch{return E.json(z("VALIDATION_ERROR","Invalid JSON body"),400)}try{let Q=await t(M),_=await q0(M,J),B={};for(let X of Object.keys(J))if(Object.hasOwn(Q,X))B[X]=Q[X];return f.trackConfigAudit({id:Z0(),timestamp:new Date().toISOString(),patch:J,previousValues:B,source:"api"}),E.json(K({config:l0(_.config),meta:_.meta,warnings:_.warnings}))}catch(Q){return E.json(z("INTERNAL_ERROR",String(Q)),500)}}),O.get("/v1/config/audit",(E)=>{return E.json(K(f.getConfigAuditTimeline()))}),O.post("/v1/config/rollback",async(E)=>{let J;try{J=await E.req.json()}catch{return E.json(z("VALIDATION_ERROR","Invalid JSON body"),400)}if(!J.eventId)return E.json(z("VALIDATION_ERROR","eventId is required"),400);try{let Q=await f.rollbackConfig(J.eventId);if(!Q)return E.json(z("NOT_FOUND","Audit event not found"),404);return E.json(K(Q))}catch(Q){return E.json(z("INTERNAL_ERROR",String(Q)),500)}});let V={balanced:{minOutputLength:50,contextFullObservationCount:3,maxObservations:50,batchSize:5},focus:{minOutputLength:120,contextFullObservationCount:2,maxObservations:30,batchSize:3},chill:{minOutputLength:200,contextFullObservationCount:1,maxObservations:15,batchSize:2,compressionEnabled:!1}};if(O.get("/v1/modes",(E)=>E.json(K({modes:Object.entries(V).map(([J,Q])=>({id:J,patch:Q}))}))),O.post("/v1/modes/:id/apply",async(E)=>{let J=E.req.param("id"),Q=V[J];if(!Q)return E.json(z("NOT_FOUND","Unknown mode"),404);try{let _=await t(M),B=await q0(M,Q),X={};for(let W of Object.keys(Q))if(Object.hasOwn(_,W))X[W]=_[W];return f.trackConfigAudit({id:Z0(),timestamp:new Date().toISOString(),patch:Q,previousValues:X,source:"mode"}),E.json(K({applied:J,config:l0(B.config),meta:B.meta,warnings:B.warnings}))}catch(_){return E.json(z("INTERNAL_ERROR",String(_)),500)}}),O.get("/v1/workflow-modes",(E)=>E.json(K({modes:h0().map((J)=>i1(J))}))),O.post("/v1/maintenance/folder-context/dry-run",async(E)=>{try{let Q=(await E.req.json().catch(()=>({}))).action??"clean",_=await f.maintainFolderContext(Q,!0);return f.trackMaintenanceResult({id:Z0(),timestamp:new Date().toISOString(),action:`folder-context-${Q}-dry-run`,dryRun:!0,result:_}),E.json(K(_))}catch(J){return E.json(z("INTERNAL_ERROR",String(J)),500)}}),O.post("/v1/maintenance/folder-context/clean",async(E)=>{try{let J=await f.maintainFolderContext("clean",!1);return f.trackMaintenanceResult({id:Z0(),timestamp:new Date().toISOString(),action:"folder-context-clean",dryRun:!1,result:J}),E.json(K(J))}catch(J){return E.json(z("INTERNAL_ERROR",String(J)),500)}}),O.post("/v1/maintenance/folder-context/rebuild",async(E)=>{try{let J=await f.maintainFolderContext("rebuild",!1);return f.trackMaintenanceResult({id:Z0(),timestamp:new Date().toISOString(),action:"folder-context-rebuild",dryRun:!1,result:J}),E.json(K(J))}catch(J){return E.json(z("INTERNAL_ERROR",String(J)),500)}}),O.get("/v1/maintenance/history",(E)=>{return E.json(K(f.getMaintenanceHistory()))}),S.sseHandler)O.get("/v1/events",S.sseHandler);return O.get("*",async(E)=>{let J=E.req.path;if(J.startsWith("/v1/"))return E.json(z("NOT_FOUND","Not found"),404);let Q=A??kS(Yf(import.meta.url),"../../dist/dashboard"),_=Kf(Q),B=_.endsWith($M)?_:`${_}${$M}`,X=J==="/"?"index.html":J.replace(/^\//,""),W=kS(Q,X);if(!W.startsWith(B))return E.json(z("NOT_FOUND","Not found"),404);try{let Y=Bun.file(W);if(await Y.exists())return new Response(Y)}catch{}let R=kS(Q,"index.html");if(!R.startsWith(B))return E.json(z("NOT_FOUND","Not found"),404);try{let Y=Bun.file(R);if(await Y.exists())return new Response(Y,{headers:{"Content-Type":"text/html; charset=utf-8"}})}catch{}return E.json(z("NOT_FOUND","Dashboard not found. Run the dashboard build first."),404)}),O}var wS=class{writer;encoder;writable;abortSubscribers=[];responseReadable;aborted=!1;closed=!1;constructor(S,M){this.writable=S,this.writer=S.getWriter(),this.encoder=new TextEncoder;let f=M.getReader();this.abortSubscribers.push(async()=>{await f.cancel()}),this.responseReadable=new ReadableStream({async pull($){let{done:A,value:O}=await f.read();A?$.close():$.enqueue(O)},cancel:()=>{this.abort()}})}async write(S){try{if(typeof S==="string")S=this.encoder.encode(S);await this.writer.write(S)}catch{}return this}async writeln(S){return await this.write(S+`
|
|
3
|
-
`),this}sleep(S){return new Promise((M)=>setTimeout(M,S))}async close(){try{await this.writer.close()}catch{}this.closed=!0}async pipe(S){this.writer.releaseLock(),await S.pipeTo(this.writable,{preventClose:!0}),this.writer=this.writable.getWriter()}onAbort(S){this.abortSubscribers.push(S)}abort(){if(!this.aborted)this.aborted=!0,this.abortSubscribers.forEach((S)=>S())}};var
|
|
4
|
-
`)
|
|
2
|
+
var mM=Object.create;var{getPrototypeOf:bM,defineProperty:B1,getOwnPropertyNames:cM}=Object;var lM=Object.prototype.hasOwnProperty;var pM=(S,M,$)=>{$=S!=null?mM(bM(S)):{};let f=M||!S||!S.__esModule?B1($,"default",{value:S,enumerable:!0}):$;for(let O of cM(S))if(!lM.call(f,O))B1(f,O,{get:()=>S[O],enumerable:!0});return f};var CS=(S,M)=>{for(var $ in M)B1(S,$,{get:M[$],enumerable:!0,configurable:!0,set:(f)=>M[$]=()=>f})};var F0=(S,M)=>()=>(S&&(M=S(S=0)),M);var g=import.meta.require;import{existsSync as J$,readdirSync as X$,readFileSync as Z$}from"fs";import{join as E$}from"path";function n(S){return{...S,observationTypes:[...S.observationTypes],conceptVocabulary:[...S.conceptVocabulary],entityTypes:[...S.entityTypes],relationshipTypes:[...S.relationshipTypes],promptOverrides:S.promptOverrides?{...S.promptOverrides}:void 0}}function Q$(S){if(!S||typeof S!=="object")return!1;let M=S,$=(O)=>Array.isArray(O)&&O.every((A)=>typeof A==="string"),f=(O)=>typeof O==="object"&&O!==null&&!Array.isArray(O)&&Object.values(O).every((A)=>typeof A==="string");return typeof M.id==="string"&&(M.extends===void 0||typeof M.extends==="string")&&(M.locale===void 0||typeof M.locale==="string")&&(M.name===void 0||typeof M.name==="string")&&(M.description===void 0||typeof M.description==="string")&&(M.observationTypes===void 0||$(M.observationTypes))&&(M.conceptVocabulary===void 0||$(M.conceptVocabulary))&&(M.entityTypes===void 0||$(M.entityTypes))&&(M.relationshipTypes===void 0||$(M.relationshipTypes))&&(M.promptOverrides===void 0||f(M.promptOverrides))}function B$(S){return typeof S.name==="string"&&typeof S.description==="string"&&Array.isArray(S.observationTypes)&&Array.isArray(S.conceptVocabulary)&&Array.isArray(S.entityTypes)&&Array.isArray(S.relationshipTypes)}function dS(S,M){return{...S,...M,id:M.id,name:M.name??S.name,description:M.description??S.description,observationTypes:M.observationTypes??S.observationTypes,conceptVocabulary:M.conceptVocabulary??S.conceptVocabulary,entityTypes:M.entityTypes??S.entityTypes,relationshipTypes:M.relationshipTypes??S.relationshipTypes,promptOverrides:{...S.promptOverrides??{},...M.promptOverrides??{}}}}class H1{modesDir;constructor(S){this.modesDir=S}loadAllRaw(){let S=new Map;if(!J$(this.modesDir))return S;for(let M of X$(this.modesDir)){if(!M.endsWith(".json"))continue;let $=E$(this.modesDir,M);try{let f=Z$($,"utf-8"),O=JSON.parse(f);if(!Q$(O))continue;if(S.has(O.id))console.warn(`[open-mem] Duplicate mode id "${O.id}" in ${$}; overriding previous definition.`);S.set(O.id,O)}catch{}}return S}resolveById(S,M){let $=new Set,f=!1,O=(V)=>{if($.has(V))return f=!0,n(f0);$.add(V);let y=M.get(V);if(!y)return n(f0);if(!y.extends){if(!B$(y))return n(f0);return dS(n(f0),y)}let J=O(y.extends);if(f)return n(f0);return dS(J,y)},A=O(S);return f?n(f0):n(A)}}var f0;var sS=F0(()=>{f0={id:"code",name:"Code",description:"Default coding workflow mode",observationTypes:["decision","bugfix","feature","refactor","discovery","change"],conceptVocabulary:["how-it-works","why-it-exists","what-changed","problem-solution","gotcha","pattern","trade-off"],entityTypes:["technology","library","pattern","concept","file","person","project","other"],relationshipTypes:["uses","depends_on","implements","extends","related_to","replaces","configures"]}});import{join as K$}from"path";function oS(){if(h0)return h0;return h0=aS.loadAllRaw(),h0}function eS(S){return aS.resolveById(S,oS())}function P0(){return[...oS().keys()].sort()}var W$,aS,h0=null;var L1=F0(()=>{sS();W$=K$(import.meta.dir,"."),aS=new H1(W$)});import{existsSync as _$,readFileSync as Y$}from"fs";function U$(){let S={};if(process.env.OPEN_MEM_DB_PATH)S.dbPath=process.env.OPEN_MEM_DB_PATH;if(process.env.OPEN_MEM_PROVIDER)S.provider=process.env.OPEN_MEM_PROVIDER;if(process.env.OPEN_MEM_MODEL)S.model=process.env.OPEN_MEM_MODEL;if(process.env.OPEN_MEM_MAX_CONTEXT_TOKENS)S.maxContextTokens=Number.parseInt(process.env.OPEN_MEM_MAX_CONTEXT_TOKENS,10);if(process.env.OPEN_MEM_COMPRESSION==="false")S.compressionEnabled=!1;if(process.env.OPEN_MEM_CONTEXT_INJECTION==="false")S.contextInjectionEnabled=!1;if(process.env.OPEN_MEM_IGNORED_TOOLS)S.ignoredTools=process.env.OPEN_MEM_IGNORED_TOOLS.split(",").map((M)=>M.trim());if(process.env.OPEN_MEM_BATCH_SIZE)S.batchSize=Number.parseInt(process.env.OPEN_MEM_BATCH_SIZE,10);if(process.env.OPEN_MEM_RETENTION_DAYS)S.retentionDays=Number.parseInt(process.env.OPEN_MEM_RETENTION_DAYS,10);if(process.env.OPEN_MEM_LOG_LEVEL)S.logLevel=process.env.OPEN_MEM_LOG_LEVEL;if(process.env.OPEN_MEM_CONTEXT_SHOW_TOKEN_COSTS==="false")S.contextShowTokenCosts=!1;if(process.env.OPEN_MEM_CONTEXT_TYPES)S.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)S.contextFullObservationCount=Number.parseInt(process.env.OPEN_MEM_CONTEXT_FULL_COUNT,10);if(process.env.OPEN_MEM_MAX_OBSERVATIONS)S.maxObservations=Number.parseInt(process.env.OPEN_MEM_MAX_OBSERVATIONS,10);if(process.env.OPEN_MEM_CONTEXT_SHOW_LAST_SUMMARY==="false")S.contextShowLastSummary=!1;if(process.env.OPEN_MEM_RATE_LIMITING==="false")S.rateLimitingEnabled=!1;if(process.env.OPEN_MEM_FOLDER_CONTEXT==="false")S.folderContextEnabled=!1;if(process.env.OPEN_MEM_FOLDER_CONTEXT_MAX_DEPTH)S.folderContextMaxDepth=Number.parseInt(process.env.OPEN_MEM_FOLDER_CONTEXT_MAX_DEPTH,10);if(process.env.OPEN_MEM_FOLDER_CONTEXT_MODE==="single")S.folderContextMode="single";if(process.env.OPEN_MEM_FOLDER_CONTEXT_MODE==="dispersed")S.folderContextMode="dispersed";if(process.env.OPEN_MEM_FOLDER_CONTEXT_FILENAME)S.folderContextFilename=process.env.OPEN_MEM_FOLDER_CONTEXT_FILENAME;if(process.env.OPEN_MEM_DAEMON==="true")S.daemonEnabled=!0;if(process.env.OPEN_MEM_DASHBOARD==="true")S.dashboardEnabled=!0;if(process.env.OPEN_MEM_DASHBOARD_PORT)S.dashboardPort=Number.parseInt(process.env.OPEN_MEM_DASHBOARD_PORT,10);if(process.env.OPEN_MEM_PLATFORM_OPENCODE==="false")S.platformOpenCodeEnabled=!1;if(process.env.OPEN_MEM_PLATFORM_CLAUDE_CODE==="true")S.platformClaudeCodeEnabled=!0;if(process.env.OPEN_MEM_PLATFORM_CURSOR==="true")S.platformCursorEnabled=!0;if(process.env.OPEN_MEM_MCP_PROTOCOL_VERSION)S.mcpProtocolVersion=process.env.OPEN_MEM_MCP_PROTOCOL_VERSION;if(process.env.OPEN_MEM_MCP_SUPPORTED_PROTOCOLS)S.mcpSupportedProtocolVersions=process.env.OPEN_MEM_MCP_SUPPORTED_PROTOCOLS.split(",").map((M)=>M.trim()).filter(Boolean);if(process.env.OPEN_MEM_EMBEDDING_DIMENSION)S.embeddingDimension=Number.parseInt(process.env.OPEN_MEM_EMBEDDING_DIMENSION,10);if(process.env.OPEN_MEM_CONFLICT_RESOLUTION==="true")S.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))S.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))S.conflictSimilarityBandHigh=M}if(process.env.OPEN_MEM_USER_MEMORY==="true")S.userMemoryEnabled=!0;if(process.env.OPEN_MEM_USER_MEMORY_DB_PATH)S.userMemoryDbPath=process.env.OPEN_MEM_USER_MEMORY_DB_PATH;if(process.env.OPEN_MEM_USER_MEMORY_MAX_TOKENS)S.userMemoryMaxContextTokens=Number.parseInt(process.env.OPEN_MEM_USER_MEMORY_MAX_TOKENS,10);if(process.env.OPEN_MEM_RERANKING==="true")S.rerankingEnabled=!0;if(process.env.OPEN_MEM_RERANKING_MAX_CANDIDATES)S.rerankingMaxCandidates=Number.parseInt(process.env.OPEN_MEM_RERANKING_MAX_CANDIDATES,10);if(process.env.OPEN_MEM_ENTITY_EXTRACTION==="true")S.entityExtractionEnabled=!0;if(process.env.OPEN_MEM_FALLBACK_PROVIDERS)S.fallbackProviders=process.env.OPEN_MEM_FALLBACK_PROVIDERS.split(",").map((M)=>M.trim()).filter(Boolean);if(process.env.OPEN_MEM_MODE)S.mode=process.env.OPEN_MEM_MODE;return S}function R$(S){let M=`${S}/.open-mem/config.json`;if(!_$(M))return{};try{let $=Y$(M,"utf-8"),f=JSON.parse($);if(!f||typeof f!=="object"||Array.isArray(f))return{};return f}catch{return{}}}function z$(S){switch(S){case"google":return 768;case"openai":return 1536;case"bedrock":return 1024;case"anthropic":return 0;case"openrouter":return 0;default:return 768}}function _0(S,M){let $=R$(S),f=U$(),O={...S2,...$,...f,...M};if(!O.dbPath.startsWith("/"))O.dbPath=`${S}/${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";else if(process.env.OPENROUTER_API_KEY)O.provider="openrouter"}if(!O.apiKey)switch(O.provider){case"google":O.apiKey=process.env.GOOGLE_GENERATIVE_AI_API_KEY||process.env.GEMINI_API_KEY;break;case"anthropic":O.apiKey=process.env.ANTHROPIC_API_KEY;break;case"openai":O.apiKey=process.env.OPENAI_API_KEY;break;case"openrouter":O.apiKey=process.env.OPENROUTER_API_KEY;break;case"bedrock":break}if(O.provider==="openrouter"&&O.model==="gemini-2.5-flash-lite")O.model="google/gemini-2.5-flash-lite";if(O.embeddingDimension===void 0)O.embeddingDimension=z$(O.provider);if(O.mode&&!P0().includes(O.mode))O.mode="code";return O}function M2(S){let M=[],$=S.provider!=="bedrock";if(S.compressionEnabled&&$&&!S.apiKey)M.push("AI compression enabled but no API key found. Get a free Gemini API key at https://aistudio.google.com/apikey and set GOOGLE_GENERATIVE_AI_API_KEY, or set OPEN_MEM_PROVIDER and the appropriate API key for your provider.");if(S.maxContextTokens<500)M.push("maxContextTokens must be at least 500");if(S.batchSize<1)M.push("batchSize must be at least 1");if(S.minOutputLength<0)M.push("minOutputLength must be non-negative");return M}function C1(){return{...S2}}async function $2(S){let M=S.dbPath.substring(0,S.dbPath.lastIndexOf("/")),{mkdir:$}=await import("fs/promises");await $(M,{recursive:!0})}var S2;var F1=F0(()=>{L1();S2={dbPath:".open-mem/memory.db",provider:"google",apiKey:void 0,model:"gemini-2.5-flash-lite",maxTokensPerCompression:1024,compressionEnabled:!0,contextInjectionEnabled:!0,maxContextTokens:4000,batchSize:5,batchIntervalMs:30000,ignoredTools:[],minOutputLength:50,maxIndexEntries:20,sensitivePatterns:[],retentionDays:90,maxDatabaseSizeMb:500,logLevel:"warn",contextShowTokenCosts:!0,contextObservationTypes:"all",contextFullObservationCount:3,maxObservations:50,contextShowLastSummary:!0,rateLimitingEnabled:!0,folderContextEnabled:!0,folderContextMaxDepth:5,folderContextMode:"single",folderContextFilename:"AGENTS.md",daemonEnabled:!1,dashboardEnabled:!1,dashboardPort:3737,platformOpenCodeEnabled:!0,platformClaudeCodeEnabled:!1,platformCursorEnabled:!1,mcpProtocolVersion:"2024-11-05",mcpSupportedProtocolVersions:["2024-11-05"],embeddingDimension:void 0,conflictResolutionEnabled:!1,conflictSimilarityBandLow:0.7,conflictSimilarityBandHigh:0.92,userMemoryEnabled:!1,userMemoryDbPath:"~/.config/open-mem/user-memory.db",userMemoryMaxContextTokens:1000,rerankingEnabled:!1,rerankingMaxCandidates:20,entityExtractionEnabled:!1,fallbackProviders:void 0,mode:"code"}});var N2={};CS(N2,{writeProjectConfig:()=>V2,validatePatch:()=>T1,readProjectConfig:()=>i,previewConfig:()=>x1,patchConfig:()=>m0,getEffectiveConfig:()=>r,getConfigSchema:()=>j1});import{existsSync as D$}from"fs";import{mkdir as G$,readFile as H$,writeFile as L$}from"fs/promises";import{dirname as C$,join as F$}from"path";function O2(S){return F$(S,".open-mem","config.json")}function A2(S){return f2.find((M)=>M.key===S)}function T$(S,M){let $=A2(S);if(!$)return null;if($.type==="string"&&typeof M!=="string")return`${String(S)} must be a string`;if($.type==="number"&&typeof M!=="number")return`${String(S)} must be a number`;if($.type==="boolean"&&typeof M!=="boolean")return`${String(S)} must be a boolean`;if($.type==="array"&&!Array.isArray(M))return`${String(S)} must be an array`;if($.enum&&typeof M==="string"&&!$.enum.includes(M))return`${String(S)} must be one of: ${$.enum.join(", ")}`;if(typeof M==="number"){if($.min!==void 0&&M<$.min)return`${String(S)} must be >= ${$.min}`;if($.max!==void 0&&M>$.max)return`${String(S)} must be <= ${$.max}`}return null}function j1(){return f2}async function i(S){let M=O2(S);if(!D$(M))return{};try{let $=await H$(M,"utf-8"),f=JSON.parse($);if(!f||typeof f!=="object"||Array.isArray(f))return{};return f}catch{return{}}}async function V2(S,M){let $=O2(S),O={...await i(S),...M};await G$(C$($),{recursive:!0}),await L$($,JSON.stringify(O,null,2),"utf-8")}function T1(S){let M=[];for(let[$,f]of Object.entries(S)){let A=T$($,f);if(A)M.push(A)}return M}async function r(S){let M=C1(),$=await i(S),f=_0(S),O=[],A={};for(let[V,y]of Object.entries(M)){let J=V,N=A2(J),Z=(j$[J]??[]).some((K)=>typeof process.env[K]==="string"),E=Object.hasOwn($,J),Q="default";if(E)Q="file";if(Z)Q="env";if(A[J]={source:Q,locked:Z,restartRequired:N?.restartRequired??!1,liveApply:N?.liveApply??!1},Q==="env"&&E)O.push(`${String(J)} is overridden by environment variable.`);if(f[J]===void 0&&y!==void 0)O.push(`${String(J)} resolved to undefined unexpectedly.`)}return{config:f,meta:A,warnings:O}}async function x1(S,M){let $=T1(M);if($.length>0)return{...await r(S),warnings:$};let f=C1(),O=await i(S),A={...f,...O,...M},y={..._0(S,M),...A},J=(await r(S)).meta;return{config:y,meta:J,warnings:[]}}async function m0(S,M){let $=T1(M);if($.length>0)return{...await r(S),warnings:$};return await V2(S,M),r(S)}var f2,j$;var I1=F0(()=>{F1();f2=[{key:"dbPath",label:"Database Path",type:"string",group:"Storage",liveApply:!1,restartRequired:!0},{key:"provider",label:"Provider",type:"string",group:"AI",liveApply:!1,restartRequired:!0,enum:["google","anthropic","openai","bedrock"]},{key:"model",label:"Model",type:"string",group:"AI",liveApply:!1,restartRequired:!0},{key:"maxTokensPerCompression",label:"Max Tokens Per Compression",type:"number",group:"AI",liveApply:!0,restartRequired:!1,min:128,max:8192},{key:"compressionEnabled",label:"Compression Enabled",type:"boolean",group:"Behavior",liveApply:!0,restartRequired:!1},{key:"contextInjectionEnabled",label:"Context Injection Enabled",type:"boolean",group:"Behavior",liveApply:!0,restartRequired:!1},{key:"maxContextTokens",label:"Max Context Tokens",type:"number",group:"Behavior",liveApply:!0,restartRequired:!1,min:500,max:64000},{key:"batchSize",label:"Batch Size",type:"number",group:"Behavior",liveApply:!0,restartRequired:!1,min:1,max:100},{key:"batchIntervalMs",label:"Batch Interval (ms)",type:"number",group:"Behavior",liveApply:!0,restartRequired:!1,min:1000,max:300000},{key:"ignoredTools",label:"Ignored Tools",type:"array",group:"Filtering",liveApply:!0,restartRequired:!1},{key:"minOutputLength",label:"Min Output Length",type:"number",group:"Filtering",liveApply:!0,restartRequired:!1,min:0,max:1e4},{key:"maxObservations",label:"Max Observations",type:"number",group:"Progressive Disclosure",liveApply:!0,restartRequired:!1,min:1,max:200},{key:"contextFullObservationCount",label:"Full Observation Count",type:"number",group:"Progressive Disclosure",liveApply:!0,restartRequired:!1,min:0,max:20},{key:"contextShowTokenCosts",label:"Show Token Costs",type:"boolean",group:"Progressive Disclosure",liveApply:!0,restartRequired:!1},{key:"sensitivePatterns",label:"Sensitive Patterns",type:"array",group:"Privacy",liveApply:!0,restartRequired:!1},{key:"retentionDays",label:"Retention Days",type:"number",group:"Data Retention",liveApply:!1,restartRequired:!0,min:0,max:3650},{key:"maxDatabaseSizeMb",label:"Max Database Size (MB)",type:"number",group:"Data Retention",liveApply:!1,restartRequired:!0,min:0,max:1e5},{key:"dashboardEnabled",label:"Dashboard Enabled",type:"boolean",group:"Dashboard",liveApply:!1,restartRequired:!0},{key:"dashboardPort",label:"Dashboard Port",type:"number",group:"Dashboard",liveApply:!1,restartRequired:!0,min:1,max:65535},{key:"platformOpenCodeEnabled",label:"OpenCode Adapter",type:"boolean",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"platformClaudeCodeEnabled",label:"Claude Code Adapter",type:"boolean",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"platformCursorEnabled",label:"Cursor Adapter",type:"boolean",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"mcpProtocolVersion",label:"MCP Protocol Version",type:"string",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"mcpSupportedProtocolVersions",label:"MCP Supported Protocols",type:"array",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"rerankingEnabled",label:"Reranking Enabled",type:"boolean",group:"Advanced",liveApply:!0,restartRequired:!1},{key:"entityExtractionEnabled",label:"Entity Extraction Enabled",type:"boolean",group:"Advanced",liveApply:!0,restartRequired:!1},{key:"userMemoryEnabled",label:"User Memory Enabled",type:"boolean",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"userMemoryMaxContextTokens",label:"User Memory Max Context Tokens",type:"number",group:"Advanced",liveApply:!0,restartRequired:!1,min:0,max:8000}],j$={dbPath:["OPEN_MEM_DB_PATH"],provider:["OPEN_MEM_PROVIDER"],model:["OPEN_MEM_MODEL"],compressionEnabled:["OPEN_MEM_COMPRESSION"],contextInjectionEnabled:["OPEN_MEM_CONTEXT_INJECTION"],maxContextTokens:["OPEN_MEM_MAX_CONTEXT_TOKENS"],ignoredTools:["OPEN_MEM_IGNORED_TOOLS"],batchSize:["OPEN_MEM_BATCH_SIZE"],retentionDays:["OPEN_MEM_RETENTION_DAYS"],contextShowTokenCosts:["OPEN_MEM_CONTEXT_SHOW_TOKEN_COSTS"],contextFullObservationCount:["OPEN_MEM_CONTEXT_FULL_COUNT"],maxObservations:["OPEN_MEM_MAX_OBSERVATIONS"],dashboardEnabled:["OPEN_MEM_DASHBOARD"],dashboardPort:["OPEN_MEM_DASHBOARD_PORT"],platformOpenCodeEnabled:["OPEN_MEM_PLATFORM_OPENCODE"],platformClaudeCodeEnabled:["OPEN_MEM_PLATFORM_CLAUDE_CODE"],platformCursorEnabled:["OPEN_MEM_PLATFORM_CURSOR"],mcpProtocolVersion:["OPEN_MEM_MCP_PROTOCOL_VERSION"],mcpSupportedProtocolVersions:["OPEN_MEM_MCP_SUPPORTED_PROTOCOLS"],rerankingEnabled:["OPEN_MEM_RERANKING"],userMemoryEnabled:["OPEN_MEM_USER_MEMORY"]}});var qM={};CS(qM,{createOpenCodeBridge:()=>nO});function nO(S){let M=S;if(!M?.session?.create||!M?.session?.prompt)return null;let $=null,f=null;async function O(){if($)return $;if(f)return f;return f=(async()=>{try{let J=(await M.session.create({body:{title:"[open-mem] AI compression"}}))?.data?.id;if(!J)throw Error("No session ID returned");return $=J,J}finally{f=null}})(),f}async function A(y){let J=await O(),N=y.prompt||"";return{text:((await M.session.prompt({path:{id:J},body:{parts:[{type:"text",text:N}],system:y.system,tools:{},noReply:!1}}))?.data?.parts||[]).filter((Q)=>Q.type==="text").map((Q)=>Q.text||"").join(""),finishReason:"stop",usage:{promptTokens:0,completionTokens:0,totalTokens:0}}}async function V(){if($){try{await M.session.delete({path:{id:$}})}catch{}$=null}}return{generateText:A,cleanup:V}}import{existsSync as rO}from"fs";import{dirname as iO,join as S0}from"path";import{fileURLToPath as tO}from"url";var nM=new Set(["127.0.0.1","::1","localhost"]);function rM(S){return S.trim().toLowerCase()}function iM(S){return nM.has(rM(S))}function FS(S,M){if(iM(S))return;throw Error(`[open-mem] ${M} must bind to loopback only (127.0.0.1, ::1, localhost). Received "${S}".`)}import{randomUUID as Y0}from"crypto";import{normalize as u$,resolve as q1,sep as y2}from"path";import{fileURLToPath as w$}from"url";var K1=(S,M,$)=>{return(f,O)=>{let A=-1;return V(0);async function V(y){if(y<=A)throw Error("next() called multiple times");A=y;let J,N=!1,X;if(S[y])X=S[y][0][0],f.req.routeIndex=y;else X=y===S.length&&O||void 0;if(X)try{J=await X(f,()=>V(y+1))}catch(Z){if(Z instanceof Error&&M)f.error=Z,J=await M(Z,f),N=!0;else throw Z}else if(f.finalized===!1&&$)J=await $(f);if(J&&(f.finalized===!1||N))f.res=J;return f}}};var jS=Symbol();var TS=async(S,M=Object.create(null))=>{let{all:$=!1,dot:f=!1}=M,A=(S instanceof j0?S.raw.headers:S.headers).get("Content-Type");if(A?.startsWith("multipart/form-data")||A?.startsWith("application/x-www-form-urlencoded"))return tM(S,{all:$,dot:f});return{}};async function tM(S,M){let $=await S.formData();if($)return dM($,M);return{}}function dM(S,M){let $=Object.create(null);if(S.forEach((f,O)=>{if(!(M.all||O.endsWith("[]")))$[O]=f;else sM($,O,f)}),M.dot)Object.entries($).forEach(([f,O])=>{if(f.includes("."))aM($,f,O),delete $[f]});return $}var sM=(S,M,$)=>{if(S[M]!==void 0)if(Array.isArray(S[M]))S[M].push($);else S[M]=[S[M],$];else if(!M.endsWith("[]"))S[M]=$;else S[M]=[$]},aM=(S,M,$)=>{let f=S,O=M.split(".");O.forEach((A,V)=>{if(V===O.length-1)f[A]=$;else{if(!f[A]||typeof f[A]!=="object"||Array.isArray(f[A])||f[A]instanceof File)f[A]=Object.create(null);f=f[A]}})};var _1=(S)=>{let M=S.split("/");if(M[0]==="")M.shift();return M},xS=(S)=>{let{groups:M,path:$}=oM(S),f=_1($);return eM(f,M)},oM=(S)=>{let M=[];return S=S.replace(/\{[^}]+\}/g,($,f)=>{let O=`@${f}`;return M.push([O,$]),O}),{groups:M,path:S}},eM=(S,M)=>{for(let $=M.length-1;$>=0;$--){let[f]=M[$];for(let O=S.length-1;O>=0;O--)if(S[O].includes(f)){S[O]=S[O].replace(f,M[$][1]);break}}return S},T0={},IS=(S,M)=>{if(S==="*")return"*";let $=S.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);if($){let f=`${S}#${M}`;if(!T0[f])if($[2])T0[f]=M&&M[0]!==":"&&M[0]!=="*"?[f,$[1],new RegExp(`^${$[2]}(?=/${M})`)]:[S,$[1],new RegExp(`^${$[2]}$`)];else T0[f]=[S,$[1],!0];return T0[f]}return null},x0=(S,M)=>{try{return M(S)}catch{return S.replace(/(?:%[0-9A-Fa-f]{2})+/g,($)=>{try{return M($)}catch{return $}})}},S$=(S)=>x0(S,decodeURI),Y1=(S)=>{let M=S.url,$=M.indexOf("/",M.indexOf(":")+4),f=$;for(;f<M.length;f++){let O=M.charCodeAt(f);if(O===37){let A=M.indexOf("?",f),V=M.slice($,A===-1?void 0:A);return S$(V.includes("%25")?V.replace(/%25/g,"%2525"):V)}else if(O===63)break}return M.slice($,f)};var uS=(S)=>{let M=Y1(S);return M.length>1&&M.at(-1)==="/"?M.slice(0,-1):M},l=(S,M,...$)=>{if($.length)M=l(M,...$);return`${S?.[0]==="/"?"":"/"}${S}${M==="/"?"":`${S?.at(-1)==="/"?"":"/"}${M?.[0]==="/"?M.slice(1):M}`}`},I0=(S)=>{if(S.charCodeAt(S.length-1)!==63||!S.includes(":"))return null;let M=S.split("/"),$=[],f="";return M.forEach((O)=>{if(O!==""&&!/\:/.test(O))f+="/"+O;else if(/\:/.test(O))if(/\?/.test(O)){if($.length===0&&f==="")$.push("/");else $.push(f);let A=O.replace("?","");f+="/"+A,$.push(f)}else f+="/"+O}),$.filter((O,A,V)=>V.indexOf(O)===A)},W1=(S)=>{if(!/[%+]/.test(S))return S;if(S.indexOf("+")!==-1)S=S.replace(/\+/g," ");return S.indexOf("%")!==-1?x0(S,U1):S},wS=(S,M,$)=>{let f;if(!$&&M&&!/[%+]/.test(M)){let V=S.indexOf("?",8);if(V===-1)return;if(!S.startsWith(M,V+1))V=S.indexOf(`&${M}`,V+1);while(V!==-1){let y=S.charCodeAt(V+M.length+1);if(y===61){let J=V+M.length+2,N=S.indexOf("&",J);return W1(S.slice(J,N===-1?void 0:N))}else if(y==38||isNaN(y))return"";V=S.indexOf(`&${M}`,V+1)}if(f=/[%+]/.test(S),!f)return}let O={};f??=/[%+]/.test(S);let A=S.indexOf("?",8);while(A!==-1){let V=S.indexOf("&",A+1),y=S.indexOf("=",A);if(y>V&&V!==-1)y=-1;let J=S.slice(A+1,y===-1?V===-1?void 0:V:y);if(f)J=W1(J);if(A=V,J==="")continue;let N;if(y===-1)N="";else if(N=S.slice(y+1,V===-1?void 0:V),f)N=W1(N);if($){if(!(O[J]&&Array.isArray(O[J])))O[J]=[];O[J].push(N)}else O[J]??=N}return M?O[M]:O},kS=wS,qS=(S,M)=>{return wS(S,M,!0)},U1=decodeURIComponent;var gS=(S)=>x0(S,U1),j0=class{raw;#S;#M;routeIndex=0;path;bodyCache={};constructor(S,M="/",$=[[]]){this.raw=S,this.path=M,this.#M=$,this.#S={}}param(S){return S?this.#$(S):this.#A()}#$(S){let M=this.#M[0][this.routeIndex][1][S],$=this.#O(M);return $&&/\%/.test($)?gS($):$}#A(){let S={},M=Object.keys(this.#M[0][this.routeIndex][1]);for(let $ of M){let f=this.#O(this.#M[0][this.routeIndex][1][$]);if(f!==void 0)S[$]=/\%/.test(f)?gS(f):f}return S}#O(S){return this.#M[1]?this.#M[1][S]:S}query(S){return kS(this.url,S)}queries(S){return qS(this.url,S)}header(S){if(S)return this.raw.headers.get(S)??void 0;let M={};return this.raw.headers.forEach(($,f)=>{M[f]=$}),M}async parseBody(S){return this.bodyCache.parsedBody??=await TS(this,S)}#f=(S)=>{let{bodyCache:M,raw:$}=this,f=M[S];if(f)return f;let O=Object.keys(M)[0];if(O)return M[O].then((A)=>{if(O==="json")A=JSON.stringify(A);return new Response(A)[S]()});return M[S]=$[S]()};json(){return this.#f("text").then((S)=>JSON.parse(S))}text(){return this.#f("text")}arrayBuffer(){return this.#f("arrayBuffer")}blob(){return this.#f("blob")}formData(){return this.#f("formData")}addValidatedData(S,M){this.#S[S]=M}valid(S){return this.#S[S]}get url(){return this.raw.url}get method(){return this.raw.method}get[jS](){return this.#M}get matchedRoutes(){return this.#M[0].map(([[,S]])=>S)}get routePath(){return this.#M[0].map(([[,S]])=>S)[this.routeIndex].path}};var u0={Stringify:1,BeforeStream:2,Stream:3},M$=(S,M)=>{let $=new String(S);return $.isEscaped=!0,$.callbacks=M,$};var E0=async(S,M,$,f,O)=>{if(typeof S==="object"&&!(S instanceof String)){if(!(S instanceof Promise))S=S.toString();if(S instanceof Promise)S=await S}let A=S.callbacks;if(!A?.length)return Promise.resolve(S);if(O)O[0]+=S;else O=[S];let V=Promise.all(A.map((y)=>y({phase:M,buffer:O,context:f}))).then((y)=>Promise.all(y.filter(Boolean).map((J)=>E0(J,M,!1,f,O))).then(()=>O[0]));if($)return M$(await V,A);else return V};var vS="text/plain; charset=UTF-8",R1=(S,M)=>{return{"Content-Type":S,...M}},hS=class{#S;#M;env={};#$;finalized=!1;error;#A;#O;#f;#X;#y;#J;#N;#Z;#E;constructor(S,M){if(this.#S=S,M)this.#O=M.executionCtx,this.env=M.env,this.#J=M.notFoundHandler,this.#E=M.path,this.#Z=M.matchResult}get req(){return this.#M??=new j0(this.#S,this.#E,this.#Z),this.#M}get event(){if(this.#O&&"respondWith"in this.#O)return this.#O;else throw Error("This context has no FetchEvent")}get executionCtx(){if(this.#O)return this.#O;else throw Error("This context has no ExecutionContext")}get res(){return this.#f||=new Response(null,{headers:this.#N??=new Headers})}set res(S){if(this.#f&&S){S=new Response(S.body,S);for(let[M,$]of this.#f.headers.entries()){if(M==="content-type")continue;if(M==="set-cookie"){let f=this.#f.headers.getSetCookie();S.headers.delete("set-cookie");for(let O of f)S.headers.append("set-cookie",O)}else S.headers.set(M,$)}}this.#f=S,this.finalized=!0}render=(...S)=>{return this.#y??=(M)=>this.html(M),this.#y(...S)};setLayout=(S)=>this.#X=S;getLayout=()=>this.#X;setRenderer=(S)=>{this.#y=S};header=(S,M,$)=>{if(this.finalized)this.#f=new Response(this.#f.body,this.#f);let f=this.#f?this.#f.headers:this.#N??=new Headers;if(M===void 0)f.delete(S);else if($?.append)f.append(S,M);else f.set(S,M)};status=(S)=>{this.#A=S};set=(S,M)=>{this.#$??=new Map,this.#$.set(S,M)};get=(S)=>{return this.#$?this.#$.get(S):void 0};get var(){if(!this.#$)return{};return Object.fromEntries(this.#$)}#V(S,M,$){let f=this.#f?new Headers(this.#f.headers):this.#N??new Headers;if(typeof M==="object"&&"headers"in M){let A=M.headers instanceof Headers?M.headers:new Headers(M.headers);for(let[V,y]of A)if(V.toLowerCase()==="set-cookie")f.append(V,y);else f.set(V,y)}if($)for(let[A,V]of Object.entries($))if(typeof V==="string")f.set(A,V);else{f.delete(A);for(let y of V)f.append(A,y)}let O=typeof M==="number"?M:M?.status??this.#A;return new Response(S,{status:O,headers:f})}newResponse=(...S)=>this.#V(...S);body=(S,M,$)=>this.#V(S,M,$);text=(S,M,$)=>{return!this.#N&&!this.#A&&!M&&!$&&!this.finalized?new Response(S):this.#V(S,M,R1(vS,$))};json=(S,M,$)=>{return this.#V(JSON.stringify(S),M,R1("application/json",$))};html=(S,M,$)=>{let f=(O)=>this.#V(O,M,R1("text/html; charset=UTF-8",$));return typeof S==="object"?E0(S,u0.Stringify,!1,{}).then(f):f(S)};redirect=(S,M)=>{let $=String(S);return this.header("Location",!/[^\x00-\xFF]/.test($)?$:encodeURI($)),this.newResponse(null,M??302)};notFound=()=>{return this.#J??=()=>new Response,this.#J(this)}};var L="ALL",PS="all",mS=["get","post","put","delete","options","patch"],w0="Can not add a route since the matcher is already built.",k0=class extends Error{};var bS="__COMPOSED_HANDLER";var $$=(S)=>{return S.text("404 Not Found",404)},cS=(S,M)=>{if("getResponse"in S){let $=S.getResponse();return M.newResponse($.body,$)}return console.error(S),M.text("Internal Server Error",500)},lS=class S{get;post;put;delete;options;patch;all;on;use;router;getPath;_basePath="/";#S="/";routes=[];constructor(M={}){[...mS,PS].forEach((A)=>{this[A]=(V,...y)=>{if(typeof V==="string")this.#S=V;else this.#A(A,this.#S,V);return y.forEach((J)=>{this.#A(A,this.#S,J)}),this}}),this.on=(A,V,...y)=>{for(let J of[V].flat()){this.#S=J;for(let N of[A].flat())y.map((X)=>{this.#A(N.toUpperCase(),this.#S,X)})}return this},this.use=(A,...V)=>{if(typeof A==="string")this.#S=A;else this.#S="*",V.unshift(A);return V.forEach((y)=>{this.#A(L,this.#S,y)}),this};let{strict:f,...O}=M;Object.assign(this,O),this.getPath=f??!0?M.getPath??Y1:uS}#M(){let M=new S({router:this.router,getPath:this.getPath});return M.errorHandler=this.errorHandler,M.#$=this.#$,M.routes=this.routes,M}#$=$$;errorHandler=cS;route(M,$){let f=this.basePath(M);return $.routes.map((O)=>{let A;if($.errorHandler===cS)A=O.handler;else A=async(V,y)=>(await K1([],$.errorHandler)(V,()=>O.handler(V,y))).res,A[bS]=O.handler;f.#A(O.method,O.path,A)}),this}basePath(M){let $=this.#M();return $._basePath=l(this._basePath,M),$}onError=(M)=>{return this.errorHandler=M,this};notFound=(M)=>{return this.#$=M,this};mount(M,$,f){let O,A;if(f)if(typeof f==="function")A=f;else if(A=f.optionHandler,f.replaceRequest===!1)O=(J)=>J;else O=f.replaceRequest;let V=A?(J)=>{let N=A(J);return Array.isArray(N)?N:[N]}:(J)=>{let N=void 0;try{N=J.executionCtx}catch{}return[J.env,N]};O||=(()=>{let J=l(this._basePath,M),N=J==="/"?0:J.length;return(X)=>{let Z=new URL(X.url);return Z.pathname=Z.pathname.slice(N)||"/",new Request(Z,X)}})();let y=async(J,N)=>{let X=await $(O(J.req.raw),...V(J));if(X)return X;await N()};return this.#A(L,l(M,"*"),y),this}#A(M,$,f){M=M.toUpperCase(),$=l(this._basePath,$);let O={basePath:this._basePath,path:$,method:M,handler:f};this.router.add(M,$,[f,O]),this.routes.push(O)}#O(M,$){if(M instanceof Error)return this.errorHandler(M,$);throw M}#f(M,$,f,O){if(O==="HEAD")return(async()=>new Response(null,await this.#f(M,$,f,"GET")))();let A=this.getPath(M,{env:f}),V=this.router.match(O,A),y=new hS(M,{path:A,matchResult:V,env:f,executionCtx:$,notFoundHandler:this.#$});if(V[0].length===1){let N;try{N=V[0][0][0][0](y,async()=>{y.res=await this.#$(y)})}catch(X){return this.#O(X,y)}return N instanceof Promise?N.then((X)=>X||(y.finalized?y.res:this.#$(y))).catch((X)=>this.#O(X,y)):N??this.#$(y)}let J=K1(V[0],this.errorHandler,this.#$);return(async()=>{try{let N=await J(y);if(!N.finalized)throw Error("Context is not finalized. Did you forget to return a Response object or `await next()`?");return N.res}catch(N){return this.#O(N,y)}})()}fetch=(M,...$)=>{return this.#f(M,$[1],$[0],M.method)};request=(M,$,f,O)=>{if(M instanceof Request)return this.fetch($?new Request(M,$):M,f,O);return M=M.toString(),this.fetch(new Request(/^https?:\/\//.test(M)?M:`http://localhost${l("/",M)}`,$),f,O)};fire=()=>{addEventListener("fetch",(M)=>{M.respondWith(this.#f(M.request,M,void 0,M.request.method))})}};var Q0=[];function q0(S,M){let $=this.buildAllMatchers(),f=(O,A)=>{let V=$[O]||$[L],y=V[2][A];if(y)return y;let J=A.match(V[0]);if(!J)return[[],Q0];let N=J.indexOf("",1);return[V[1][N],J]};return this.match=f,f(S,M)}var g0="[^/]+",B0=".*",K0="(?:|/.*)",p=Symbol(),f$=new Set(".\\+*[^]$()");function O$(S,M){if(S.length===1)return M.length===1?S<M?-1:1:-1;if(M.length===1)return 1;if(S===B0||S===K0)return 1;else if(M===B0||M===K0)return-1;if(S===g0)return 1;else if(M===g0)return-1;return S.length===M.length?S<M?-1:1:M.length-S.length}var pS=class S{#S;#M;#$=Object.create(null);insert(M,$,f,O,A){if(M.length===0){if(this.#S!==void 0)throw p;if(A)return;this.#S=$;return}let[V,...y]=M,J=V==="*"?y.length===0?["","",B0]:["","",g0]:V==="/*"?["","",K0]:V.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/),N;if(J){let X=J[1],Z=J[2]||g0;if(X&&J[2]){if(Z===".*")throw p;if(Z=Z.replace(/^\((?!\?:)(?=[^)]+\)$)/,"(?:"),/\((?!\?:)/.test(Z))throw p}if(N=this.#$[Z],!N){if(Object.keys(this.#$).some((E)=>E!==B0&&E!==K0))throw p;if(A)return;if(N=this.#$[Z]=new S,X!=="")N.#M=O.varIndex++}if(!A&&X!=="")f.push([X,N.#M])}else if(N=this.#$[V],!N){if(Object.keys(this.#$).some((X)=>X.length>1&&X!==B0&&X!==K0))throw p;if(A)return;N=this.#$[V]=new S}N.insert(y,$,f,O,A)}buildRegExpStr(){let $=Object.keys(this.#$).sort(O$).map((f)=>{let O=this.#$[f];return(typeof O.#M==="number"?`(${f})@${O.#M}`:f$.has(f)?`\\${f}`:f)+O.buildRegExpStr()});if(typeof this.#S==="number")$.unshift(`#${this.#S}`);if($.length===0)return"";if($.length===1)return $[0];return"(?:"+$.join("|")+")"}};var nS=class{#S={varIndex:0};#M=new pS;insert(S,M,$){let f=[],O=[];for(let V=0;;){let y=!1;if(S=S.replace(/\{[^}]+\}/g,(J)=>{let N=`@\\${V}`;return O[V]=[N,J],V++,y=!0,N}),!y)break}let A=S.match(/(?::[^\/]+)|(?:\/\*$)|./g)||[];for(let V=O.length-1;V>=0;V--){let[y]=O[V];for(let J=A.length-1;J>=0;J--)if(A[J].indexOf(y)!==-1){A[J]=A[J].replace(y,O[V][1]);break}}return this.#M.insert(A,M,f,this.#S,$),f}buildRegExp(){let S=this.#M.buildRegExpStr();if(S==="")return[/^$/,[],[]];let M=0,$=[],f=[];return S=S.replace(/#(\d+)|@(\d+)|\.\*\$/g,(O,A,V)=>{if(A!==void 0)return $[++M]=Number(A),"$()";if(V!==void 0)return f[Number(V)]=++M,"";return""}),[new RegExp(`^${S}`),$,f]}};var A$=[/^$/,[],Object.create(null)],rS=Object.create(null);function iS(S){return rS[S]??=new RegExp(S==="*"?"":`^${S.replace(/\/\*$|([.\\+*[^\]$()])/g,(M,$)=>$?`\\${$}`:"(?:|/.*)")}$`)}function V$(){rS=Object.create(null)}function N$(S){let M=new nS,$=[];if(S.length===0)return A$;let f=S.map((N)=>[!/\*|\/:/.test(N[0]),...N]).sort(([N,X],[Z,E])=>N?1:Z?-1:X.length-E.length),O=Object.create(null);for(let N=0,X=-1,Z=f.length;N<Z;N++){let[E,Q,K]=f[N];if(E)O[Q]=[K.map(([W])=>[W,Object.create(null)]),Q0];else X++;let B;try{B=M.insert(Q,X,E)}catch(W){throw W===p?new k0(Q):W}if(E)continue;$[X]=K.map(([W,U])=>{let G=Object.create(null);U-=1;for(;U>=0;U--){let[H,z]=B[U];G[H]=z}return[W,G]})}let[A,V,y]=M.buildRegExp();for(let N=0,X=$.length;N<X;N++)for(let Z=0,E=$[N].length;Z<E;Z++){let Q=$[N][Z]?.[1];if(!Q)continue;let K=Object.keys(Q);for(let B=0,W=K.length;B<W;B++)Q[K[B]]=y[Q[K[B]]]}let J=[];for(let N in V)J[N]=$[V[N]];return[A,J,O]}function $0(S,M){if(!S)return;for(let $ of Object.keys(S).sort((f,O)=>O.length-f.length))if(iS($).test(M))return[...S[$]];return}var v0=class{name="RegExpRouter";#S;#M;constructor(){this.#S={[L]:Object.create(null)},this.#M={[L]:Object.create(null)}}add(S,M,$){let f=this.#S,O=this.#M;if(!f||!O)throw Error(w0);if(!f[S])[f,O].forEach((y)=>{y[S]=Object.create(null),Object.keys(y[L]).forEach((J)=>{y[S][J]=[...y[L][J]]})});if(M==="/*")M="*";let A=(M.match(/\/:/g)||[]).length;if(/\*$/.test(M)){let y=iS(M);if(S===L)Object.keys(f).forEach((J)=>{f[J][M]||=$0(f[J],M)||$0(f[L],M)||[]});else f[S][M]||=$0(f[S],M)||$0(f[L],M)||[];Object.keys(f).forEach((J)=>{if(S===L||S===J)Object.keys(f[J]).forEach((N)=>{y.test(N)&&f[J][N].push([$,A])})}),Object.keys(O).forEach((J)=>{if(S===L||S===J)Object.keys(O[J]).forEach((N)=>y.test(N)&&O[J][N].push([$,A]))});return}let V=I0(M)||[M];for(let y=0,J=V.length;y<J;y++){let N=V[y];Object.keys(O).forEach((X)=>{if(S===L||S===X)O[X][N]||=[...$0(f[X],N)||$0(f[L],N)||[]],O[X][N].push([$,A-J+y+1])})}}match=q0;buildAllMatchers(){let S=Object.create(null);return Object.keys(this.#M).concat(Object.keys(this.#S)).forEach((M)=>{S[M]||=this.#$(M)}),this.#S=this.#M=void 0,V$(),S}#$(S){let M=[],$=S===L;if([this.#S,this.#M].forEach((f)=>{let O=f[S]?Object.keys(f[S]).map((A)=>[A,f[S][A]]):[];if(O.length!==0)$||=!0,M.push(...O);else if(S!==L)M.push(...Object.keys(f[L]).map((A)=>[A,f[L][A]]))}),!$)return null;else return N$(M)}};var y$=class{name="PreparedRegExpRouter";#S;#M;constructor(S,M){this.#S=S,this.#M=M}#$(S,M){let $=this.#S[S];$[1].forEach((f)=>f&&f.push(M)),Object.values($[2]).forEach((f)=>f[0].push(M))}#A(S,M,$,f,O){let A=this.#S[S];if(!O)A[2][M][0].push([$,{}]);else f.forEach((V)=>{if(typeof V==="number")A[1][V].push([$,O]);else A[2][V||M][0].push([$,O])})}add(S,M,$){if(!this.#S[S]){let O=this.#S[L],A={};for(let V in O[2])A[V]=[O[2][V][0].slice(),Q0];this.#S[S]=[O[0],O[1].map((V)=>Array.isArray(V)?V.slice():0),A]}if(M==="/*"||M==="*"){let O=[$,{}];if(S===L)for(let A in this.#S)this.#$(A,O);else this.#$(S,O);return}let f=this.#M[M];if(!f)throw Error(`Path ${M} is not registered`);for(let[O,A]of f)if(S===L)for(let V in this.#S)this.#A(V,M,$,O,A);else this.#A(S,M,$,O,A)}buildAllMatchers(){return this.#S}match=q0};var z1=class{name="SmartRouter";#S=[];#M=[];constructor(S){this.#S=S.routers}add(S,M,$){if(!this.#M)throw Error(w0);this.#M.push([S,M,$])}match(S,M){if(!this.#M)throw Error("Fatal error");let $=this.#S,f=this.#M,O=$.length,A=0,V;for(;A<O;A++){let y=$[A];try{for(let J=0,N=f.length;J<N;J++)y.add(...f[J]);V=y.match(S,M)}catch(J){if(J instanceof k0)continue;throw J}this.match=y.match.bind(y),this.#S=[y],this.#M=void 0;break}if(A===O)throw Error("Fatal error");return this.name=`SmartRouter + ${this.activeRouter.name}`,V}get activeRouter(){if(this.#M||this.#S.length!==1)throw Error("No active router has been determined yet.");return this.#S[0]}};var W0=Object.create(null),tS=class S{#S;#M;#$;#A=0;#O=W0;constructor(M,$,f){if(this.#M=f||Object.create(null),this.#S=[],M&&$){let O=Object.create(null);O[M]={handler:$,possibleKeys:[],score:0},this.#S=[O]}this.#$=[]}insert(M,$,f){this.#A=++this.#A;let O=this,A=xS($),V=[];for(let y=0,J=A.length;y<J;y++){let N=A[y],X=A[y+1],Z=IS(N,X),E=Array.isArray(Z)?Z[0]:N;if(E in O.#M){if(O=O.#M[E],Z)V.push(Z[1]);continue}if(O.#M[E]=new S,Z)O.#$.push(Z),V.push(Z[1]);O=O.#M[E]}return O.#S.push({[M]:{handler:f,possibleKeys:V.filter((y,J,N)=>N.indexOf(y)===J),score:this.#A}}),O}#f(M,$,f,O){let A=[];for(let V=0,y=M.#S.length;V<y;V++){let J=M.#S[V],N=J[$]||J[L],X={};if(N!==void 0){if(N.params=Object.create(null),A.push(N),f!==W0||O&&O!==W0)for(let Z=0,E=N.possibleKeys.length;Z<E;Z++){let Q=N.possibleKeys[Z],K=X[N.score];N.params[Q]=O?.[Q]&&!K?O[Q]:f[Q]??O?.[Q],X[N.score]=!0}}}return A}search(M,$){let f=[];this.#O=W0;let A=[this],V=_1($),y=[];for(let J=0,N=V.length;J<N;J++){let X=V[J],Z=J===N-1,E=[];for(let Q=0,K=A.length;Q<K;Q++){let B=A[Q],W=B.#M[X];if(W)if(W.#O=B.#O,Z){if(W.#M["*"])f.push(...this.#f(W.#M["*"],M,B.#O));f.push(...this.#f(W,M,B.#O))}else E.push(W);for(let U=0,G=B.#$.length;U<G;U++){let H=B.#$[U],z=B.#O===W0?{}:{...B.#O};if(H==="*"){let q=B.#M["*"];if(q)f.push(...this.#f(q,M,B.#O)),q.#O=z,E.push(q);continue}let[w,k,I]=H;if(!X&&!(I instanceof RegExp))continue;let T=B.#M[w],L0=V.slice(J).join("/");if(I instanceof RegExp){let q=I.exec(L0);if(q){if(z[k]=q[0],f.push(...this.#f(T,M,B.#O,z)),Object.keys(T.#M).length){T.#O=z;let y1=q[0].match(/\//)?.length??0;(y[y1]||=[]).push(T)}continue}}if(I===!0||I.test(X))if(z[k]=X,Z){if(f.push(...this.#f(T,M,z,B.#O)),T.#M["*"])f.push(...this.#f(T.#M["*"],M,z,B.#O))}else T.#O=z,E.push(T)}}A=E.concat(y.shift()??[])}if(f.length>1)f.sort((J,N)=>{return J.score-N.score});return[f.map(({handler:J,params:N})=>[J,N])]}};var D1=class{name="TrieRouter";#S;constructor(){this.#S=new tS}add(S,M,$){let f=I0(M);if(f){for(let O=0,A=f.length;O<A;O++)this.#S.insert(S,f[O],$);return}this.#S.insert(S,M,$)}match(S,M){return this.#S.search(S,M)}};var G1=class extends lS{constructor(S={}){super(S);this.router=S.router??new z1({routers:[new v0,new D1]})}};I1();import{z as _}from"zod";var b0="1.0.0",t=_.enum(["decision","bugfix","feature","refactor","discovery","change"]),F={find:_.object({query:_.string().min(1),scope:_.enum(["project","user","all"]).optional().default("project"),types:_.array(t).optional(),limit:_.number().int().min(1).max(50).optional().default(10),cursor:_.string().optional(),include:_.object({snippets:_.boolean().optional(),scores:_.boolean().optional(),relations:_.boolean().optional()}).optional()}),history:_.object({limit:_.number().int().min(1).max(20).optional().default(5),cursor:_.string().optional(),sessionId:_.string().optional(),anchor:_.string().optional().describe("Observation ID to center the timeline around"),depthBefore:_.number().int().min(0).max(20).optional().default(5),depthAfter:_.number().int().min(0).max(20).optional().default(5)}),get:_.object({ids:_.array(_.string()).min(1),includeHistory:_.boolean().optional().default(!1),limit:_.number().int().min(1).max(50).optional().default(10)}),create:_.object({title:_.string(),type:t,narrative:_.string(),concepts:_.array(_.string()).optional(),files:_.array(_.string()).optional(),importance:_.number().int().min(1).max(5).optional(),scope:_.enum(["project","user"]).optional().default("project")}),revise:_.object({id:_.string(),title:_.string().optional(),narrative:_.string().optional(),type:t.optional(),concepts:_.array(_.string()).optional(),importance:_.number().int().min(1).max(5).optional(),reason:_.string().optional()}),remove:_.object({id:_.string(),reason:_.string().optional()}),transferExport:_.object({scope:_.enum(["project"]).optional().default("project"),type:t.optional(),limit:_.number().int().min(1).optional(),format:_.enum(["json"]).optional().default("json")}),transferImport:_.object({payload:_.string(),mode:_.enum(["skip","merge","replace"]).optional().default("skip")}),maintenance:_.object({action:_.enum(["folderContextDryRun","folderContextClean","folderContextRebuild","folderContextPurge"])}),help:_.object({})},c0=[{name:"mem-find",schema:"find",description:"Search past memories \u2014 decisions, discoveries, gotchas, and session history. Use to recall context from previous sessions before starting work."},{name:"mem-history",schema:"history",description:"Browse session timeline and summaries. Use to understand what happened in recent sessions or drill into a specific session."},{name:"mem-get",schema:"get",description:"Fetch full memory details by ID. Use after mem-find or mem-history to get complete narratives, facts, and file lists."},{name:"mem-create",schema:"create",description:"Save an important observation to memory. Use for decisions + rationale, non-obvious gotchas, user preferences, or cross-session plans that auto-capture wouldn't understand the significance of."},{name:"mem-revise",schema:"revise",description:"Update an existing memory with a new revision. Use when a previous decision changed, a gotcha was resolved, or information became outdated."},{name:"mem-remove",schema:"remove",description:"Tombstone an obsolete or incorrect memory. Use to clean up memories that are no longer accurate or relevant."},{name:"mem-export",schema:"transferExport",description:"Export project memories as portable JSON for backup or transfer between machines."},{name:"mem-import",schema:"transferImport",description:"Import memories from a JSON export. Skips duplicates by default."},{name:"mem-maintenance",schema:"maintenance",description:"Run folder context maintenance \u2014 clean, rebuild, purge, or dry-run AGENTS.md files."},{name:"mem-help",schema:"help",description:"Show detailed memory workflow guidance including when to save, what to save, and memory type reference."}];function u1(S){return c0.find((M)=>M.name===S)??null}function Y(S,M={}){return{data:S,error:null,meta:M}}function R(S,M,$){return{data:null,error:{code:S,message:M,details:$},meta:{}}}L1();class w1{evaluate(S){let M=[];if(!S.adapterStatuses.some(($)=>$.enabled))M.push("No platform adapters are enabled.");if(S.config.compressionEnabled&&S.config.provider!=="bedrock"&&!S.config.apiKey)M.push("Compression is enabled but no provider API key is configured.");if(S.runtime.status==="degraded")M.push("Runtime status is degraded.");if(S.runtime.queue.lastError)M.push(`Queue reported an error: ${S.runtime.queue.lastError}`);if(M.length===0)return{ready:!0,status:"ready",reasons:[]};return{ready:!1,status:S.runtime.status==="degraded"?"degraded":"initializing",reasons:M}}}import{existsSync as x$}from"fs";import{dirname as I$}from"path";class k1{run(S){let M=[];return M.push(this.checkDbDir(S)),M.push(this.checkProviderConfig(S)),M.push(this.checkVectorSupport(S)),M.push(this.checkAdapters(S)),M.push(this.checkDashboardPort(S)),{ok:M.every((f)=>f.status!=="fail"),checks:M}}checkDbDir(S){let M=I$(S.dbPath);return x$(M)?{id:"db-dir",status:"pass",message:"Database directory exists.",details:{dir:M}}:{id:"db-dir",status:"warn",message:"Database directory does not exist yet. It will be created on first run.",details:{dir:M}}}checkProviderConfig(S){if(!S.compressionEnabled)return{id:"provider-config",status:"pass",message:"Compression is disabled; provider API key is optional."};if(S.provider==="bedrock")return{id:"provider-config",status:"pass",message:"Bedrock provider selected; API key is not required."};if(!S.apiKey)return{id:"provider-config",status:"fail",message:"Compression is enabled but no provider API key is configured.",details:{provider:S.provider}};return{id:"provider-config",status:"pass",message:"Provider API key is configured.",details:{provider:S.provider}}}checkVectorSupport(S){if(!(S.provider==="google"||S.provider==="openai"||S.provider==="bedrock"))return{id:"vector-support",status:"warn",message:"Provider does not support embeddings; search will use FTS-only fallback.",details:{provider:S.provider}};return{id:"vector-support",status:"pass",message:"Provider supports embeddings.",details:{provider:S.provider,dimension:S.embeddingDimension}}}checkAdapters(S){let M=[["opencode",S.platformOpenCodeEnabled!==!1],["claude-code",S.platformClaudeCodeEnabled===!0],["cursor",S.platformCursorEnabled===!0]].filter(([,$])=>$);if(M.length===0)return{id:"adapters",status:"fail",message:"No platform adapters are enabled."};return{id:"adapters",status:"pass",message:`Enabled adapters: ${M.map(([$])=>$).join(", ")}`}}checkDashboardPort(S){if(!S.dashboardEnabled)return{id:"dashboard",status:"pass",message:"Dashboard is disabled."};if(S.dashboardPort<1||S.dashboardPort>65535)return{id:"dashboard",status:"fail",message:"Dashboard port is outside the valid range (1-65535).",details:{dashboardPort:S.dashboardPort}};return{id:"dashboard",status:"pass",message:"Dashboard port configuration looks valid.",details:{dashboardPort:S.dashboardPort}}}}var k$=new Set(t.options);function g1(S,M,$=100){if(!S)return M;let f=Number.parseInt(S,10);if(Number.isNaN(f))return M;return Math.max(1,Math.min(f,$))}function q$(S){if(!S)return 0;let M=Number.parseInt(S,10);if(Number.isNaN(M))return 0;return Math.max(0,M)}function J2(S){if(!S)return;if(k$.has(S))return S;return}function l0(S){let M={};for(let[$,f]of Object.entries(S)){let O=$.toLowerCase();M[$]=typeof f==="string"&&(O.includes("key")||O.includes("api"))?"***REDACTED***":f}return M}function p0(S){return{status:S.status,timestamp:S.timestamp,uptimeMs:process.uptime()*1000,queue:{mode:"in-process",running:!1,processing:!1,pending:0,lastBatchDurationMs:0,lastProcessedAt:null,lastFailedAt:null,lastError:null},batches:{total:0,processedItems:0,failedItems:0,avgDurationMs:0},enqueueCount:0}}function X2(S){let{projectPath:M,memoryEngine:$,runtimeStatusProvider:f,dashboardDir:O}=S,A=new G1,V=new w1,y=new k1;A.get("/v1/memory/observations",(N)=>{let X=g1(N.req.query("limit"),50),Z=q$(N.req.query("offset")),E=J2(N.req.query("type")),Q=N.req.query("sessionId"),K=N.req.query("state"),B=K==="current"||K==="superseded"||K==="tombstoned"?K:void 0,W=$.listObservations({limit:X,offset:Z,type:E,sessionId:Q,state:B});return N.json(Y(W,{limit:X,offset:Z}))}),A.post("/v1/memory/observations",async(N)=>{try{let X=await N.req.json(),Z=await $.save({...X,sessionId:X.sessionId??`http-${Date.now()}`});if(!Z)return N.json(R("CONFLICT","Unable to create observation"),409);return N.json(Y(Z),201)}catch{return N.json(R("VALIDATION_ERROR","Invalid JSON body"),400)}}),A.get("/v1/memory/observations/:id",(N)=>{let X=N.req.param("id"),Z=$.getObservation(X);if(!Z)return N.json(R("NOT_FOUND","Observation not found"),404);return N.json(Y(Z))}),A.get("/v1/memory/observations/:id/lineage",(N)=>{let X=N.req.param("id"),Z=$.getLineage(X);if(!Z)return N.json(R("NOT_FOUND","Observation not found"),404);return N.json(Y({observationId:X,lineage:Z}))}),A.get("/v1/memory/observations/:id/revision-diff",(N)=>{let X=N.req.param("id"),Z=N.req.query("against");if(!Z)return N.json(R("VALIDATION_ERROR","Query parameter 'against' is required"),400);let E=$.getRevisionDiff(X,Z);if(!E)return N.json(R("NOT_FOUND","One or both observations not found"),404);return N.json(Y(E))}),A.post("/v1/memory/observations/:id/revisions",async(N)=>{let X=N.req.param("id");try{let Z=await N.req.json(),E=await $.update({id:X,...Z});if(!E)return N.json(R("NOT_FOUND","Observation not found"),404);return N.json(Y({previousId:X,newId:E.id,observation:E}))}catch{return N.json(R("VALIDATION_ERROR","Invalid JSON body"),400)}}),A.post("/v1/memory/observations/:id/tombstone",async(N)=>{let X=N.req.param("id");if(await $.delete([X])===0)return N.json(R("NOT_FOUND","Observation not found"),404);return N.json(Y({id:X,tombstoned:!0}))}),A.get("/v1/memory/sessions",(N)=>{let X=g1(N.req.query("limit"),20),Z=N.req.query("projectPath")||M;return N.json(Y($.listSessions({limit:X,projectPath:Z}),{limit:X}))}),A.get("/v1/memory/sessions/:id",(N)=>{let X=N.req.param("id"),Z=$.getSession(X);if(!Z)return N.json(R("NOT_FOUND","Session not found"),404);return N.json(Y({...Z.session,observations:Z.observations,summary:Z.summary}))}),A.get("/v1/memory/search",async(N)=>{let X=N.req.query("q");if(!X)return N.json(R("VALIDATION_ERROR","Query parameter 'q' is required"),400);let Z=J2(N.req.query("type")),E=g1(N.req.query("limit"),20);try{let Q=await $.search(X,{type:Z,limit:E});return N.json(Y(Q,{limit:E}))}catch{return N.json(Y([],{limit:E}))}}),A.post("/v1/memory/recall",async(N)=>{try{let X=await N.req.json(),Z=await $.recall(X.ids??[],X.limit??10);return N.json(Y(Z))}catch{return N.json(R("VALIDATION_ERROR","Invalid JSON body"),400)}}),A.post("/v1/memory/export",async(N)=>{try{let X=await N.req.json().catch(()=>({})),Z=await $.export("project",{type:X.type,limit:X.limit});return N.json(Y(Z))}catch(X){return N.json(R("INTERNAL_ERROR",String(X)),500)}}),A.post("/v1/memory/import",async(N)=>{try{let X=await N.req.json(),Z=X.mode==="replace"?"overwrite":"skip-duplicates",E=await $.import(X.payload,{mode:Z});return N.json(Y(E))}catch{return N.json(R("VALIDATION_ERROR","Invalid import payload"),400)}}),A.get("/v1/memory/stats",(N)=>{return N.json(Y($.stats()))}),A.get("/v1/health",(N)=>{let X=$.getHealth(),Z=$.getMetrics(),Q=f?.()??p0(X);return N.json(Y({status:Q.status,timestamp:Q.timestamp,uptimeMs:Q.uptimeMs,queue:Q.queue,memory:{totalObservations:Z.memory.totalObservations,totalSessions:Z.memory.totalSessions}}))}),A.get("/v1/readiness",(N)=>{let X=$.getHealth(),Z=f?.()??p0(X),E=V.evaluate({config:S.config,adapterStatuses:$.getAdapterStatuses().map((Q)=>({name:Q.name,enabled:Q.enabled})),runtime:{status:Z.status,queue:{lastError:Z.queue.lastError}}});return N.json(Y(E),E.ready?200:503)}),A.get("/v1/diagnostics",(N)=>{let X=y.run(S.config);return N.json(Y(X),X.ok?200:503)}),A.get("/v1/tools/guide",(N)=>{return N.json(Y({contractVersion:b0,workflow:{recommended:["mem-find","mem-history","mem-get"],description:"Start with compact discovery, then timeline context, then full detail fetch by IDs."},tools:c0}))}),A.get("/v1/queue",(N)=>{let X=$.getHealth(),Z=f?.()??p0(X);return N.json(Y({contractVersion:b0,queue:Z.queue,batches:Z.batches,enqueueCount:Z.enqueueCount}))}),A.post("/v1/queue/process",async(N)=>{let X=await $.processPending();return N.json(Y({processed:X}))}),A.get("/v1/metrics",(N)=>{let X=$.getHealth(),E=f?.()??p0(X);return N.json(Y(E))}),A.get("/v1/platforms",(N)=>{let X=$.getAdapterStatuses();return N.json(Y({platforms:X.map((Z)=>({name:Z.name,version:Z.version,enabled:Z.enabled,capabilities:Z.capabilities}))}))}),A.get("/v1/adapters/status",(N)=>{return N.json(Y($.getAdapterStatuses()))}),A.get("/v1/config/schema",(N)=>N.json(Y(j1()))),A.get("/v1/config/effective",async(N)=>{let X=await r(M);return N.json(Y({config:l0(X.config),meta:X.meta,warnings:X.warnings}))}),A.post("/v1/config/preview",async(N)=>{try{let X=await N.req.json(),Z=await x1(M,X);return N.json(Y({config:l0(Z.config),meta:Z.meta,warnings:Z.warnings}))}catch{return N.json(R("VALIDATION_ERROR","Invalid JSON body"),400)}}),A.patch("/v1/config",async(N)=>{let X;try{X=await N.req.json()}catch{return N.json(R("VALIDATION_ERROR","Invalid JSON body"),400)}try{let Z=await i(M),E=await m0(M,X),Q={};for(let K of Object.keys(X))if(Object.hasOwn(Z,K))Q[K]=Z[K];return $.trackConfigAudit({id:Y0(),timestamp:new Date().toISOString(),patch:X,previousValues:Q,source:"api"}),N.json(Y({config:l0(E.config),meta:E.meta,warnings:E.warnings}))}catch(Z){return N.json(R("INTERNAL_ERROR",String(Z)),500)}}),A.get("/v1/config/audit",(N)=>{return N.json(Y($.getConfigAuditTimeline()))}),A.post("/v1/config/rollback",async(N)=>{let X;try{X=await N.req.json()}catch{return N.json(R("VALIDATION_ERROR","Invalid JSON body"),400)}if(!X.eventId)return N.json(R("VALIDATION_ERROR","eventId is required"),400);try{let Z=await $.rollbackConfig(X.eventId);if(!Z)return N.json(R("NOT_FOUND","Audit event not found"),404);return N.json(Y(Z))}catch(Z){return N.json(R("INTERNAL_ERROR",String(Z)),500)}});let J={balanced:{minOutputLength:50,contextFullObservationCount:3,maxObservations:50,batchSize:5},focus:{minOutputLength:120,contextFullObservationCount:2,maxObservations:30,batchSize:3},chill:{minOutputLength:200,contextFullObservationCount:1,maxObservations:15,batchSize:2,compressionEnabled:!1}};if(A.get("/v1/modes",(N)=>N.json(Y({modes:Object.entries(J).map(([X,Z])=>({id:X,patch:Z}))}))),A.post("/v1/modes/:id/apply",async(N)=>{let X=N.req.param("id"),Z=J[X];if(!Z)return N.json(R("NOT_FOUND","Unknown mode"),404);try{let E=await i(M),Q=await m0(M,Z),K={};for(let B of Object.keys(Z))if(Object.hasOwn(E,B))K[B]=E[B];return $.trackConfigAudit({id:Y0(),timestamp:new Date().toISOString(),patch:Z,previousValues:K,source:"mode"}),N.json(Y({applied:X,config:l0(Q.config),meta:Q.meta,warnings:Q.warnings}))}catch(E){return N.json(R("INTERNAL_ERROR",String(E)),500)}}),A.get("/v1/workflow-modes",(N)=>N.json(Y({modes:P0().map((X)=>eS(X))}))),A.post("/v1/maintenance/folder-context/dry-run",async(N)=>{try{let Z=(await N.req.json().catch(()=>({}))).action??"clean",E=await $.maintainFolderContext(Z,!0);return $.trackMaintenanceResult({id:Y0(),timestamp:new Date().toISOString(),action:`folder-context-${Z}-dry-run`,dryRun:!0,result:E}),N.json(Y(E))}catch(X){return N.json(R("INTERNAL_ERROR",String(X)),500)}}),A.post("/v1/maintenance/folder-context/clean",async(N)=>{try{let X=await $.maintainFolderContext("clean",!1);return $.trackMaintenanceResult({id:Y0(),timestamp:new Date().toISOString(),action:"folder-context-clean",dryRun:!1,result:X}),N.json(Y(X))}catch(X){return N.json(R("INTERNAL_ERROR",String(X)),500)}}),A.post("/v1/maintenance/folder-context/rebuild",async(N)=>{try{let X=await $.maintainFolderContext("rebuild",!1);return $.trackMaintenanceResult({id:Y0(),timestamp:new Date().toISOString(),action:"folder-context-rebuild",dryRun:!1,result:X}),N.json(Y(X))}catch(X){return N.json(R("INTERNAL_ERROR",String(X)),500)}}),A.get("/v1/maintenance/history",(N)=>{return N.json(Y($.getMaintenanceHistory()))}),S.sseHandler)A.get("/v1/events",S.sseHandler);return A.get("*",async(N)=>{let X=N.req.path;if(X.startsWith("/v1/"))return N.json(R("NOT_FOUND","Not found"),404);let Z=O??q1(w$(import.meta.url),"../../dist/dashboard"),E=u$(Z),Q=E.endsWith(y2)?E:`${E}${y2}`,K=X==="/"?"index.html":X.replace(/^\//,""),B=q1(Z,K);if(!B.startsWith(Q))return N.json(R("NOT_FOUND","Not found"),404);try{let U=Bun.file(B);if(await U.exists())return new Response(U)}catch{}let W=q1(Z,"index.html");if(!W.startsWith(Q))return N.json(R("NOT_FOUND","Not found"),404);try{let U=Bun.file(W);if(await U.exists())return new Response(U,{headers:{"Content-Type":"text/html; charset=utf-8"}})}catch{}return N.json(R("NOT_FOUND","Dashboard not found. Run the dashboard build first."),404)}),A}var v1=class{writer;encoder;writable;abortSubscribers=[];responseReadable;aborted=!1;closed=!1;constructor(S,M){this.writable=S,this.writer=S.getWriter(),this.encoder=new TextEncoder;let $=M.getReader();this.abortSubscribers.push(async()=>{await $.cancel()}),this.responseReadable=new ReadableStream({async pull(f){let{done:O,value:A}=await $.read();O?f.close():f.enqueue(A)},cancel:()=>{this.abort()}})}async write(S){try{if(typeof S==="string")S=this.encoder.encode(S);await this.writer.write(S)}catch{}return this}async writeln(S){return await this.write(S+`
|
|
3
|
+
`),this}sleep(S){return new Promise((M)=>setTimeout(M,S))}async close(){try{await this.writer.close()}catch{}this.closed=!0}async pipe(S){this.writer.releaseLock(),await S.pipeTo(this.writable,{preventClose:!0}),this.writer=this.writable.getWriter()}onAbort(S){this.abortSubscribers.push(S)}abort(){if(!this.aborted)this.aborted=!0,this.abortSubscribers.forEach((S)=>S())}};var n0=()=>{let S=typeof Bun<"u"?Bun.version:void 0;if(S===void 0)return!1;let M=S.startsWith("1.1")||S.startsWith("1.0")||S.startsWith("0.");return n0=()=>M,M};var Z2=class extends v1{constructor(S,M){super(S,M)}async writeSSE(S){let $=(await E0(S.data,u0.Stringify,!1,{})).split(/\r\n|\r|\n/).map((O)=>{return`data: ${O}`}).join(`
|
|
4
|
+
`),f=[S.event&&`event: ${S.event}`,$,S.id&&`id: ${S.id}`,S.retry&&`retry: ${S.retry}`].filter(Boolean).join(`
|
|
5
5
|
`)+`
|
|
6
6
|
|
|
7
|
-
`;await this.write(
|
|
8
|
-
${
|
|
7
|
+
`;await this.write(f)}},g$=async(S,M,$)=>{try{await M(S)}catch(f){if(f instanceof Error&&$)await $(f,S),await S.writeSSE({event:"error",data:f.message});else console.error(f)}finally{S.close()}},v$=new WeakMap,h1=(S,M,$)=>{let{readable:f,writable:O}=new TransformStream,A=new Z2(O,f);if(n0())S.req.raw.signal.addEventListener("abort",()=>{if(!A.closed)A.abort()});return v$.set(A.responseReadable,S),S.header("Transfer-Encoding","chunked"),S.header("Content-Type","text/event-stream"),S.header("Cache-Control","no-cache"),S.header("Connection","keep-alive"),g$(A,M,$),S.newResponse(A.responseReadable)};class P1{eventBus;clients=new Set;cleanups=[];constructor(S){this.eventBus=S;this.subscribeToAll()}addClient(S){this.clients.add(S)}removeClient(S){this.clients.delete(S)}get clientCount(){return this.clients.size}destroy(){for(let S of this.cleanups)S();this.cleanups=[],this.clients.clear()}subscribeToAll(){let S=["observation:created","observation:updated","session:started","session:ended","summary:created","pending:enqueued","pending:processed"];for(let M of S){let $=(f)=>this.broadcast(M,f);this.eventBus.on(M,$),this.cleanups.push(()=>this.eventBus.off(M,$))}}broadcast(S,M){let $=JSON.stringify(M);for(let f of this.clients)try{let O=f(S,$);if(O&&typeof O.catch==="function")O.catch(()=>this.clients.delete(f))}catch{this.clients.delete(f)}}}var P$=30000;function E2(S){return(M)=>{return h1(M,async($)=>{let f=(A,V)=>{$.writeSSE({event:A,data:V,id:Date.now().toString()})};S.addClient(f);let O=setInterval(()=>{$.writeSSE({event:"heartbeat",data:"",id:Date.now().toString()})},P$);$.onAbort(()=>{S.removeClient(f),clearInterval(O)});while(!$.aborted)await $.sleep(1000)})}}function C(S){return JSON.stringify(S,null,2)}function m$(S,M){return S.filter(($)=>M==="all"?!0:M==="user"?$.source==="user":$.source!=="user").map(($)=>({id:$.observation.id,title:$.observation.title,type:$.observation.type,summary:$.observation.narrative,snippet:$.snippet,score:$.rank,source:$.source??"project",createdAt:$.observation.createdAt}))}function Q2(S){let M=($)=>{let f=u1($);if(!f)throw Error(`Missing tool contract metadata for ${$}`);return f.description};return{"mem-find":{description:M("mem-find"),args:F.find.shape,execute:async($)=>{try{let f=F.find.parse($),O=await S.search(f.query,{limit:f.limit,type:f.types?.[0]}),A=Y({results:m$(O,f.scope),nextCursor:null});return C(A)}catch(f){return C(R("VALIDATION_ERROR","Invalid find arguments",String(f)))}}},"mem-history":{description:M("mem-history"),args:F.history.shape,execute:async($)=>{try{let f=F.history.parse($),O=await S.timeline({limit:f.limit,sessionId:f.sessionId,anchor:f.anchor,depthBefore:f.depthBefore,depthAfter:f.depthAfter});return C(Y({items:O,nextCursor:null}))}catch(f){return C(R("VALIDATION_ERROR","Invalid history arguments",String(f)))}}},"mem-get":{description:M("mem-get"),args:F.get.shape,execute:async($)=>{try{let f=F.get.parse($),O=await S.recall(f.ids,f.limit);return C(Y({observations:O}))}catch(f){return C(R("VALIDATION_ERROR","Invalid get arguments",String(f)))}}},"mem-create":{description:M("mem-create"),args:F.create.shape,execute:async($,f)=>{try{let O=F.create.parse($),A=await S.save({...O,sessionId:f.sessionID});if(!A)return C(R("CONFLICT","Unable to create memory"));return C(Y({observation:A}))}catch(O){return C(R("VALIDATION_ERROR","Invalid create arguments",String(O)))}}},"mem-revise":{description:M("mem-revise"),args:F.revise.shape,execute:async($)=>{try{let f=F.revise.parse($),O=await S.update(f);if(!O)return C(R("NOT_FOUND",`Observation ${f.id} not found`));return C(Y({previousId:f.id,newId:O.id,observation:O}))}catch(f){return C(R("VALIDATION_ERROR","Invalid revise arguments",String(f)))}}},"mem-remove":{description:M("mem-remove"),args:F.remove.shape,execute:async($)=>{try{let f=F.remove.parse($);if(await S.delete([f.id])===0)return C(R("NOT_FOUND",`Observation ${f.id} not found`));return C(Y({id:f.id,tombstoned:!0}))}catch(f){return C(R("VALIDATION_ERROR","Invalid remove arguments",String(f)))}}},"mem-export":{description:M("mem-export"),args:F.transferExport.shape,execute:async($)=>{try{let f=F.transferExport.parse($),O=await S.export("project",{type:f.type,limit:f.limit});return C(Y({payload:O,format:f.format}))}catch(f){return C(R("VALIDATION_ERROR","Invalid export arguments",String(f)))}}},"mem-import":{description:M("mem-import"),args:F.transferImport.shape,execute:async($)=>{try{let f=F.transferImport.parse($),O=f.mode==="replace"?"overwrite":"skip-duplicates",A=await S.import(f.payload,{mode:O});return C(Y({imported:A.imported,skipped:A.skipped,mode:f.mode}))}catch(f){return C(R("VALIDATION_ERROR","Invalid import arguments",String(f)))}}},"mem-maintenance":{description:M("mem-maintenance"),args:F.maintenance.shape,execute:async($)=>{try{let f=F.maintenance.parse($);if(f.action==="folderContextDryRun")return C(Y(await S.maintainFolderContext("clean",!0)));if(f.action==="folderContextClean")return C(Y(await S.maintainFolderContext("clean",!1)));if(f.action==="folderContextPurge")return C(Y(await S.maintainFolderContext("purge",!1)));return C(Y(await S.maintainFolderContext("rebuild",!1)))}catch(f){return C(R("VALIDATION_ERROR","Invalid maintenance arguments",String(f)))}}},"mem-help":{description:M("mem-help"),args:F.help.shape,execute:async()=>C(Y({guide:S.guide()}))}}}import{generateText as s$}from"ai";function c(S){if(typeof S!=="object"||S===null)return!1;let M=S,$=M.status;if($===429||$===500||$===503)return!0;let f=M.error;if(typeof f==="object"&&f!==null&&f.type==="overloaded_error")return!0;return!1}function U0(S){if(S&&typeof S==="object"){let M=S.status;if(typeof M==="number")return M===400||M===401||M===403}return!1}function d(S){return new Promise((M)=>setTimeout(M,S))}var b$=new Set(["decision","bugfix","feature","refactor","discovery","change"]);function D(S,M){let $=new RegExp(`<${M}[^>]*>([\\s\\S]*?)</${M}>`,"i"),f=S.match($);return f?f[1].trim():""}function v(S,M){let $=new RegExp(`<${M}[^>]*>([\\s\\S]*?)</${M}>`,"gi"),f=[];for(let O of S.matchAll($)){let A=O[1].trim();if(A)f.push(A)}return f}function B2(S){let M=D(S,"observation");if(!M)return null;let $=D(M,"type").toLowerCase(),f=b$.has($)?$:"discovery",O=D(M,"title")||"Untitled observation",A=D(M,"subtitle"),V=D(M,"narrative"),y=v(D(M,"facts"),"fact"),J=v(D(M,"concepts"),"concept"),N=v(D(M,"files_read"),"file"),X=v(D(M,"files_modified"),"file"),Z=D(M,"importance"),E=Number.parseInt(Z,10),Q=Number.isNaN(E)?3:Math.max(1,Math.min(5,E));return{type:f,title:O,subtitle:A,facts:y,narrative:V,concepts:J,filesRead:N,filesModified:X,importance:Q}}function K2(S){let M=D(S,"session_summary");if(!M)return null;let $=D(M,"summary")||"No summary available",f=v(D(M,"key_decisions"),"decision"),O=v(D(M,"files_modified"),"file"),A=v(D(M,"concepts"),"concept"),V=D(M,"request")||void 0,y=D(M,"investigated")||void 0,J=D(M,"learned")||void 0,N=D(M,"completed")||void 0,X=D(M,"next_steps")||void 0;return{summary:$,keyDecisions:f,filesModified:O,concepts:A,request:V,investigated:y,learned:J,completed:N,nextSteps:X}}function W2(S){let M=D(S,"reranked");if(!M)return null;let $=v(M,"index");if($.length===0)return null;let f=[];for(let O of $){let A=Number.parseInt(O,10);if(Number.isNaN(A)||A<0)return null;f.push(A)}return f}var c$=new Set(["new_fact","update","duplicate"]);function _2(S){let M=D(S,"evaluation");if(!M)return null;let $=D(M,"outcome").toLowerCase().trim();if(!c$.has($))return null;let f=$,O=D(M,"reason");if(!O)return null;let A=D(M,"supersedes"),V={outcome:f,reason:O};if(f==="update"&&A)V.supersedesId=A;if(f==="update"&&!V.supersedesId)return null;return V}var l$=new Set(["technology","library","pattern","concept","file","person","project","other"]),p$=new Set(["uses","depends_on","implements","extends","related_to","replaces","configures"]);function Y2(S){let M=D(S,"extraction");if(!M)return null;let $=D(M,"entities"),f=D(M,"relations"),O=v($,"entity"),A=[];for(let J of O){let N=D(J,"name");if(!N)continue;let X=D(J,"type").toLowerCase(),Z=l$.has(X)?X:"other";A.push({name:N,entityType:Z})}let V=v(f,"relation"),y=[];for(let J of V){let N=D(J,"source"),X=D(J,"target"),Z=D(J,"relationship").toLowerCase();if(!N||!X||!Z)continue;if(!p$.has(Z))continue;y.push({sourceName:N,targetName:X,relationship:Z})}return{entities:A,relations:y}}function j(S){return Math.ceil(S.length/4)}function U2(S,M,$,f){let O=$?`<session_context>
|
|
8
|
+
${$}
|
|
9
9
|
</session_context>
|
|
10
10
|
|
|
11
|
-
`:"",
|
|
11
|
+
`:"",A=f?f.observationTypes.join("|"):"decision|bugfix|feature|refactor|discovery|change",y=(f?f.conceptVocabulary:["how-it-works","why-it-exists","what-changed","problem-solution","gotcha","pattern","trade-off"]).map((J)=>{let X={"how-it-works":"Technical mechanisms and behaviors","why-it-exists":"Rationale and motivations","what-changed":"Modifications and their effects","problem-solution":"Issues encountered and how they were resolved",gotcha:"Surprising behaviors, edge cases, or pitfalls",pattern:"Recurring design patterns or approaches","trade-off":"Deliberate compromises between competing concerns",hypothesis:"Proposed explanations or predictions",finding:"Key results or discoveries",methodology:"Research methods and approaches",evidence:"Supporting data or observations",limitation:"Known constraints or boundaries",implication:"Consequences or downstream effects",comparison:"Similarities and differences between approaches"}[J];return X?`- ${J}: ${X}`:`- ${J}`}).join(`
|
|
12
12
|
`);return`<task>
|
|
13
13
|
Analyze the following tool output and extract a structured observation.
|
|
14
14
|
</task>
|
|
@@ -19,16 +19,16 @@ Analyze the following tool output and extract a structured observation.
|
|
|
19
19
|
${M}
|
|
20
20
|
</tool_output>
|
|
21
21
|
|
|
22
|
-
${
|
|
22
|
+
${O}<instructions>
|
|
23
23
|
Extract a structured observation from the tool output. Determine the most appropriate type and provide a concise but informative summary.
|
|
24
24
|
|
|
25
25
|
When extracting concepts, prefer established vocabulary where appropriate:
|
|
26
|
-
${
|
|
26
|
+
${y}
|
|
27
27
|
You may also use any domain-specific concepts relevant to the observation.
|
|
28
28
|
|
|
29
29
|
Respond with EXACTLY this XML format:
|
|
30
30
|
<observation>
|
|
31
|
-
<type>${
|
|
31
|
+
<type>${A}</type>
|
|
32
32
|
<title>Brief descriptive title (max 80 chars)</title>
|
|
33
33
|
<subtitle>One-line elaboration</subtitle>
|
|
34
34
|
<importance>1-5 (1=trivial/routine, 2=low, 3=normal, 4=significant, 5=critical decision or discovery)</importance>
|
|
@@ -48,9 +48,9 @@ Respond with EXACTLY this XML format:
|
|
|
48
48
|
<file>path/to/file/modified</file>
|
|
49
49
|
</files_modified>
|
|
50
50
|
</observation>
|
|
51
|
-
</instructions>`}function
|
|
52
|
-
<title>${
|
|
53
|
-
<narrative>${
|
|
51
|
+
</instructions>`}function R2(S,M){let $=S.map((f,O)=>` <obs index="${O+1}" type="${f.type}">
|
|
52
|
+
<title>${f.title}</title>
|
|
53
|
+
<narrative>${f.narrative}</narrative>
|
|
54
54
|
</obs>`).join(`
|
|
55
55
|
`);return`<task>
|
|
56
56
|
Summarize the following coding session based on its observations.
|
|
@@ -59,7 +59,7 @@ Summarize the following coding session based on its observations.
|
|
|
59
59
|
<session_id>${M}</session_id>
|
|
60
60
|
|
|
61
61
|
<observations>
|
|
62
|
-
${
|
|
62
|
+
${$}
|
|
63
63
|
</observations>
|
|
64
64
|
|
|
65
65
|
<instructions>
|
|
@@ -83,11 +83,11 @@ Respond with EXACTLY this XML format:
|
|
|
83
83
|
<concept>key-concept</concept>
|
|
84
84
|
</concepts>
|
|
85
85
|
</session_summary>
|
|
86
|
-
</instructions>`}function
|
|
87
|
-
<title>${
|
|
88
|
-
<narrative>${
|
|
89
|
-
<concepts>${
|
|
90
|
-
<type>${
|
|
86
|
+
</instructions>`}function z2(S,M){let $=M.map((f)=>` <candidate id="${f.id}">
|
|
87
|
+
<title>${f.title}</title>
|
|
88
|
+
<narrative>${f.narrative}</narrative>
|
|
89
|
+
<concepts>${f.concepts.join(", ")}</concepts>
|
|
90
|
+
<type>${f.type}</type>
|
|
91
91
|
</candidate>`).join(`
|
|
92
92
|
`);return`<conflict_evaluation>
|
|
93
93
|
<new_observation>
|
|
@@ -97,7 +97,7 @@ Respond with EXACTLY this XML format:
|
|
|
97
97
|
<type>${S.type}</type>
|
|
98
98
|
</new_observation>
|
|
99
99
|
<existing_candidates>
|
|
100
|
-
${
|
|
100
|
+
${$}
|
|
101
101
|
</existing_candidates>
|
|
102
102
|
<instructions>
|
|
103
103
|
Evaluate whether the new observation represents:
|
|
@@ -112,22 +112,22 @@ Respond with EXACTLY this XML format:
|
|
|
112
112
|
<reason>Brief explanation</reason>
|
|
113
113
|
</evaluation>
|
|
114
114
|
</instructions>
|
|
115
|
-
</conflict_evaluation>`}function
|
|
115
|
+
</conflict_evaluation>`}function D2(S,M){let $=[...S.filesRead,...S.filesModified],f=M?M.entityTypes.join(", "):"technology, library, pattern, concept, file, person, project, other",O=M?M.relationshipTypes.join(", "):"uses, depends_on, implements, extends, related_to, replaces, configures";return`<entity_extraction>
|
|
116
116
|
<observation>
|
|
117
117
|
<title>${S.title}</title>
|
|
118
118
|
<type>${S.type}</type>
|
|
119
119
|
<narrative>${S.narrative}</narrative>
|
|
120
120
|
<facts>${S.facts.join(`
|
|
121
121
|
`)}</facts>
|
|
122
|
-
<files>${
|
|
122
|
+
<files>${$.join(`
|
|
123
123
|
`)}</files>
|
|
124
124
|
<concepts>${S.concepts.join(", ")}</concepts>
|
|
125
125
|
</observation>
|
|
126
126
|
<instructions>
|
|
127
127
|
Extract entities and relationships from this observation.
|
|
128
128
|
|
|
129
|
-
Entity types: ${
|
|
130
|
-
Relationship types: ${
|
|
129
|
+
Entity types: ${f}
|
|
130
|
+
Relationship types: ${O}
|
|
131
131
|
|
|
132
132
|
Extract entities that are clearly mentioned or strongly implied. For example, "React hooks" implies a relationship between React and hooks. Do not extract speculative relationships.
|
|
133
133
|
Respond with EXACTLY this XML format:
|
|
@@ -141,11 +141,11 @@ Respond with EXACTLY this XML format:
|
|
|
141
141
|
</relations>
|
|
142
142
|
</extraction>
|
|
143
143
|
</instructions>
|
|
144
|
-
</entity_extraction>`}function
|
|
144
|
+
</entity_extraction>`}function G2(S,M){let $=M.map((f,O)=>` <candidate index="${O}"><title>${f.title}</title><narrative>${f.narrative}</narrative></candidate>`).join(`
|
|
145
145
|
`);return`<rerank_request>
|
|
146
146
|
<query>${S}</query>
|
|
147
147
|
<candidates>
|
|
148
|
-
${
|
|
148
|
+
${$}
|
|
149
149
|
</candidates>
|
|
150
150
|
<instructions>Reorder the candidates by relevance to the query. Return indices from most to least relevant.
|
|
151
151
|
|
|
@@ -156,63 +156,64 @@ Respond with EXACTLY this XML format:
|
|
|
156
156
|
<index>0</index>
|
|
157
157
|
</reranked>
|
|
158
158
|
</instructions>
|
|
159
|
-
</rerank_request>`}class
|
|
160
|
-
|
|
161
|
-
[... truncated ...]`:M,
|
|
162
|
-
`)}function
|
|
163
|
-
**Read cost:** ~${M}t | **Discovery cost:** ~${
|
|
164
|
-
Recent sessions:`);for(let
|
|
165
|
-
Recent observations (${S.observationIndex.length} entries):`);for(let
|
|
166
|
-
`)}function
|
|
167
|
-
`)}function
|
|
168
|
-
Cross-project observations (${
|
|
169
|
-
`)}var
|
|
170
|
-
`);await
|
|
171
|
-
`)}async function
|
|
159
|
+
</rerank_request>`}class m1{shouldFailover(S){let{error:M,attemptIndex:$,totalProviders:f}=S;if(U0(M))return!1;if($>=f-1)return!1;return c(M)}onFailover(S){let M=S.error?.status??"unknown";if(!S.nextProvider)return;console.error(`[open-mem] Provider ${S.provider} failed (${M}), falling over to ${S.nextProvider}`)}}class b1{specificationVersion;provider;modelId;supportedUrls;providers;policy;constructor(S,M=new m1){if(S.length===0)throw Error("At least one provider required");let $=S[0].model;this.specificationVersion=$.specificationVersion,this.provider=$.provider,this.modelId=$.modelId,this.supportedUrls=$.supportedUrls,this.providers=S,this.policy=M}async doGenerate(S){let M;for(let $=0;$<this.providers.length;$++){let f=this.providers[$];try{return this.policy.onAttempt?.({error:null,provider:f.name,nextProvider:this.providers[$+1]?.name,attemptIndex:$,totalProviders:this.providers.length}),await f.model.doGenerate(S)}catch(O){if(M=O,U0(O))throw O;let A=this.providers[$+1]?.name,V={error:O,provider:f.name,nextProvider:A,attemptIndex:$,totalProviders:this.providers.length};if(this.policy.shouldFailover(V)){this.policy.onFailover(V);continue}throw this.policy.onFinalFailure?.(V),O}}throw M}async doStream(S){let M;for(let $=0;$<this.providers.length;$++){let f=this.providers[$];try{return this.policy.onAttempt?.({error:null,provider:f.name,nextProvider:this.providers[$+1]?.name,attemptIndex:$,totalProviders:this.providers.length}),await f.model.doStream(S)}catch(O){if(M=O,U0(O))throw O;let A=this.providers[$+1]?.name,V={error:O,provider:f.name,nextProvider:A,attemptIndex:$,totalProviders:this.providers.length};if(this.policy.shouldFailover(V)){this.policy.onFailover(V);continue}throw this.policy.onFinalFailure?.(V),O}}throw M}}var n$={"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 r$(S){if(S.includes("."))return S;return n$[S]||`us.anthropic.${S}-v1:0`}function H2(S){switch(S.provider){case"anthropic":{let{createAnthropic:M}=g("@ai-sdk/anthropic");return M({apiKey:S.apiKey})(S.model)}case"bedrock":{let{createAmazonBedrock:M}=g("@ai-sdk/amazon-bedrock");return M()(r$(S.model))}case"openai":{let{createOpenAI:M}=g("@ai-sdk/openai");return M({apiKey:S.apiKey})(S.model)}case"google":{let{createGoogleGenerativeAI:M}=g("@ai-sdk/google");return M({apiKey:S.apiKey})(S.model)}case"openrouter":{let{createOpenRouter:M}=g("@openrouter/ai-sdk-provider");return M({apiKey:S.apiKey})(S.model)}default:throw Error(`Unknown provider: ${S.provider}. Supported: anthropic, bedrock, openai, google, openrouter`)}}function L2(S){try{switch(S.provider){case"google":{let{createGoogleGenerativeAI:M}=g("@ai-sdk/google");return M({apiKey:S.apiKey}).embedding("text-embedding-004")}case"openai":{let{createOpenAI:M}=g("@ai-sdk/openai");return M({apiKey:S.apiKey}).embedding("text-embedding-3-small")}case"bedrock":{let{createAmazonBedrock:M}=g("@ai-sdk/amazon-bedrock");return M().embedding("amazon.titan-embed-text-v2:0")}case"anthropic":return null;case"openrouter":return null;default:return null}}catch{return null}}var i$={google:"gemini-2.5-flash-lite",anthropic:"claude-sonnet-4-20250514",openai:"gpt-4o-mini",bedrock:"us.anthropic.claude-3-5-haiku-20241022-v1:0",openrouter:"google/gemini-2.5-flash-lite"};function t$(S){switch(S){case"google":return process.env.GOOGLE_GENERATIVE_AI_API_KEY||process.env.GEMINI_API_KEY;case"anthropic":return process.env.ANTHROPIC_API_KEY;case"openai":return process.env.OPENAI_API_KEY;case"openrouter":return process.env.OPENROUTER_API_KEY;case"bedrock":return;default:return}}function h(S){if(!S.fallbackProviders||S.fallbackProviders.length===0)return[];return S.fallbackProviders.map((M)=>({provider:M,model:i$[M]??"gemini-2.5-flash-lite",apiKey:t$(M)}))}function P(S,M=[],$){let f=H2(S);if(M.length===0)return f;let O=[{name:S.provider,model:f},...M.map((A)=>({name:A.provider,model:H2(A)}))];return new b1(O,$)}var d$={"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},C2=0;async function m(S,M){if(!M)return;let $=d$[S]||5,f=Math.ceil(60000/$)+100,A=Date.now()-C2;if(A<f){let V=f-A;await new Promise((y)=>setTimeout(y,V))}C2=Date.now()}class R0{model;config;_generate=s$;constructor(S){this.config=S,this.model=null;let M=S.provider!=="bedrock";if(S.compressionEnabled&&(!M||S.apiKey))try{this.model=P({provider:S.provider,model:S.model,apiKey:S.apiKey},h(S))}catch{}}static MAX_INPUT_LENGTH=50000;async compress(S,M,$){if(!this.config.compressionEnabled||!this.model)return null;if(M.length<this.config.minOutputLength)return null;let f=j(M),O=M.length>R0.MAX_INPUT_LENGTH?`${M.substring(0,R0.MAX_INPUT_LENGTH)}
|
|
160
|
+
|
|
161
|
+
[... truncated ...]`:M,A=U2(S,O,$),V=2;for(let y=0;y<=V;y++)try{if(this.config.provider==="google")await m(this.config.model,this.config.rateLimitingEnabled);let{text:J}=await this._generate({model:this.model,maxOutputTokens:this.config.maxTokensPerCompression,prompt:A}),N=B2(J);if(N)N.discoveryTokens=f;return N}catch(J){if(c(J)&&y<V){let N=2**y*1000;await d(N);continue}return null}return null}async compressBatch(S){let M=new Map;for(let $=0;$<S.length;$++){let f=S[$],O=await this.compress(f.toolName,f.toolOutput,f.sessionContext);if(M.set(f.callId,O),$<S.length-1)await d(200)}return M}createFallbackObservation(S,M){let $=e$(M),f=a$[S]??"discovery";return{type:f,title:`${S} execution`,subtitle:M.substring(0,100).replace(/\n/g," "),facts:[],narrative:`Tool ${S} was executed. Output length: ${M.length} chars.`,concepts:[],filesRead:f==="discovery"?$:[],filesModified:f==="change"?$:[],discoveryTokens:j(M),importance:2}}async isAvailable(){if(!this.model)return!1;try{return await this._generate({model:this.model,maxOutputTokens:10,prompt:"ping"}),!0}catch{return!1}}}var a$={Read:"discovery",Write:"change",Edit:"change",Bash:"change",Glob:"discovery",Grep:"discovery"},o$=/(?:^|\s)((?:\.\/|\/|src\/|tests\/|lib\/)\S+\.\w+)/gm;function e$(S){let M=[];for(let $ of S.matchAll(o$))M.push($[1]);return[...new Set(M)]}import{generateText as Sf}from"ai";class c1{model;config;_generate=Sf;constructor(S){if(this.config=S,this.model=null,S.provider==="bedrock"||S.apiKey)try{this.model=P({provider:S.provider,model:S.model,apiKey:S.apiKey},h(S))}catch{}}async evaluate(S,M){if(!this.model||M.length===0)return null;let $=z2(S,M),f=2;for(let O=0;O<=f;O++)try{if(this.config.provider==="google")await m(this.config.model,this.config.rateLimitingEnabled);let{text:A}=await this._generate({model:this.model,maxOutputTokens:512,prompt:$});return _2(A)}catch(A){if(c(A)&&O<f){let V=2**O*1000;await d(V);continue}return null}return null}}import{generateText as Mf}from"ai";class l1{model;config;_generate=Mf;constructor(S){if(this.config=S,this.model=null,S.provider==="bedrock"||S.apiKey)try{this.model=P({provider:S.provider,model:S.model,apiKey:S.apiKey},h(S))}catch{}}async extract(S){if(!this.model)return null;let M=D2(S),$=2;for(let f=0;f<=$;f++)try{if(this.config.provider==="google")await m(this.config.model,this.config.rateLimitingEnabled);let{text:O}=await this._generate({model:this.model,maxOutputTokens:1024,prompt:M});return Y2(O)}catch(O){if(c(O)&&f<$){let A=2**f*1000;await d(A);continue}return null}return null}}import{generateText as $f}from"ai";class p1{model;config;_generate=$f;constructor(S){this.config=S,this.model=null;let M=S.provider!=="bedrock";if(S.compressionEnabled&&(!M||S.apiKey))try{this.model=P({provider:S.provider,model:S.model,apiKey:S.apiKey},h(S))}catch{}}async summarize(S,M){if(M.length===0)return null;if(!this.config.compressionEnabled||!this.model)return this.createFallbackSummary(M);let $=R2(M.map((f)=>({type:f.type,title:f.title,narrative:f.narrative})),S);try{if(this.config.provider==="google")await m(this.config.model,this.config.rateLimitingEnabled);let{text:f}=await this._generate({model:this.model,maxOutputTokens:this.config.maxTokensPerCompression,prompt:$}),O=K2(f);if(!O)return this.createFallbackSummary(M);return O}catch{return this.createFallbackSummary(M)}}createFallbackSummary(S){let M=new Set,$=new Set,f=[];for(let y of S){for(let J of y.filesModified)M.add(J);for(let J of y.concepts)$.add(J);if(y.type==="decision")f.push(y.title)}let O=new Map;for(let y of S)O.set(y.type,(O.get(y.type)??0)+1);let A=Array.from(O.entries()).map(([y,J])=>`${J} ${y}${J>1?"s":""}`).join(", "),V=Array.from($).slice(0,5).join(", ");return{summary:`Session with ${S.length} observations: ${A}. Files modified: ${M.size}. Key concepts: ${V}.`,keyDecisions:f.slice(0,5),filesModified:Array.from(M),concepts:Array.from($)}}shouldSummarize(S){return S>=2}}F1();import{randomUUID as b2}from"crypto";var ff={showTokenCosts:!0,observationTypes:"all",fullObservationCount:3,showLastSummary:!0},z0={bugfix:"\uD83D\uDD34",feature:"\uD83D\uDFE3",refactor:"\uD83D\uDD04",change:"\u2705",discovery:"\uD83D\uDD35",decision:"\u2696\uFE0F"};function r0(S,M=ff){let $=[];if($.push("## open-mem: Past Session Memory"),$.push(""),$.push("**\uD83D\uDCA1 Progressive Disclosure:** This is a compact index showing WHAT was observed and retrieval COST."),$.push("Use `mem-find` to find observations by query, then `mem-get` with IDs to fetch full details."),$.push(""),$.push("**3-Layer Memory Access:**"),$.push("- **Layer 1** `mem-find` \u2014 Find observations by query (returns IDs + summaries)"),$.push("- **Layer 2** `mem-history` \u2014 Browse session history and drill into sessions"),$.push("- **Layer 3** `mem-get` \u2014 Get full details by ID (use IDs from search results or the index below)"),$.push(""),$.push("**\uD83D\uDCDD When to Save (`mem-create`):** Proactively save decisions + rationale, non-obvious gotchas/workarounds, user preferences, and cross-session plans. Auto-capture handles tool executions \u2014 use `mem-create` for insights auto-capture can't understand the significance of. Wrap sensitive content in `<private>` tags to exclude from memory. Call `mem-help` for detailed guidance."),M.showLastSummary&&S.recentSummaries.length>0){$.push(""),$.push("### Recent Sessions"),$.push("| Session | Summary | Decisions |"),$.push("|---------|---------|-----------|");for(let V of S.recentSummaries){let y=V.keyDecisions.length>0?V.keyDecisions.join("; "):"\u2014";$.push(`| ${V.sessionId} | ${V.summary} | ${y} |`)}}let f=M.observationTypes==="all"?S.observationIndex:S.observationIndex.filter((V)=>M.observationTypes.includes(V.type));if(f.length>0){$.push(""),$.push(`### Recent Observations (${f.length} entries)`);let V=Af(f,S.fullObservations);for(let[y,J]of V){if($.push(""),$.push(`**${y}**`),M.showTokenCosts)$.push("| ID | Type | Title | ~Tokens |"),$.push("|----|------|-------|---------|");else $.push("| ID | Type | Title |"),$.push("|----|------|-------|");for(let N of J){let X=z0[N.type]||"\uD83D\uDCDD";if(M.showTokenCosts)$.push(`| ${N.id} | ${X} | ${N.title} | ~${N.tokenCount} |`);else $.push(`| ${N.id} | ${X} | ${N.title} |`)}}}let O=S.fullObservations.slice(0,M.fullObservationCount);if(O.length>0){$.push(""),$.push("### Full Details (most recent)");for(let V of O){let y=z0[V.type]||"\uD83D\uDCDD";if($.push(""),$.push(`#### ${y} ${V.title} (${V.id})`),$.push(V.narrative),V.facts.length>0)$.push(`**Facts:** ${V.facts.map((N)=>`- ${N}`).join(" ")}`);if(V.concepts.length>0)$.push(`**Concepts:** ${V.concepts.join(", ")}`);let J=[...V.filesRead,...V.filesModified];if(J.length>0)$.push(`**Files:** ${J.join(", ")}`)}}let A=Of(S);if(A)$.push(""),$.push(A);return $.join(`
|
|
162
|
+
`)}function Of(S){let M=0,$=0,f=new Set(S.observationIndex.map((V)=>V.id));for(let V of S.observationIndex)M+=V.tokenCount,$+=V.discoveryTokens;for(let V of S.fullObservations)if(!f.has(V.id))M+=V.tokenCount,$+=V.discoveryTokens;if($===0)return null;let O=$-M,A=Math.max(0,Math.round(O/$*100));return`### \uD83D\uDCB0 Memory Economics
|
|
163
|
+
**Read cost:** ~${M}t | **Discovery cost:** ~${$}t | **Savings:** ${A}% (${O}t saved)`}function Af(S,M){let $=new Map;for(let O of M){let A=O.filesModified[0]||O.filesRead[0];if(A)$.set(O.id,A)}let f=new Map;for(let O of S){let A=$.get(O.id)??"General",V=f.get(A)??[];V.push(O),f.set(A,V)}return f}function i0(S){let M=[];if(M.push("[open-mem] Memory context:"),S.recentSummaries.length>0){M.push(`
|
|
164
|
+
Recent sessions:`);for(let $ of S.recentSummaries)M.push(`- ${$.summary}`)}if(S.observationIndex.length>0){M.push(`
|
|
165
|
+
Recent observations (${S.observationIndex.length} entries):`);for(let $ of S.observationIndex)M.push(`- ${z0[$.type]||"\uD83D\uDCDD"} ${$.title}`)}return M.join(`
|
|
166
|
+
`)}function t0(S,M){if(S.length===0)return"";let $=M,f=[];for(let A of S){let V=A.tokenCount||j(A.title);if($-V<0)break;f.push(A),$-=V}if(f.length===0)return"";let O=[];O.push("### Cross-Project Memory"),O.push(""),O.push("| ID | Type | Title | ~Tokens |"),O.push("|----|------|-------|---------|");for(let A of f){let V=z0[A.type]||"\uD83D\uDCDD";O.push(`| ${A.id} | ${V} | ${A.title} | ~${A.tokenCount} |`)}return O.join(`
|
|
167
|
+
`)}function d0(S,M){if(S.length===0)return"";let $=M,f=[];for(let A of S){let V=A.tokenCount||j(A.title);if($-V<0)break;f.push(A),$-=V}if(f.length===0)return"";let O=[];O.push(`
|
|
168
|
+
Cross-project observations (${f.length} entries):`);for(let A of f)O.push(`- ${z0[A.type]||"\uD83D\uDCDD"} ${A.title}`);return O.join(`
|
|
169
|
+
`)}var s0={recency:0.4,typeImportance:0.3,sessionAffinity:0.2,tokenEfficiency:0.1},Vf={decision:1,bugfix:0.9,feature:0.8,refactor:0.6,discovery:0.5,change:0.4};function Nf(S,M){let $=new Date(S),O=(M.getTime()-$.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 yf(S){return Vf[S]??0.3}function Jf(S,M){if(!M)return 0.5;return S===M?1:0.3}function Xf(S){if(S<=10)return 1;if(S>=200)return 0.2;return 1-(S-10)/190*0.8}function Zf(S,M){let $=Nf(S.createdAt,M.now),f=yf(S.type),O=Jf(S.sessionId,M.currentSessionId),A=Xf(S.tokenCount);return $*s0.recency+f*s0.typeImportance+O*s0.sessionAffinity+A*s0.tokenEfficiency}function F2(S,M){let $=new Map;for(let f of S)$.set(f.id,Zf(f,M));return[...S].sort((f,O)=>{let A=$.get(f.id)??0,V=$.get(O.id)??0;if(V!==A)return V-A;return new Date(O.createdAt).getTime()-new Date(f.createdAt).getTime()})}function O0(S,M,$,f,O=[],A){let V=f,y=[],J=[];for(let X of M){let Z=X.tokenCount||j(X.summary);if(V-Z<0)break;y.push(X),V-=Z}let N=A?F2($,A):$;for(let X of N){let Z=X.tokenCount||j(X.title);if(V-Z<0)break;J.push(X),V-=Z}return{recentSummaries:y,observationIndex:J,fullObservations:[...O],totalTokens:f-V}}import{existsSync as a1}from"fs";import{readdir as Df,readFile as k2,unlink as s1,writeFile as q2}from"fs/promises";import{join as o1,resolve as e1}from"path";import{existsSync as T2}from"fs";import{mkdir as Ef,readFile as Qf,rename as Bf,unlink as Kf,writeFile as Wf}from"fs/promises";import{dirname as a0,isAbsolute as i1,join as D0,normalize as _f,relative as t1,resolve as V0,sep as n1}from"path";var A0="<!-- open-mem-context -->",s="<!-- /open-mem-context -->",x2={bugfix:"\uD83D\uDD34",feature:"\uD83D\uDFE3",refactor:"\uD83D\uDD04",change:"\u2705",discovery:"\uD83D\uDD35",decision:"\u2696\uFE0F"},j2=new Map,Yf=new Set(["node_modules",".git","dist","coverage",".open-mem","build","__pycache__",".next",".nuxt"]);async function o0(S,M,$){if(M.length===0)return;if($.mode==="single")return Uf(S,M,$);let{maxDepth:f,filename:O}=$,A=[];for(let J of M){for(let N of J.filesModified)A.push(N);for(let N of J.filesRead)A.push(N)}let V=u2(A,S,f);if(V.size===0)return;let y=w2(M,V,S);for(let[J,N]of y)try{let X=Rf(J,N,S);await I2(J,X,O)}catch(X){console.error(`[open-mem] Failed to update AGENTS.md in ${J}:`,X)}}async function Uf(S,M,$){let{maxDepth:f,filename:O}=$,A=M.filter(r1);if(A.length===0)return;let V=[];for(let Q of A){for(let K of Q.filesModified)V.push(K);for(let K of Q.filesRead)V.push(K)}let y=u2(V,S,f),J=w2(A,y,S),N=A.filter((Q)=>{return[...Q.filesModified,...Q.filesRead].some((B)=>{if(!B)return!1;let W=i1(B)?B:D0(S,B);return V0(a0(W))===V0(S)})});if(N.length>0)J.set(V0(S),N);if(J.size===0)return;let X=[];X.push("## Project Activity (auto-generated by open-mem)"),X.push("");let Z=[...J.entries()].map(([Q,K])=>({relPath:t1(S,Q)||".",observations:K})).sort((Q,K)=>Q.relPath.localeCompare(K.relPath));for(let{relPath:Q,observations:K}of Z){let B=K.filter(r1).sort((G,H)=>H.createdAt.localeCompare(G.createdAt)).slice(0,10);if(B.length===0)continue;X.push(`### ${Q}/`),X.push("| ID | Type | Title | Date |"),X.push("|----|------|-------|------|");for(let G of B){let H=x2[G.type]||"\uD83D\uDCDD",z=G.createdAt.split("T")[0],w=G.title.replace(/\|/g,"\\|");X.push(`| ${G.id} | ${H} ${G.type} | ${w} | ${z} |`)}let W=new Set;for(let G of B)for(let H of G.concepts)W.add(H);if(W.size>0){let G=[...W].slice(0,10).join(", ");X.push(""),X.push(`**Key concepts:** ${G}`)}let U=B.filter((G)=>G.type==="decision").map((G)=>G.title);if(U.length>0)X.push(""),X.push(`**Recent decisions:** ${U.slice(0,5).join("; ")}`);X.push("")}X.push("\uD83D\uDCA1 *Use `mem-find` to search full details. Use `mem-create` to save important decisions.*");let E=X.join(`
|
|
170
|
+
`);await I2(S,E,O)}function r1(S){return!/^\w[\w-]*\s+execution$/i.test(S.title)}function Rf(S,M,$){let f=[...M].filter(r1).sort((N,X)=>X.createdAt.localeCompare(N.createdAt)).slice(0,10),O=t1($,S)||".",A=[];A.push(`## Recent Activity in \`${O}/\` (auto-generated by open-mem)`),A.push(""),A.push("| ID | Type | Title | Date |"),A.push("|----|------|-------|------|");for(let N of f){let X=x2[N.type]||"\uD83D\uDCDD",Z=N.createdAt.split("T")[0],E=N.title.replace(/\|/g,"\\|");A.push(`| ${N.id} | ${X} ${N.type} | ${E} | ${Z} |`)}let V=new Set;for(let N of f)for(let X of N.concepts)V.add(X);if(V.size>0){let N=[...V].slice(0,10).join(", ");A.push(""),A.push(`**Key concepts:** ${N}`)}let y=f.filter((N)=>N.type==="decision").map((N)=>N.title);if(y.length>0)A.push(""),A.push(`**Recent decisions:** ${y.slice(0,5).join("; ")}`);let J=f.filter((N)=>N.type==="decision"&&N.narrative).slice(0,3);if(J.length>0){A.push(""),A.push("**Decision details:**");for(let N of J){let X=N.narrative.split(/[.!?]\s/)[0],Z=X.length>120?`${X.slice(0,117)}...`:X;A.push(`- \u2696\uFE0F ${N.title}: ${Z}`)}}return A.push(""),A.push("\uD83D\uDCA1 *Use `mem-find` to search full details across all sessions. Use `mem-create` to save important decisions.*"),A.join(`
|
|
171
|
+
`)}async function I2(S,M,$){if(!T2(S))return;let O=(j2.get(S)??Promise.resolve()).then(async()=>{let A=D0(S,$),V=D0(S,`.${$}.tmp`),y="";try{y=await Qf(A,"utf-8")}catch{}let J=zf(y,M);try{await Ef(a0(V),{recursive:!0}),await Wf(V,J,"utf-8"),await Bf(V,A)}catch(N){try{await Kf(V)}catch{}throw N}});return j2.set(S,O.catch(()=>{})),O}function zf(S,M){if(!S)return`${A0}
|
|
172
172
|
${M}
|
|
173
173
|
${s}
|
|
174
|
-
`;let
|
|
174
|
+
`;let $=S.indexOf(A0),f=S.indexOf(s);if($!==-1&&f!==-1&&f>$){let A=S.substring(0,$),V=S.substring(f+s.length);return`${A}${A0}
|
|
175
175
|
${M}
|
|
176
|
-
${s}${
|
|
176
|
+
${s}${V}`}let O=S;if($!==-1&&f===-1)O=O.replace(A0,"").trim();else if($===-1&&f!==-1)O=O.replace(s,"").trim();else if($!==-1&&f!==-1&&f<=$)O=O.replace(s,"").replace(A0,"").trim();return`${O}
|
|
177
177
|
|
|
178
178
|
${A0}
|
|
179
179
|
${M}
|
|
180
180
|
${s}
|
|
181
|
-
`}function
|
|
182
|
-
`:""}if(M===-1
|
|
183
|
-
`:""}if(
|
|
184
|
-
`:""}let
|
|
185
|
-
`;if(!
|
|
186
|
-
`;return`${
|
|
187
|
-
|
|
188
|
-
${
|
|
189
|
-
`}async function
|
|
190
|
-
|
|
191
|
-
${
|
|
192
|
-
`)}listObservations(S){let{limit:M=50,offset:f=0,type:$,sessionId:A,state:O}=S;if(O)return this.listByProjectWithState({limit:M,offset:f,type:$,state:O,sessionId:A});if(A){let V=this.observations.getBySession(A);if($)V=V.filter((E)=>E.type===$);return V.slice(f,f+M)}let N=this.observations.getIndex(this.projectPath,f+M).slice(f);if($)N=N.filter((V)=>V.type===$);return N.map((V)=>this.observations.getById(V.id)).filter((V)=>V!==null)}getObservation(S){return this.observations.getById(S)}getLineage(S){let f=this.getByIdIncludingArchived(S);if(!f)return null;let $=f,A=0,O=new Set([f.id]);while($.revisionOf&&A<256){let J=this.getByIdIncludingArchived($.revisionOf);if(!J||O.has(J.id))break;$=J,O.add(J.id),A+=1}let y=[],N=$,V=new Set,E=0;while(N&&!V.has(N.id)&&E<256){V.add(N.id);let J=N.deletedAt?"tombstoned":N.supersededBy?"superseded":"current";y.push({id:N.id,revisionOf:N.revisionOf??null,supersededBy:N.supersededBy??null,supersededAt:N.supersededAt??null,deletedAt:N.deletedAt??null,state:J,observation:N}),N=N.supersededBy?this.getByIdIncludingArchived(N.supersededBy):null,E+=1}return y}listSessions(S){return this.sessions.getRecent(S.projectPath??this.projectPath,S.limit??20)}getSession(S){let M=this.sessions.getById(S);if(!M)return null;return{session:M,summary:this.summaries.getBySessionId(S),observations:this.observations.getBySession(S)}}stats(){let S=this.observations.getCount(),f=this.sessions.getAll(this.projectPath).length,$=this.observations.getIndex(this.projectPath,1e4),A=0,O=0,y={};for(let E of $)A+=E.tokenCount,O+=E.discoveryTokens,y[E.type]=(y[E.type]||0)+1;let N=O-A,V=$.length>0?Math.round(A/$.length):0;return{totalObservations:S,totalSessions:f,totalTokensSaved:N,averageObservationSize:V,typeBreakdown:y}}async maintainFolderContext(S,M){if(S==="purge")return{action:"purge",dryRun:!1,...await wM(this.projectPath,this.config.folderContextFilename)};if(S==="rebuild"){let $=await gM(this.projectPath,this.sessions,this.observations,{maxDepth:this.config.folderContextMaxDepth,mode:this.config.folderContextMode,filename:this.config.folderContextFilename},M);return{action:S,dryRun:M,...$}}let f=await IM(this.projectPath,this.config.folderContextFilename,M);return{action:"clean",dryRun:M,...f}}getRevisionDiff(S,M){let f=this.getByIdIncludingArchived(S),$=this.getByIdIncludingArchived(M);if(!f||!$)return null;let A=[],O=(N,V,E)=>{if(JSON.stringify(V)!==JSON.stringify(E))A.push({field:N,before:V,after:E})};O("title",$.title,f.title),O("subtitle",$.subtitle,f.subtitle),O("narrative",$.narrative,f.narrative),O("type",$.type,f.type),O("facts",$.facts,f.facts),O("concepts",$.concepts,f.concepts),O("filesRead",$.filesRead,f.filesRead),O("filesModified",$.filesModified,f.filesModified),O("importance",$.importance,f.importance);let y=A.length===0?"No material changes between revisions.":`Changed ${A.length} field${A.length===1?"":"s"}: ${A.map((N)=>N.field).join(", ")}.`;return{fromId:M,toId:S,summary:y,changedFields:A}}getHealth(){let S=this.runtimeSnapshotProvider?.(),M=S?.queue.lastError?"degraded":"ok";return{status:S?.status??"ok",timestamp:S?.timestamp??new Date().toISOString(),components:{database:{status:"ok"},search:{status:"ok"},config:{status:"ok"},queue:{status:M,detail:S?.queue.lastError??void 0}}}}getMetrics(){let S=this.stats();return{timestamp:this.runtimeSnapshotProvider?.()?.timestamp??new Date().toISOString(),memory:{totalObservations:S.totalObservations,totalSessions:S.totalSessions,totalTokensSaved:S.totalTokensSaved,averageObservationSize:S.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 S={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((f)=>({name:f.name,version:f.version,enabled:S[f.name]??!1,capabilities:f.capabilities}))}getConfigAuditTimeline(){if(this.configAuditStore)return this.configAuditStore.list();return[...this.configAuditLogFallback].reverse()}trackConfigAudit(S){if(this.configAuditStore){this.configAuditStore.append(S);return}this.configAuditLogFallback.push(S)}async rollbackConfig(S){let M=this.configAuditStore?this.configAuditStore.getById(S):this.configAuditLogFallback.find((O)=>O.id===S)??null;if(!M)return null;if(!M.previousValues||typeof M.previousValues!=="object")return null;let{patchConfig:f}=await Promise.resolve().then(() => (TS(),fM)),$=M.previousValues;try{await f(this.projectPath,$)}catch(O){let y={id:`rollback-failed-${mM()}`,timestamp:new Date().toISOString(),patch:M.previousValues,previousValues:M.patch,source:"rollback-failed"};throw this.trackConfigAudit(y),O}let A={id:`rollback-${mM()}`,timestamp:new Date().toISOString(),patch:M.previousValues,previousValues:M.patch,source:"rollback"};return this.trackConfigAudit(A),A}getMaintenanceHistory(){if(this.maintenanceHistoryStore)return this.maintenanceHistoryStore.list();return[...this.maintenanceLogFallback].reverse()}trackMaintenanceResult(S){if(this.maintenanceHistoryStore){this.maintenanceHistoryStore.append(S);return}this.maintenanceLogFallback.push(S)}}import{existsSync as Z$}from"fs";import{existsSync as J$}from"fs";import{homedir as Q$}from"os";import{join as hM}from"path";function _$(){let S=[],M=process.env.BUN_INSTALL;if(M)S.push(hM(M,"bin","bun"));let f=Q$();return S.push(hM(f,".bun","bin","bun")),S.push("/usr/local/bin/bun"),S.push("/opt/homebrew/bin/bun"),S.push("/home/linuxbrew/.linuxbrew/bin/bun"),S}function B$(){let S=Bun.which("bun");if(S)return S;for(let M of _$())if(J$(M))return console.debug(`[open-mem] Resolved bun path via candidate scan: ${M}`),M;return"bun"}var oS=null;function qM(){if(oS===null)oS=B$();return oS}import{existsSync as W$,mkdirSync as nE,readFileSync as X$,unlinkSync as R$,writeFileSync as rE}from"fs";function a(S){if(!W$(S))return null;let M=X$(S,"utf-8").trim(),f=Number.parseInt(M,10);if(Number.isNaN(f))return null;return f}function y0(S){try{return process.kill(S,0),!0}catch(M){if(M instanceof Error&&"code"in M&&M.code==="EPERM")return!0;return!1}}function D0(S){try{R$(S)}catch{}}function e0(S){let M=S.lastIndexOf("/");if(M>=0)return`${S.substring(0,M)}/worker.pid`;return"worker.pid"}var K$=100,Y$=2000;class S1{pidPath;projectPath;daemonScript;subprocess=null;constructor(S){this.pidPath=e0(S.dbPath),this.projectPath=S.projectPath,this.daemonScript=S.daemonScript}start(){if(this.isRunning())return!1;this.subprocess=Bun.spawn([qM(),"run",this.daemonScript,"--project",this.projectPath],{detached:!0,stdio:["ignore","ignore","ignore"],ipc(M){}}),this.subprocess.unref();let S=Date.now()+Y$;while(Date.now()<S)if(Bun.sleepSync(K$),Z$(this.pidPath)){let M=a(this.pidPath);if(M!==null&&y0(M))return!0}return!1}signal(S){try{this.subprocess?.send(S)}catch{}}stop(){let S=a(this.pidPath);if(S!==null)try{process.kill(S,"SIGTERM")}catch{}this.subprocess=null,D0(this.pidPath)}isRunning(){let S=a(this.pidPath);if(S===null)return!1;return y0(S)}getStatus(){let S=a(this.pidPath);if(S===null)return{running:!1,pid:null};if(!y0(S))return{running:!1,pid:null};return{running:!0,pid:S}}}import{existsSync as M1}from"fs";function PM(S){let M={reaped:0,errors:[]};try{let f=e0(S),$=a(f);if($===null){try{if(M1(f))if(D0(f),!M1(f))M.reaped++,console.log("[open-mem] Reaped corrupt daemon PID file");else M.errors.push("Failed to remove corrupt PID file: file still exists after removal")}catch(A){M.errors.push(`Failed to check/remove corrupt PID file: ${A instanceof Error?A.message:String(A)}`)}return M}if(y0($))return M;if(D0(f),!M1(f))M.reaped++,console.log(`[open-mem] Reaped stale daemon PID file (pid=${$})`);else M.errors.push(`Failed to remove stale PID file (pid=${$}): file still exists after removal`)}catch(f){M.errors.push(`Reaper error: ${f instanceof Error?f.message:String(f)}`)}return M}function o0(S){try{let M=JSON.parse(S);return M&&typeof M==="object"?M:{}}catch{return{}}}class f1{db;constructor(S){this.db=S}list(){return this.db.all("SELECT id, timestamp, patch, previous_values, source FROM config_audit_events ORDER BY timestamp DESC").map((S)=>({id:S.id,timestamp:S.timestamp,patch:o0(S.patch),previousValues:o0(S.previous_values),source:S.source}))}getById(S){let M=this.db.get("SELECT id, timestamp, patch, previous_values, source FROM config_audit_events WHERE id = ?",[S]);if(!M)return null;return{id:M.id,timestamp:M.timestamp,patch:o0(M.patch),previousValues:o0(M.previous_values),source:M.source}}append(S){this.db.run("INSERT INTO config_audit_events (id, timestamp, patch, previous_values, source) VALUES (?, ?, ?, ?, ?)",[S.id,S.timestamp,JSON.stringify(S.patch??{}),JSON.stringify(S.previousValues??{}),S.source])}}import{Database as vM}from"bun:sqlite";import{existsSync as $1,mkdirSync as z$,unlinkSync as lM}from"fs";import*as cM from"sqlite-vec";class SS{db;dbPath;_hasVectorExtension=!1;static enableExtensionSupport(){let S=["/opt/homebrew/opt/sqlite/lib/libsqlite3.dylib","/usr/local/opt/sqlite/lib/libsqlite3.dylib"];for(let M of S)try{if($1(M))return vM.setCustomSQLite(M),!0}catch{return!1}return!1}constructor(S){this.dbPath=S,this.db=this.open(S),this.configure()}open(S){let M=S.lastIndexOf("/");if(M>0){let f=S.substring(0,M);z$(f,{recursive:!0})}return new vM(S,{create:!0})}configure(){try{this.applyPragmas(),this.loadExtensions()}catch(S){console.warn("[open-mem] Database configure failed, attempting recovery by removing WAL/SHM files:",S.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(f){throw console.warn("[open-mem] All recovery attempts failed, filesystem may be broken:",f.message),S}}}}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{cM.load(this.db),this._hasVectorExtension=!0}catch{this._hasVectorExtension=!1}}get hasVectorExtension(){return this._hasVectorExtension}deleteSidecarFiles(){for(let S of["-wal","-shm"]){let M=this.dbPath+S;try{if($1(M))lM(M)}catch{}}}deleteDatabaseFiles(){this.deleteSidecarFiles();try{if($1(this.dbPath))lM(this.dbPath)}catch{}}ensureMigrationTable(){this.db.exec(`
|
|
181
|
+
`}function u2(S,M,$){let f=new Set,O=V0(M);for(let A of S){if(!A||!A.trim())continue;if(A.startsWith("~")||A.startsWith("http"))continue;let V=i1(A)?A:D0(M,A),y=a0(V),J=V0(y);if(!J.startsWith(O+n1)&&J!==O)continue;if(J===O)continue;let N=t1(O,J);if(N.split(n1).length>$)continue;if(_f(N).split(n1).some((E)=>Yf.has(E)))continue;if(!T2(J))continue;f.add(J)}return f}function w2(S,M,$){let f=new Map;for(let O of S){let A=[...O.filesModified,...O.filesRead],V=new Set;for(let y of A){if(!y)continue;let J=i1(y)?y:D0($,y),N=V0(a0(J));if(M.has(N))V.add(N)}for(let y of V){let J=f.get(y)??[];J.push(O),f.set(y,J)}}return f}var d1="<!-- open-mem-context -->",e0="<!-- /open-mem-context -->";async function v2(S,M,$){let f;try{f=await Df(S,{withFileTypes:!0,encoding:"utf8"})}catch{return}for(let O of f){let A=String(O.name);if(A===".git"||A==="node_modules"||A===".open-mem"||A==="dist")continue;let V=o1(S,A);if(O.isDirectory())await v2(V,M,$);else if(O.isFile()&&A===M)$.push(V)}}async function SS(S,M){let $=e1(S),f=[];return await v2($,M,f),f}function g2(S){let M=S.indexOf(d1),$=S.indexOf(e0);if(M===-1&&$===-1)return S;if(M!==-1&&$===-1){let A=S.replace(d1,"").trim();return A?`${A}
|
|
182
|
+
`:""}if(M===-1&&$!==-1){let A=S.replace(e0,"").trim();return A?`${A}
|
|
183
|
+
`:""}if($<=M){let A=S.replace(d1,"").replace(e0,"").trim();return A?`${A}
|
|
184
|
+
`:""}let f=S.slice(0,M).trimEnd(),O=S.slice($+e0.length).trimStart();if(!f&&!O)return"";if(!f)return`${O}
|
|
185
|
+
`;if(!O)return`${f}
|
|
186
|
+
`;return`${f}
|
|
187
|
+
|
|
188
|
+
${O}
|
|
189
|
+
`}async function h2(S,M,$=!1){let f=await SS(S,M),O=0;for(let A of f){let V=await k2(A,"utf-8"),y=g2(V);if(y!==V){if(O+=1,!$)if(y==="")await s1(A);else await q2(A,y,"utf-8")}}if(M){let A=o1(e1(S),M);if(a1(A))try{let V=await k2(A,"utf-8"),y=g2(V);if(y!==V){if(O+=1,!$)if(y==="")await s1(A);else await q2(A,y,"utf-8")}if(!f.includes(A))f.push(A)}catch{}}return{files:f,changed:O}}async function P2(S,M){let $=await SS(S,M);if(M){let O=o1(e1(S),M);if(a1(O)&&!$.includes(O))$.push(O)}let f=0;for(let O of $)try{await s1(O),f++}catch{}return{deleted:f,files:$}}async function m2(S,M,$,f,O=!1){let V=M.getAll(S).flatMap((J)=>$.getBySession(J.id));if(O){let J=new Set;for(let N of V)for(let X of[...N.filesRead,...N.filesModified])J.add(X);return{observations:V.length,filesTouched:J.size}}if(!a1(S))return{observations:0,filesTouched:0};await o0(S,V,{maxDepth:f.maxDepth,mode:f.mode,filename:f.filename});let y=await SS(S,f.filename);return{observations:V.length,filesTouched:y.length}}class MS{observations;sessions;summaries;searchOrchestrator;projectPath;config;userObservationRepo;runtimeSnapshotProvider;configAuditStore;maintenanceHistoryStore;configAuditLogFallback=[];maintenanceLogFallback=[];constructor(S){this.observations=S.observations,this.sessions=S.sessions,this.summaries=S.summaries,this.searchOrchestrator=S.searchOrchestrator,this.projectPath=S.projectPath,this.config=S.config,this.userObservationRepo=S.userObservationRepo??null,this.runtimeSnapshotProvider=S.runtimeSnapshotProvider??null,this.configAuditStore=S.configAuditStore??null,this.maintenanceHistoryStore=S.maintenanceHistoryStore??null}getByIdIncludingArchived(S){let M=this.observations;return M.getByIdIncludingArchived?M.getByIdIncludingArchived(S):this.observations.getById(S)}listByProjectWithState(S){let M=this.observations;if(M.listByProject)return M.listByProject(this.projectPath,S);if(S.state!=="current")return[];return this.listObservations({limit:S.limit,offset:S.offset,type:S.type,sessionId:S.sessionId})}async ingest(S){}async processPending(S){return 0}async search(S,M={}){return this.searchOrchestrator.search(S,{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(S={}){if(S.anchor){let $=this.observations.getById(S.anchor);if(!$)return[];let f=S.depthBefore??5,O=S.depthAfter??5,A=this.observations.getAroundTimestamp($.createdAt,f,O,this.projectPath),V=[...A.filter((J)=>J.createdAt<$.createdAt),$,...A.filter((J)=>J.createdAt>$.createdAt)];return[{session:this.sessions.getById($.sessionId)??{id:$.sessionId,projectPath:this.projectPath,startedAt:$.createdAt,endedAt:null,status:"completed",observationCount:0,summaryId:null},summary:null,observations:V}]}if(S.sessionId){let $=this.sessions.getById(S.sessionId);if(!$)return[];return[{session:$,summary:this.summaries.getBySessionId($.id),observations:this.observations.getBySession($.id)}]}return this.sessions.getRecent(this.projectPath,S.limit??5).map(($)=>({session:$,summary:this.summaries.getBySessionId($.id),observations:[]}))}async recall(S,M=10){let $=[];for(let f of S.slice(0,M)){let O=this.observations.getById(f);if(O){$.push(O);continue}if(!this.userObservationRepo)continue;let A=this.userObservationRepo.getById(f);if(!A)continue;$.push({...A,sessionId:"",rawToolOutput:"",discoveryTokens:0})}return $}async save(S){if(S.scope==="user"){if(!this.userObservationRepo)return null;return{...this.userObservationRepo.create({type:S.type,title:S.title,subtitle:"",facts:[],narrative:S.narrative,concepts:S.concepts??[],filesRead:[],filesModified:S.files??[],toolName:"mem-create",tokenCount:j(`${S.title} ${S.narrative}`),importance:S.importance??3,sourceProject:this.projectPath}),sessionId:"",rawToolOutput:"",discoveryTokens:0}}this.sessions.getOrCreate(S.sessionId,this.projectPath);let M=this.observations.create({sessionId:S.sessionId,type:S.type,title:S.title,subtitle:"",facts:[],narrative:S.narrative,concepts:S.concepts??[],filesRead:[],filesModified:S.files??[],rawToolOutput:`[Manual save] ${S.narrative}`,toolName:"mem-create",tokenCount:j(`${S.title} ${S.narrative}`),discoveryTokens:0,importance:S.importance??3});return this.sessions.incrementObservationCount(S.sessionId),M}async update(S){let M=this.observations.getById(S.id);if(!M)return null;let $=this.sessions.getById(M.sessionId);if(!$||$.projectPath!==this.projectPath)return null;let{id:f,...O}=S;return this.observations.update(S.id,O)??null}async delete(S){let M=0;for(let $ of S){let f=this.observations.getById($);if(!f)continue;let O=this.sessions.getById(f.sessionId);if(!O||O.projectPath!==this.projectPath)continue;if(this.observations.delete($))M+=1}return M}async export(S,M={}){if(S!=="project")throw Error("Only project scope export is supported.");let $=this.sessions.getAll(this.projectPath),f=[];for(let y of $)f.push(...this.observations.getBySession(y.id));if(M.type)f=f.filter((y)=>y.type===M.type);if(f.sort((y,J)=>new Date(y.createdAt).getTime()-new Date(J.createdAt).getTime()),M.limit&&M.limit<f.length)f=f.slice(0,M.limit);let O=f.map(({rawToolOutput:y,...J})=>J),A=$.map((y)=>this.summaries.getBySessionId(y.id)).filter((y)=>y!==null);return{version:1,exportedAt:new Date().toISOString(),project:this.projectPath,observations:O,summaries:A}}async import(S,M={}){let $;try{$=JSON.parse(S)}catch{throw Error("Invalid JSON payload.")}if(typeof $!=="object"||$===null)throw Error("Invalid import payload.");let f=$;if(f.version!==1||!Array.isArray(f.observations))throw Error("Unsupported export format.");let O=M.mode??"skip-duplicates",A=0,V=0;for(let y of f.observations){let J=this.observations.getById(y.id);if(J&&O==="skip-duplicates"){V+=1;continue}if(J&&O==="overwrite")this.observations.delete(y.id);this.sessions.getOrCreate(y.sessionId,this.projectPath),this.observations.importObservation({id:y.id,sessionId:y.sessionId,type:y.type,title:y.title,subtitle:y.subtitle??"",facts:y.facts??[],narrative:y.narrative??"",concepts:y.concepts??[],filesRead:y.filesRead??[],filesModified:y.filesModified??[],rawToolOutput:y.rawToolOutput??"",toolName:y.toolName??"unknown",createdAt:y.createdAt,tokenCount:y.tokenCount??0,discoveryTokens:y.discoveryTokens??0,importance:y.importance??3,supersededBy:y.supersededBy??null,supersededAt:y.supersededAt??null}),this.sessions.incrementObservationCount(y.sessionId),A+=1}for(let y of f.summaries??[]){let J=this.summaries.getBySessionId(y.sessionId);if(J&&O==="skip-duplicates")continue;if(J&&O==="overwrite")continue;this.sessions.getOrCreate(y.sessionId,this.projectPath),this.summaries.importSummary(y),this.sessions.setSummary(y.sessionId,y.id)}return{imported:A,skipped:V}}async buildContext(S,M="normal"){let $=this.sessions.getRecent(this.projectPath,5),f=$.map((X)=>X.summaryId?this.summaries.getBySessionId(X.id):null).filter((X)=>X!==null),O=this.observations.getIndex(this.projectPath,this.config.maxObservations),V=O.slice(0,this.config.contextFullObservationCount).map((X)=>X.id).map((X)=>this.observations.getById(X)).filter((X)=>X!==null),y=O0($,f,O,this.config.maxContextTokens,V);if(M==="compaction"){let X=i0(y);if(this.config.userMemoryEnabled&&this.userObservationRepo)X+=d0(this.userObservationRepo.getIndex(this.config.maxObservations),this.config.userMemoryMaxContextTokens);return X}let J={showTokenCosts:this.config.contextShowTokenCosts,observationTypes:this.config.contextObservationTypes,fullObservationCount:this.config.contextFullObservationCount,showLastSummary:this.config.contextShowLastSummary},N=r0(y,J);if(this.config.userMemoryEnabled&&this.userObservationRepo){let X=t0(this.userObservationRepo.getIndex(this.config.maxObservations),this.config.userMemoryMaxContextTokens);if(X)N+=`
|
|
190
|
+
|
|
191
|
+
${X}`}return N}guide(){return["# open-mem Workflow Guide","","## Reading Memories","1. `mem-find` \u2014 Search by query (returns IDs + summaries)","2. `mem-history` \u2014 Browse session timeline and summaries","3. `mem-get` \u2014 Fetch full details by ID (from find/history results)","","## When to Save (`mem-create`)","Save when the information is **stable, reusable, and non-obvious**:",'- Architectural decisions + rationale ("chose X over Y because...")',"- Non-obvious gotchas or workarounds discovered","- User preferences and conventions","- Cross-session plans or migration progress",'- Environment constraints ("Bedrock requires tool names matching [a-zA-Z0-9_-]+")',"","## When NOT to Save","Auto-capture already handles tool executions. Don't manually save:","- Ephemeral logs or one-off command outputs","- Information already visible in code or config files","- Routine file reads or edits (auto-captured)","","## Memory Types","- `decision` \u2014 Architectural choices with rationale","- `discovery` \u2014 Non-obvious findings, gotchas, constraints","- `bugfix` \u2014 Bug root causes and fixes","- `feature` \u2014 Feature implementations and design notes","- `refactor` \u2014 Refactoring rationale and approach","- `change` \u2014 General changes worth remembering","","## Editing & Cleanup","- `mem-revise` \u2014 Update outdated memories with new revisions","- `mem-remove` \u2014 Tombstone obsolete or incorrect memories","","## Privacy","Wrap sensitive content in `<private>` tags to exclude from memory.","","## Transfer","- `mem-export` \u2014 Backup/portability as JSON","- `mem-import` \u2014 Restore from JSON export"].join(`
|
|
192
|
+
`)}listObservations(S){let{limit:M=50,offset:$=0,type:f,sessionId:O,state:A}=S;if(A)return this.listByProjectWithState({limit:M,offset:$,type:f,state:A,sessionId:O});if(O){let J=this.observations.getBySession(O);if(f)J=J.filter((N)=>N.type===f);return J.slice($,$+M)}let y=this.observations.getIndex(this.projectPath,$+M).slice($);if(f)y=y.filter((J)=>J.type===f);return y.map((J)=>this.observations.getById(J.id)).filter((J)=>J!==null)}getObservation(S){return this.observations.getById(S)}getLineage(S){let $=this.getByIdIncludingArchived(S);if(!$)return null;let f=$,O=0,A=new Set([$.id]);while(f.revisionOf&&O<256){let X=this.getByIdIncludingArchived(f.revisionOf);if(!X||A.has(X.id))break;f=X,A.add(X.id),O+=1}let V=[],y=f,J=new Set,N=0;while(y&&!J.has(y.id)&&N<256){J.add(y.id);let X=y.deletedAt?"tombstoned":y.supersededBy?"superseded":"current";V.push({id:y.id,revisionOf:y.revisionOf??null,supersededBy:y.supersededBy??null,supersededAt:y.supersededAt??null,deletedAt:y.deletedAt??null,state:X,observation:y}),y=y.supersededBy?this.getByIdIncludingArchived(y.supersededBy):null,N+=1}return V}listSessions(S){return this.sessions.getRecent(S.projectPath??this.projectPath,S.limit??20)}getSession(S){let M=this.sessions.getById(S);if(!M)return null;return{session:M,summary:this.summaries.getBySessionId(S),observations:this.observations.getBySession(S)}}stats(){let S=this.observations.getCount(),$=this.sessions.getAll(this.projectPath).length,f=this.observations.getIndex(this.projectPath,1e4),O=0,A=0,V={};for(let N of f)O+=N.tokenCount,A+=N.discoveryTokens,V[N.type]=(V[N.type]||0)+1;let y=A-O,J=f.length>0?Math.round(O/f.length):0;return{totalObservations:S,totalSessions:$,totalTokensSaved:y,averageObservationSize:J,typeBreakdown:V}}async maintainFolderContext(S,M){if(S==="purge")return{action:"purge",dryRun:!1,...await P2(this.projectPath,this.config.folderContextFilename)};if(S==="rebuild"){let f=await m2(this.projectPath,this.sessions,this.observations,{maxDepth:this.config.folderContextMaxDepth,mode:this.config.folderContextMode,filename:this.config.folderContextFilename},M);return{action:S,dryRun:M,...f}}let $=await h2(this.projectPath,this.config.folderContextFilename,M);return{action:"clean",dryRun:M,...$}}getRevisionDiff(S,M){let $=this.getByIdIncludingArchived(S),f=this.getByIdIncludingArchived(M);if(!$||!f)return null;let O=[],A=(y,J,N)=>{if(JSON.stringify(J)!==JSON.stringify(N))O.push({field:y,before:J,after:N})};A("title",f.title,$.title),A("subtitle",f.subtitle,$.subtitle),A("narrative",f.narrative,$.narrative),A("type",f.type,$.type),A("facts",f.facts,$.facts),A("concepts",f.concepts,$.concepts),A("filesRead",f.filesRead,$.filesRead),A("filesModified",f.filesModified,$.filesModified),A("importance",f.importance,$.importance);let V=O.length===0?"No material changes between revisions.":`Changed ${O.length} field${O.length===1?"":"s"}: ${O.map((y)=>y.field).join(", ")}.`;return{fromId:M,toId:S,summary:V,changedFields:O}}getHealth(){let S=this.runtimeSnapshotProvider?.(),M=S?.queue.lastError?"degraded":"ok";return{status:S?.status??"ok",timestamp:S?.timestamp??new Date().toISOString(),components:{database:{status:"ok"},search:{status:"ok"},config:{status:"ok"},queue:{status:M,detail:S?.queue.lastError??void 0}}}}getMetrics(){let S=this.stats();return{timestamp:this.runtimeSnapshotProvider?.()?.timestamp??new Date().toISOString(),memory:{totalObservations:S.totalObservations,totalSessions:S.totalSessions,totalTokensSaved:S.totalTokensSaved,averageObservationSize:S.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 S={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(($)=>({name:$.name,version:$.version,enabled:S[$.name]??!1,capabilities:$.capabilities}))}getConfigAuditTimeline(){if(this.configAuditStore)return this.configAuditStore.list();return[...this.configAuditLogFallback].reverse()}trackConfigAudit(S){if(this.configAuditStore){this.configAuditStore.append(S);return}this.configAuditLogFallback.push(S)}async rollbackConfig(S){let M=this.configAuditStore?this.configAuditStore.getById(S):this.configAuditLogFallback.find((A)=>A.id===S)??null;if(!M)return null;if(!M.previousValues||typeof M.previousValues!=="object")return null;let{patchConfig:$}=await Promise.resolve().then(() => (I1(),N2)),f=M.previousValues;try{await $(this.projectPath,f)}catch(A){let V={id:`rollback-failed-${b2()}`,timestamp:new Date().toISOString(),patch:M.previousValues,previousValues:M.patch,source:"rollback-failed"};throw this.trackConfigAudit(V),A}let O={id:`rollback-${b2()}`,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(S){if(this.maintenanceHistoryStore){this.maintenanceHistoryStore.append(S);return}this.maintenanceLogFallback.push(S)}}import{existsSync as xf}from"fs";import{existsSync as Gf}from"fs";import{homedir as Hf}from"os";import{join as c2}from"path";function Lf(){let S=[],M=process.env.BUN_INSTALL;if(M)S.push(c2(M,"bin","bun"));let $=Hf();return S.push(c2($,".bun","bin","bun")),S.push("/usr/local/bin/bun"),S.push("/opt/homebrew/bin/bun"),S.push("/home/linuxbrew/.linuxbrew/bin/bun"),S}function Cf(){let S=Bun.which("bun");if(S)return S;for(let M of Lf())if(Gf(M))return console.debug(`[open-mem] Resolved bun path via candidate scan: ${M}`),M;return"bun"}var $S=null;function l2(){if($S===null)$S=Cf();return $S}import{existsSync as Ff,mkdirSync as j5,readFileSync as jf,unlinkSync as p2,writeFileSync as T5}from"fs";function a(S){if(!Ff(S))return null;let M=jf(S,"utf-8").trim(),$=Number.parseInt(M,10);if(Number.isNaN($))return null;return $}function o(S){try{return process.kill(S,0),!0}catch(M){if(M instanceof Error&&"code"in M&&M.code==="EPERM")return!0;return!1}}function n2(S,M){let $=a(S);if($===null)return{state:"missing",pid:null,stalePid:null,stalePidRemoved:!1};if(o($))return{state:"alive",pid:$,stalePid:null,stalePidRemoved:!1};if(!M)return{state:"dead",pid:null,stalePid:$,stalePidRemoved:!1};let f=Tf(S,$);return{state:"dead",pid:null,stalePid:$,stalePidRemoved:f}}function G0(S){try{p2(S)}catch{}}function Tf(S,M){let $=a(S);if($===null||$!==M)return!1;try{return p2(S),!0}catch{return!1}}function S1(S){let M=S.lastIndexOf("/");if(M>=0)return`${S.substring(0,M)}/worker.pid`;return"worker.pid"}var If=100,uf=2000;class fS{pidPath;projectPath;daemonScript;subprocess=null;constructor(S){this.pidPath=S1(S.dbPath),this.projectPath=S.projectPath,this.daemonScript=S.daemonScript}start(){if(this.isRunning())return!1;this.subprocess=Bun.spawn([l2(),"run",this.daemonScript,"--project",this.projectPath],{detached:!0,stdio:["ignore","ignore","ignore"],ipc(M){}}),this.subprocess.unref();let S=Date.now()+uf;while(Date.now()<S)if(Bun.sleepSync(If),xf(this.pidPath)){let M=a(this.pidPath);if(M!==null&&o(M))return!0}return!1}signal(S){let M=()=>{try{return this.getStatus()}catch{return null}};try{if(this.subprocess)return this.subprocess.send(S),{ok:!0,state:"delivered",via:"ipc",pid:M()?.pid??null,message:S};if(S!=="PROCESS_NOW")return{ok:!1,state:"unsupported-signal",via:"none",pid:null,message:S};let $=this.getStatus();if($.state==="missing")return{ok:!1,state:"no-daemon",via:"none",pid:null,message:S};if($.state==="dead")return{ok:!1,state:"daemon-dead",via:"none",pid:$.stalePid,message:S};if($.pid!==null)return process.kill($.pid,"SIGUSR1"),{ok:!0,state:"delivered",via:"os-signal",pid:$.pid,message:S};return{ok:!1,state:"delivery-failed",via:"none",pid:null,message:S,error:"Daemon was reported running but did not expose a PID"}}catch($){return{ok:!1,state:"delivery-failed",via:"none",pid:M()?.pid??null,message:S,error:String($)}}}stop(){let S=a(this.pidPath);if(S!==null)try{process.kill(S,"SIGTERM")}catch{}this.subprocess=null,G0(this.pidPath)}isRunning(){return this.getStatus().running}getStatus(){return wf(this.pidPath,!0)}}function wf(S,M){let $=n2(S,M);if($.state==="missing")return{state:"missing",running:!1,pid:null,stalePid:null,stalePidRemoved:!1};if($.state==="dead")return{state:"dead",running:!1,pid:null,stalePid:$.stalePid,stalePidRemoved:$.stalePidRemoved};return{state:"running",running:!0,pid:$.pid,stalePid:null,stalePidRemoved:!1}}import{existsSync as OS}from"fs";function r2(S){let M={reaped:0,errors:[]};try{let $=S1(S),f=a($);if(f===null){try{if(OS($))if(G0($),!OS($))M.reaped++,console.log("[open-mem] Reaped corrupt daemon PID file");else M.errors.push("Failed to remove corrupt PID file: file still exists after removal")}catch(O){M.errors.push(`Failed to check/remove corrupt PID file: ${O instanceof Error?O.message:String(O)}`)}return M}if(o(f))return M;if(G0($),!OS($))M.reaped++,console.log(`[open-mem] Reaped stale daemon PID file (pid=${f})`);else M.errors.push(`Failed to remove stale PID file (pid=${f}): file still exists after removal`)}catch($){M.errors.push(`Reaper error: ${$ instanceof Error?$.message:String($)}`)}return M}function M1(S){try{let M=JSON.parse(S);return M&&typeof M==="object"?M:{}}catch{return{}}}class AS{db;constructor(S){this.db=S}list(){return this.db.all("SELECT id, timestamp, patch, previous_values, source FROM config_audit_events ORDER BY timestamp DESC").map((S)=>({id:S.id,timestamp:S.timestamp,patch:M1(S.patch),previousValues:M1(S.previous_values),source:S.source}))}getById(S){let M=this.db.get("SELECT id, timestamp, patch, previous_values, source FROM config_audit_events WHERE id = ?",[S]);if(!M)return null;return{id:M.id,timestamp:M.timestamp,patch:M1(M.patch),previousValues:M1(M.previous_values),source:M.source}}append(S){this.db.run("INSERT INTO config_audit_events (id, timestamp, patch, previous_values, source) VALUES (?, ?, ?, ?, ?)",[S.id,S.timestamp,JSON.stringify(S.patch??{}),JSON.stringify(S.previousValues??{}),S.source])}}import{Database as SM}from"bun:sqlite";import{existsSync as nf,mkdirSync as rf}from"fs";import*as $M from"sqlite-vec";import{closeSync as kf,fsyncSync as qf,openSync as gf,readFileSync as vf,unlinkSync as t2,writeFileSync as hf}from"fs";import{hostname as d2}from"os";var s2="plugin";class $1 extends Error{lockPath;role;waitDurationMs;owner;constructor(S){super(`Timed out acquiring advisory write lock after ${S.waitDurationMs}ms (role=${S.role}, lockPath=${S.lockPath})`);this.name="AdvisoryLockTimeoutError",this.lockPath=S.lockPath,this.role=S.role,this.waitDurationMs=S.waitDurationMs,this.owner=S.owner}}var Pf=5000,mf=50,N0=new Map;function bf(S){if(S<=0)return;Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,S)}function i2(S,M){if(typeof S!=="number"||!Number.isFinite(S)||S<=0)return M;return Math.floor(S)}function a2(S){try{let M=vf(S,"utf8").trim();if(!M)return null;let $=JSON.parse(M);if(typeof $!=="object"||$===null||typeof $.pid!=="number"||typeof $.role!=="string"||typeof $.hostname!=="string"||typeof $.acquiredAt!=="string")return null;return{pid:$.pid,role:$.role,hostname:$.hostname,acquiredAt:$.acquiredAt,ownerId:typeof $.ownerId==="string"?$.ownerId:void 0}}catch{return null}}function cf(S,M){if(!S||!M)return!1;return S.pid===M.pid&&S.role===M.role&&S.hostname===M.hostname&&S.acquiredAt===M.acquiredAt&&S.ownerId===M.ownerId}function lf(S,M){if(!M)return!1;if(M.hostname!==d2())return!1;if(o(M.pid))return!1;let $=a2(S);if(!cf($,M))return!1;try{return t2(S),!0}catch(f){if(f.code==="ENOENT")return!1;throw f}}function VS(S,M){kf(M);try{t2(S)}catch($){if($.code!=="ENOENT")throw $}}function o2(S){return`${S}.write.lock`}function pf(S,M){let $=M.now??Date.now,f=i2(M.timeoutMs,Pf),O=i2(M.retryIntervalMs,mf),A=N0.get(S);if(A){A.count+=1;let N=!1;return{lockPath:S,role:M.role,waitDurationMs:0,reentrant:!0,release:()=>{if(N)return;N=!0;let X=N0.get(S);if(!X)return;if(X.count-=1,X.count===0)N0.delete(S),VS(S,X.fd)}}}let V={pid:process.pid,role:M.role,hostname:d2(),acquiredAt:new Date($()).toISOString(),ownerId:M.ownerId},y=$(),J=null;for(;;)try{let N=gf(S,"wx");try{hf(N,JSON.stringify(V),"utf8"),qf(N)}catch(Z){throw VS(S,N),Z}N0.set(S,{count:1,fd:N});let X=!1;return{lockPath:S,role:M.role,waitDurationMs:$()-y,reentrant:!1,release:()=>{if(X)return;X=!0;let Z=N0.get(S);if(!Z)return;if(Z.count-=1,Z.count===0)N0.delete(S),VS(S,Z.fd)}}}catch(N){if(N.code!=="EEXIST")throw N;if(J=a2(S),lf(S,J))continue;let Z=$()-y;if(Z>=f)throw new $1({lockPath:S,role:M.role,waitDurationMs:Z,owner:J});bf(Math.min(O,f-Z))}}function e2(S,M,$){let f=pf(S,M);try{return $()}finally{f.release()}}var tf=new Set(["SQLITE_BUSY","SQLITE_LOCKED","SQLITE_IOERR","SQLITE_IOERR_VNODE","SQLITE_IOERR_READ","SQLITE_IOERR_WRITE","SQLITE_IOERR_SHORT_READ","SQLITE_IOERR_FSYNC","SQLITE_PROTOCOL"]),df=3,MM=50,sf=new Set(["INSERT","UPDATE","DELETE","REPLACE","CREATE","ALTER","DROP","VACUUM","REINDEX","ANALYZE","ATTACH","DETACH"]),af=new Set(["WAL_CHECKPOINT","OPTIMIZE","INCREMENTAL_VACUUM","SHRINK_MEMORY"]),of=/^(?:\s+|--[^\n]*(?:\n|$)|\/\*[\s\S]*?\*\/)+/;function ef(S){let M=S;for(;;){let $=M.replace(of,"");if($===M)return M.trimStart();M=$}}function SO(S){let M=[],$=0,f=!1,O=!1,A=!1,V=!1,y=!1,J=!1;for(let X=0;X<S.length;X+=1){let Z=S[X],E=S[X+1];if(y){if(Z===`
|
|
193
|
+
`)y=!1;continue}if(J){if(Z==="*"&&E==="/")J=!1,X+=1;continue}if(f){if(Z==="'")if(E==="'")X+=1;else f=!1;continue}if(O){if(Z==='"')if(E==='"')X+=1;else O=!1;continue}if(A){if(Z==="`")A=!1;continue}if(V){if(Z==="]")V=!1;continue}if(Z==="-"&&E==="-"){y=!0,X+=1;continue}if(Z==="/"&&E==="*"){J=!0,X+=1;continue}if(Z==="'"){f=!0;continue}if(Z==='"'){O=!0;continue}if(Z==="`"){A=!0;continue}if(Z==="["){V=!0;continue}if(Z===";"){let Q=S.slice($,X).trim();if(Q.length>0)M.push(Q);$=X+1}}let N=S.slice($).trim();if(N.length>0)M.push(N);return M}function MO(S){let M=ef(S);if(!M)return!1;let $=M.toUpperCase();if(/\bRETURNING\b/.test($))return!0;if($.startsWith("PRAGMA")){if(/^PRAGMA\s+(?:[A-Z0-9_]+\.)?[A-Z0-9_]+\s*=/.test($))return!0;let O=/^PRAGMA\s+(?:[A-Z0-9_]+\.)?([A-Z0-9_]+)/.exec($)?.[1];if(!O)return!1;return af.has(O)}let f=/^[A-Z]+/.exec($)?.[0];if(!f)return!1;if(sf.has(f))return!0;if(f==="WITH")return/\b(INSERT|UPDATE|DELETE|REPLACE)\b/.test($);return!1}function NS(S){let M=SO(S);if(M.length===0)return!1;for(let $ of M)if(MO($))return!0;return!1}var $O=new Set(["PASSIVE","FULL","RESTART","TRUNCATE"]);function H0(S){if(S instanceof Error){let M=S.code;return{code:typeof M==="string"?M:"UNKNOWN",message:S.message}}return{code:"UNKNOWN",message:String(S)}}function fO(S){if(S&&typeof S==="object"&&"code"in S){let M=S.code;return tf.has(M)}return!1}class f1{db;dbPath;advisoryWriteLockPath;processRole;transactionDepth=0;_hasVectorExtension=!1;static enableExtensionSupport(){let S=["/opt/homebrew/opt/sqlite/lib/libsqlite3.dylib","/usr/local/opt/sqlite/lib/libsqlite3.dylib"];for(let M of S)try{if(nf(M))return SM.setCustomSQLite(M),!0}catch{return!1}return!1}constructor(S,M={}){this.dbPath=S,this.processRole=M.processRole??s2,this.advisoryWriteLockPath=o2(S),this.db=this.open(S),this.configure()}open(S){let M=S.lastIndexOf("/");if(M>0){let $=S.substring(0,M);rf($,{recursive:!0})}return new SM(S,{create:!0})}configure(){this.runConfigureStage("applyPragmas",()=>this.applyPragmas()),this.runConfigureStage("loadExtensions",()=>this.loadExtensions())}runConfigureStage(S,M){try{M()}catch($){this.throwConfigureFailure(S,$)}}throwConfigureFailure(S,M){let $=H0(M);try{this.db.close()}catch{}throw console.error("[open-mem] Database configure failed (non-destructive fail-safe)",{stage:S,dbPath:this.dbPath,sqliteCode:$.code,sqliteMessage:$.message,action:"startup-abort",deletionAttempted:!1}),Error(`Database startup failed during ${S} (fail-safe, non-destructive): [${$.code}] ${$.message}`)}applyPragmas(){this.db.exec("PRAGMA journal_mode = WAL"),this.db.exec("PRAGMA synchronous = NORMAL"),this.db.exec("PRAGMA foreign_keys = ON"),this.db.exec("PRAGMA busy_timeout = 5000")}loadExtensions(){try{$M.load(this.db),this._hasVectorExtension=!0}catch(S){let M=H0(S);console.warn("[open-mem] SQLite extension load skipped",{stage:"loadExtensions",dbPath:this.dbPath,sqliteCode:M.code,sqliteMessage:M.message,action:"continue-without-extension"}),this._hasVectorExtension=!1}}get hasVectorExtension(){return this._hasVectorExtension}ensureMigrationTable(){this.db.exec(`
|
|
193
194
|
CREATE TABLE IF NOT EXISTS _migrations (
|
|
194
195
|
version INTEGER PRIMARY KEY,
|
|
195
196
|
name TEXT NOT NULL,
|
|
196
197
|
applied_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
197
198
|
)
|
|
198
|
-
`)}migrate(S){this.ensureMigrationTable();let M=this.db.query("SELECT version FROM _migrations ORDER BY version").all()
|
|
199
|
+
`)}migrate(S){this.withAdvisoryWriteLock(this.processRole,()=>{this.ensureMigrationTable();let M=this.withRetry("migrate.applied_versions",()=>{return this.db.query("SELECT version FROM _migrations ORDER BY version").all()}),$=new Set(M.map((O)=>O.version)),f=S.filter((O)=>!$.has(O.version)).sort((O,A)=>O.version-A.version);for(let O of f)this.transaction(()=>{this.exec(O.up),this.run("INSERT INTO _migrations (version, name) VALUES ($version, $name)",[{$version:O.version,$name:O.name}])})})}withRetry(S,M){let $=this.transactionDepth>0?0:df,f;for(let O=0;O<=$;O++)try{return M()}catch(A){if(f=A,!fO(A)||O===$)throw A;let V=MM*2**O+Math.random()*MM;Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,V);let y=H0(A);console.warn("[open-mem] Retrying after transient SQLite error",{attempt:O+1,maxRetries:$,operation:S,role:this.processRole,dbPath:this.dbPath,sqliteCode:y.code,sqliteMessage:y.message})}throw f}run(S,M){this.withAdvisoryWriteLock(this.processRole,()=>{this.withRetry("run",()=>{let $=this.db.query(S);if(M)$.run(...M);else $.run()})})}get(S,M){let $=()=>{let f=this.db.query(S);return M?f.get(...M):f.get()};if(NS(S))return this.withAdvisoryWriteLock(this.processRole,()=>this.withRetry("get",$));return this.withRetry("get",$)}all(S,M){let $=()=>{let f=this.db.query(S);return M?f.all(...M):f.all()};if(NS(S))return this.withAdvisoryWriteLock(this.processRole,()=>this.withRetry("all",$));return this.withRetry("all",$)}exec(S){let M=()=>this.withRetry("exec",()=>this.db.exec(S));if(NS(S)){this.withAdvisoryWriteLock(this.processRole,M);return}M()}transaction(S){return this.withAdvisoryWriteLock(this.processRole,()=>{if(this.transactionDepth>0)return S();let M=this.db.transaction(S);if(typeof M.immediate==="function"){this.transactionDepth+=1;try{return M.immediate()}finally{this.transactionDepth-=1}}this.db.exec("BEGIN IMMEDIATE"),this.transactionDepth+=1;try{let $=S();return this.db.exec("COMMIT"),$}catch($){let f=$;try{this.db.exec("ROLLBACK")}catch(O){if(f instanceof Error){let A=f;if(A.cause===void 0)A.cause=O;else A.suppressed=[...A.suppressed??[],O]}console.warn("[open-mem] Transaction rollback failed after transaction error",{dbPath:this.dbPath,originalError:H0(f),rollbackError:H0(O)})}throw f}finally{this.transactionDepth-=1}})}get writeLockPath(){return this.advisoryWriteLockPath}withAdvisoryWriteLock(S,M,$){try{return e2(this.advisoryWriteLockPath,{...$,role:S},M)}catch(f){if(f instanceof $1)console.error("[open-mem] Advisory write lock timeout",{role:S,dbPath:this.dbPath,lockPath:f.lockPath,waitDurationMs:f.waitDurationMs,owner:f.owner});throw f}}checkpointWal(S="PASSIVE"){let M=typeof S==="string"?S.toUpperCase():"";if(!$O.has(M))throw Error(`Invalid wal_checkpoint mode: ${String(S)}`);return this.withAdvisoryWriteLock(this.processRole,()=>{return this.withRetry("maintenance.wal_checkpoint",()=>{let $=this.db.query(`PRAGMA wal_checkpoint(${M})`).get();if(!$)throw Error("wal_checkpoint returned no result row");return{mode:M,busy:$.busy??0,logFrames:$.log??0,checkpointedFrames:$.checkpointed??0}})})}integrityCheck(S=1){let M=Number.isFinite(S)?Math.max(1,Math.floor(S)):1;return this.withRetry("maintenance.integrity_check",()=>{let $=this.db.query(`PRAGMA integrity_check(${M})`).all();if($.length===0)throw Error("integrity_check returned no result rows");let f=$.map((O)=>Object.values(O).find((A)=>typeof A==="string")).filter((O)=>typeof O==="string").map((O)=>O.trim()).filter((O)=>O.length>0);if(f.length===0)throw Error("integrity_check returned no diagnostic messages");return{ok:f.length===1&&f[0].toLowerCase()==="ok",messages:f,maxErrors:M}})}close(){this.db.close()}get isOpen(){try{return this.db.query("SELECT 1").get(),!0}catch{return!1}}get raw(){return this.db}}function O1(S,M){return new f1(S,M)}import{randomUUID as fM}from"crypto";class yS{db;constructor(S){this.db=S}upsertEntity(S,M){let $=fM(),f=new Date().toISOString();this.db.run(`INSERT INTO entities (id, name, entity_type, first_seen_at, last_seen_at, mention_count)
|
|
199
200
|
VALUES (?, ?, ?, ?, ?, 1)
|
|
200
201
|
ON CONFLICT(name, entity_type) DO UPDATE SET
|
|
201
202
|
mention_count = mention_count + 1,
|
|
202
|
-
last_seen_at = ?`,[f,
|
|
203
|
+
last_seen_at = ?`,[$,S,M,f,f,f]);let O=this.db.get("SELECT * FROM entities WHERE name = ? AND entity_type = ?",[S,M]);if(!O)throw Error(`Failed to upsert entity: ${S} (${M})`);return this.mapEntityRow(O)}createRelation(S,M,$,f){let O=fM(),A=new Date().toISOString();try{this.db.run(`INSERT OR IGNORE INTO entity_relations
|
|
203
204
|
(id, source_entity_id, target_entity_id, relationship, observation_id, created_at)
|
|
204
|
-
VALUES (?, ?, ?, ?, ?, ?)`,[
|
|
205
|
-
WHERE source_entity_id = ? AND target_entity_id = ? AND relationship = ?`,[S,M
|
|
205
|
+
VALUES (?, ?, ?, ?, ?, ?)`,[O,S,M,$,f,A])}catch{return null}let V=this.db.get(`SELECT * FROM entity_relations
|
|
206
|
+
WHERE source_entity_id = ? AND target_entity_id = ? AND relationship = ?`,[S,M,$]);return V?this.mapRelationRow(V):null}linkObservation(S,M){this.db.run("INSERT OR IGNORE INTO entity_observations (entity_id, observation_id) VALUES (?, ?)",[S,M])}findByName(S){try{return this.db.all(`SELECT e.*
|
|
206
207
|
FROM entities e
|
|
207
208
|
JOIN entities_fts fts ON e._rowid = fts.rowid
|
|
208
209
|
WHERE entities_fts MATCH ?
|
|
209
|
-
ORDER BY rank`,[S]).map((
|
|
210
|
-
WHERE source_entity_id = ? OR target_entity_id = ?`,[S,S]).map((
|
|
211
|
-
`)}function
|
|
210
|
+
ORDER BY rank`,[S]).map(($)=>this.mapEntityRow($))}catch{return[]}}getRelationsFor(S){return this.db.all(`SELECT * FROM entity_relations
|
|
211
|
+
WHERE source_entity_id = ? OR target_entity_id = ?`,[S,S]).map(($)=>this.mapRelationRow($))}traverseRelations(S,M=1){let $=Math.min(M,2),f=100,O=new Set,A=[{id:S,currentDepth:0}];O.add(S);while(A.length>0){if(O.size>=100)break;let V=A.shift();if(!V)continue;if(V.currentDepth>=$)continue;let y=this.getRelationsFor(V.id);for(let J of y){let N=J.sourceEntityId===V.id?J.targetEntityId:J.sourceEntityId;if(!O.has(N))O.add(N),A.push({id:N,currentDepth:V.currentDepth+1})}}return O}getObservationsForEntity(S){return this.db.all("SELECT observation_id FROM entity_observations WHERE entity_id = ?",[S]).map(($)=>$.observation_id)}getById(S){let M=this.db.get("SELECT * FROM entities WHERE id = ?",[S]);return M?this.mapEntityRow(M):null}mapEntityRow(S){return{id:S.id,name:S.name,entityType:S.entity_type,firstSeenAt:S.first_seen_at,lastSeenAt:S.last_seen_at,mentionCount:S.mention_count}}mapRelationRow(S){return{id:S.id,sourceEntityId:S.source_entity_id,targetEntityId:S.target_entity_id,relationship:S.relationship,observationId:S.observation_id,createdAt:S.created_at}}}function OO(S){try{let M=JSON.parse(S);return M&&typeof M==="object"?M:{}}catch{return{}}}class JS{db;constructor(S){this.db=S}list(){return this.db.all("SELECT id, timestamp, action, dry_run, result FROM maintenance_history ORDER BY timestamp DESC").map((S)=>({id:S.id,timestamp:S.timestamp,action:S.action,dryRun:S.dry_run===1,result:OO(S.result)}))}append(S){this.db.run("INSERT INTO maintenance_history (id, timestamp, action, dry_run, result) VALUES (?, ?, ?, ?, ?)",[S.id,S.timestamp,S.action,S.dryRun?1:0,JSON.stringify(S.result??{})])}}import{randomUUID as VO}from"crypto";import{embed as AO}from"ai";async function e(S,M){try{let{embedding:$}=await AO({model:S,value:M});return $}catch{return null}}function y0(S,M){if(S.length!==M.length||S.length===0)return 0;let $=0,f=0,O=0;for(let V=0;V<S.length;V++)$+=S[V]*M[V],f+=S[V]*S[V],O+=M[V]*M[V];let A=Math.sqrt(f)*Math.sqrt(O);if(A===0)return 0;return $/A}function XS(S){let M=[S.title,S.narrative];if(S.concepts.length>0)M.push(S.concepts.join(", "));return M.join(`
|
|
212
|
+
`)}function NO(S){return S.replace(/[%_\\]/g,"\\$&")}class ZS{db;constructor(S){this.db=S}create(S){let M=VO(),$=new Date().toISOString(),f=S.discoveryTokens??0,O=S.importance??3,A=S.scope??"project";return this.db.run(`INSERT INTO observations
|
|
212
213
|
(id, session_id, scope, type, title, subtitle, facts, narrative,
|
|
213
214
|
concepts, files_read, files_modified, raw_tool_output,
|
|
214
215
|
tool_name, created_at, token_count, discovery_tokens, importance, revision_of, deleted_at)
|
|
215
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[M,S.sessionId,
|
|
216
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[M,S.sessionId,A,S.type,S.title,S.subtitle,JSON.stringify(S.facts),S.narrative,JSON.stringify(S.concepts),JSON.stringify(S.filesRead),JSON.stringify(S.filesModified),S.rawToolOutput,S.toolName,$,S.tokenCount,f,O,null,null]),{...S,id:M,scope:A,createdAt:$,discoveryTokens:f,importance:O,revisionOf:null,deletedAt:null,supersededBy:null,supersededAt:null}}importObservation(S){this.db.run(`INSERT INTO observations
|
|
216
217
|
(id, session_id, scope, type, title, subtitle, facts, narrative,
|
|
217
218
|
concepts, files_read, files_modified, raw_tool_output,
|
|
218
219
|
tool_name, created_at, token_count, discovery_tokens, importance, revision_of, deleted_at)
|
|
@@ -221,68 +222,68 @@ ${J}`}return E}guide(){return["# open-mem Workflow Guide","","## Reading Memorie
|
|
|
221
222
|
JOIN sessions s ON o.session_id = s.id
|
|
222
223
|
WHERE s.project_path = ? AND o.superseded_by IS NULL AND o.deleted_at IS NULL
|
|
223
224
|
ORDER BY o.created_at DESC
|
|
224
|
-
LIMIT ?`,[S,M]).map((
|
|
225
|
+
LIMIT ?`,[S,M]).map(($)=>({id:$.id,sessionId:$.session_id,type:$.type,title:$.title,tokenCount:$.token_count,discoveryTokens:$.discovery_tokens??0,createdAt:$.created_at,importance:$.importance??3}))}getAroundTimestamp(S,M,$,f){let O=M>0?this.db.all(`SELECT o.*
|
|
225
226
|
FROM observations o
|
|
226
227
|
JOIN sessions s ON o.session_id = s.id
|
|
227
228
|
WHERE s.project_path = ? AND o.created_at < ?
|
|
228
229
|
AND o.superseded_by IS NULL AND o.deleted_at IS NULL
|
|
229
230
|
ORDER BY o.created_at DESC
|
|
230
|
-
LIMIT ?`,[
|
|
231
|
+
LIMIT ?`,[f,S,M]).reverse():[],A=$>0?this.db.all(`SELECT o.*
|
|
231
232
|
FROM observations o
|
|
232
233
|
JOIN sessions s ON o.session_id = s.id
|
|
233
234
|
WHERE s.project_path = ? AND o.created_at > ?
|
|
234
235
|
AND o.superseded_by IS NULL AND o.deleted_at IS NULL
|
|
235
236
|
ORDER BY o.created_at ASC
|
|
236
|
-
LIMIT ?`,[
|
|
237
|
+
LIMIT ?`,[f,S,$]):[];return[...O,...A].map((V)=>this.mapRow(V))}listByProject(S,M={}){let{limit:$=50,offset:f=0,type:O,state:A,sessionId:V}=M,y=`SELECT o.*
|
|
237
238
|
FROM observations o
|
|
238
239
|
JOIN sessions s ON o.session_id = s.id
|
|
239
|
-
WHERE s.project_path = ?`,
|
|
240
|
+
WHERE s.project_path = ?`,J=[S];if(V)y+=" AND o.session_id = ?",J.push(V);if(O)y+=" AND o.type = ?",J.push(O);if(A==="current")y+=" AND o.superseded_by IS NULL AND o.deleted_at IS NULL";else if(A==="superseded")y+=" AND o.superseded_by IS NOT NULL AND o.deleted_at IS NULL";else if(A==="tombstoned")y+=" AND o.deleted_at IS NOT NULL";else y+=" AND o.superseded_by IS NULL AND o.deleted_at IS NULL";return y+=" ORDER BY o.created_at DESC LIMIT ? OFFSET ?",J.push($,f),this.db.all(y,J).map((N)=>this.mapRow(N))}search(S){let M=!!S.projectPath,$=`
|
|
240
241
|
SELECT o.*, rank
|
|
241
242
|
FROM observations o
|
|
242
243
|
JOIN observations_fts fts ON o._rowid = fts.rowid
|
|
243
244
|
${M?"JOIN sessions s ON o.session_id = s.id":""}
|
|
244
245
|
WHERE observations_fts MATCH ? AND o.superseded_by IS NULL AND o.deleted_at IS NULL
|
|
245
|
-
|
|
246
|
-
OR EXISTS (SELECT 1 FROM json_each(o.files_modified) WHERE LOWER(value) LIKE LOWER(?) ESCAPE '\\'))`)
|
|
246
|
+
`,f=[S.query];if(M&&S.projectPath)$+=" AND s.project_path = ?",f.push(S.projectPath);if(S.sessionId)$+=" AND o.session_id = ?",f.push(S.sessionId);if(S.type)$+=" AND o.type = ?",f.push(S.type);if(S.importanceMin!==void 0)$+=" AND o.importance >= ?",f.push(S.importanceMin);if(S.importanceMax!==void 0)$+=" AND o.importance <= ?",f.push(S.importanceMax);if(S.createdAfter)$+=" AND o.created_at >= ?",f.push(S.createdAfter);if(S.createdBefore)$+=" AND o.created_at <= ?",f.push(S.createdBefore);if(S.concepts&&S.concepts.length>0){let O=S.concepts.map(()=>"EXISTS (SELECT 1 FROM json_each(o.concepts) WHERE LOWER(value) = LOWER(?))");$+=` AND (${O.join(" OR ")})`;for(let A of S.concepts)f.push(A)}if(S.files&&S.files.length>0){let O=S.files.map(()=>`(EXISTS (SELECT 1 FROM json_each(o.files_read) WHERE LOWER(value) LIKE LOWER(?) ESCAPE '\\')
|
|
247
|
+
OR EXISTS (SELECT 1 FROM json_each(o.files_modified) WHERE LOWER(value) LIKE LOWER(?) ESCAPE '\\'))`);$+=` AND (${O.join(" OR ")})`;for(let A of S.files){let V=`%${NO(A)}%`;f.push(V,V)}}return $+=" ORDER BY rank LIMIT ? OFFSET ?",f.push(S.limit??10),f.push(S.offset??0),this.db.all($,f).map((O)=>({observation:this.mapRow(O),rank:O.rank,snippet:O.title}))}searchByConcept(S,M=10,$){let f=!!$,O=`SELECT o.*
|
|
247
248
|
FROM observations o
|
|
248
249
|
JOIN observations_fts fts ON o._rowid = fts.rowid
|
|
249
|
-
${
|
|
250
|
+
${f?"JOIN sessions s ON o.session_id = s.id":""}
|
|
250
251
|
WHERE observations_fts MATCH ?
|
|
251
252
|
AND o.superseded_by IS NULL AND o.deleted_at IS NULL
|
|
252
|
-
${
|
|
253
|
+
${f?"AND s.project_path = ?":""}
|
|
253
254
|
ORDER BY rank
|
|
254
|
-
LIMIT ?`,
|
|
255
|
+
LIMIT ?`,V=[`concepts:"${S.replace(/"/g,'""')}"`];if(f&&$)V.push($);return V.push(M),this.db.all(O,V).map((y)=>this.mapRow(y))}searchByFile(S,M=10,$){let f=!!$,O=`SELECT o.*
|
|
255
256
|
FROM observations o
|
|
256
257
|
JOIN observations_fts fts ON o._rowid = fts.rowid
|
|
257
|
-
${
|
|
258
|
+
${f?"JOIN sessions s ON o.session_id = s.id":""}
|
|
258
259
|
WHERE observations_fts MATCH ?
|
|
259
260
|
AND o.superseded_by IS NULL AND o.deleted_at IS NULL
|
|
260
|
-
${
|
|
261
|
+
${f?"AND s.project_path = ?":""}
|
|
261
262
|
ORDER BY rank
|
|
262
|
-
LIMIT ?`,
|
|
263
|
+
LIMIT ?`,A=[`files_read:"${S.replace(/"/g,'""')}" OR files_modified:"${S.replace(/"/g,'""')}"`];if(f&&$)A.push($);return A.push(M),this.db.all(O,A).map((V)=>this.mapRow(V))}setEmbedding(S,M){this.db.run("UPDATE observations SET embedding = ? WHERE id = ?",[JSON.stringify(M),S])}getWithEmbeddings(S,M){return this.db.all(`SELECT o.id, o.embedding, o.title
|
|
263
264
|
FROM observations o
|
|
264
265
|
JOIN sessions s ON o.session_id = s.id
|
|
265
266
|
WHERE s.project_path = ? AND o.embedding IS NOT NULL AND o.superseded_by IS NULL AND o.deleted_at IS NULL
|
|
266
267
|
ORDER BY o.created_at DESC
|
|
267
|
-
LIMIT ?`,[S,M]).map((
|
|
268
|
+
LIMIT ?`,[S,M]).map(($)=>{try{return{id:$.id,embedding:JSON.parse($.embedding),title:$.title}}catch{return null}}).filter(($)=>$!==null)}findSimilar(S,M,$,f){let O=this.db.all(`SELECT id, embedding FROM observations
|
|
268
269
|
WHERE embedding IS NOT NULL AND type = ? AND superseded_by IS NULL AND deleted_at IS NULL
|
|
269
270
|
ORDER BY created_at DESC
|
|
270
|
-
LIMIT 200`,[M]),
|
|
271
|
+
LIMIT 200`,[M]),A=[];for(let V of O)try{let y=JSON.parse(V.embedding);if(!Array.isArray(y)||y.length!==S.length)continue;let J=y0(S,y);if(J>=$)A.push({id:V.id,similarity:J})}catch{}return A.sort((V,y)=>y.similarity-V.similarity).slice(0,f)}insertVecEmbedding(S,M){let $=new Float32Array(M);this.db.run("BEGIN");try{this.db.run("DELETE FROM observation_embeddings WHERE observation_id = ?",[S]),this.db.run("INSERT INTO observation_embeddings (observation_id, embedding) VALUES (?, ?)",[S,$]),this.db.run("COMMIT")}catch(f){throw this.db.run("ROLLBACK"),f}}migrateExistingEmbeddings(S){let M=this.db.all("SELECT id, embedding FROM observations WHERE embedding IS NOT NULL"),$=0,f=0;for(let O of M)try{let A=JSON.parse(O.embedding);if(!Array.isArray(A)||A.length!==S){f++;continue}this.insertVecEmbedding(O.id,A),$++}catch{f++}return{migrated:$,skipped:f}}getVecEmbeddingMatches(S,M){try{let $=new Float32Array(S);return this.db.all(`SELECT observation_id, distance
|
|
271
272
|
FROM observation_embeddings
|
|
272
|
-
WHERE embedding MATCH ? AND k = ?`,[
|
|
273
|
+
WHERE embedding MATCH ? AND k = ?`,[$,M]).map((f)=>({observationId:f.observation_id,distance:f.distance}))}catch{return[]}}searchVecSubset(S,M,$){if(M.length===0)return[];try{let f=new Float32Array(S),O=Math.max($*5,M.length),A=this.db.all(`SELECT observation_id, distance
|
|
273
274
|
FROM observation_embeddings
|
|
274
|
-
WHERE embedding MATCH ? AND k = ?`,[
|
|
275
|
+
WHERE embedding MATCH ? AND k = ?`,[f,O]),V=new Set(M);return A.filter((y)=>V.has(y.observation_id)).slice(0,$).map((y)=>({observationId:y.observation_id,distance:y.distance}))}catch{return[]}}update(S,M){let $=this.getById(S);if(!$)return null;if(Object.keys(M).length===0)return $;let f=this.create({sessionId:$.sessionId,scope:$.scope??"project",type:M.type??$.type,title:M.title??$.title,subtitle:M.subtitle??$.subtitle,facts:M.facts??$.facts,narrative:M.narrative??$.narrative,concepts:M.concepts??$.concepts,filesRead:M.filesRead??$.filesRead,filesModified:M.filesModified??$.filesModified,rawToolOutput:$.rawToolOutput,toolName:"mem-revise",tokenCount:$.tokenCount,discoveryTokens:$.discoveryTokens,importance:M.importance??$.importance});return this.db.run("UPDATE observations SET revision_of = ? WHERE id = ?",[S,f.id]),this.supersede(S,f.id),this.getById(f.id)}supersede(S,M){let $=new Date().toISOString();this.db.run("UPDATE observations SET superseded_by = ?, superseded_at = ? WHERE id = ?",[M,$,S])}delete(S){if(this.db.all("SELECT id FROM observations WHERE id = ?",[S]).length===0)return!1;let $=new Date().toISOString();return this.db.run("UPDATE observations SET deleted_at = ? WHERE id = ?",[$,S]),this.deleteEmbeddingsForObservations([S]),!0}getLineage(S){let M=this.getByIdIncludingArchived(S);if(!M)return[];let $=new Set([M.id]),f=[M];while(f[0].revisionOf){let O=this.getByIdIncludingArchived(f[0].revisionOf);if(!O||$.has(O.id))break;f.unshift(O),$.add(O.id)}while(f[f.length-1].supersededBy){let O=f[f.length-1].supersededBy;if(!O)break;let A=this.getByIdIncludingArchived(O);if(!A||$.has(A.id))break;f.push(A),$.add(A.id)}return f}deleteOlderThan(S){return this.db.all(`DELETE FROM observations
|
|
275
276
|
WHERE (created_at < datetime('now', '-' || ? || ' days') OR deleted_at IS NOT NULL)
|
|
276
277
|
AND session_id NOT IN (SELECT id FROM sessions WHERE status != 'completed')
|
|
277
|
-
RETURNING id`,[S]).length}deleteEmbeddingsForObservations(S){if(S.length===0)return;let M=S.map(()=>"?").join(",");try{this.db.run(`DELETE FROM observation_embeddings WHERE observation_id IN (${M})`,S)}catch{}this.db.run(`UPDATE observations SET embedding = NULL WHERE id IN (${M})`,S)}mapRow(S){return{id:S.id,sessionId:S.session_id,scope:S.scope??"project",type:S.type,title:S.title,subtitle:S.subtitle,facts:JSON.parse(S.facts),narrative:S.narrative,concepts:JSON.parse(S.concepts),filesRead:JSON.parse(S.files_read),filesModified:JSON.parse(S.files_modified),rawToolOutput:S.raw_tool_output,toolName:S.tool_name,createdAt:S.created_at,tokenCount:S.token_count,discoveryTokens:S.discovery_tokens??0,importance:S.importance??3,revisionOf:S.revision_of??null,deletedAt:S.deleted_at??null,supersededBy:S.superseded_by??null,supersededAt:S.superseded_at??null}}}import{randomUUID as
|
|
278
|
+
RETURNING id`,[S]).length}deleteEmbeddingsForObservations(S){if(S.length===0)return;let M=S.map(()=>"?").join(",");try{this.db.run(`DELETE FROM observation_embeddings WHERE observation_id IN (${M})`,S)}catch{}this.db.run(`UPDATE observations SET embedding = NULL WHERE id IN (${M})`,S)}mapRow(S){return{id:S.id,sessionId:S.session_id,scope:S.scope??"project",type:S.type,title:S.title,subtitle:S.subtitle,facts:JSON.parse(S.facts),narrative:S.narrative,concepts:JSON.parse(S.concepts),filesRead:JSON.parse(S.files_read),filesModified:JSON.parse(S.files_modified),rawToolOutput:S.raw_tool_output,toolName:S.tool_name,createdAt:S.created_at,tokenCount:S.token_count,discoveryTokens:S.discovery_tokens??0,importance:S.importance??3,revisionOf:S.revision_of??null,deletedAt:S.deleted_at??null,supersededBy:S.superseded_by??null,supersededAt:S.superseded_at??null}}}import{randomUUID as yO}from"crypto";class ES{db;constructor(S){this.db=S}create(S){let M=yO(),$=new Date().toISOString();return this.db.run(`INSERT INTO pending_messages
|
|
278
279
|
(id, session_id, tool_name, tool_output, call_id, created_at)
|
|
279
|
-
VALUES (?, ?, ?, ?, ?, ?)`,[M,S.sessionId,S.toolName,S.toolOutput,S.callId
|
|
280
|
+
VALUES (?, ?, ?, ?, ?, ?)`,[M,S.sessionId,S.toolName,S.toolOutput,S.callId,$]),{...S,id:M,createdAt:$,status:"pending",retryCount:0,error:null}}getPending(S=10){return this.db.all("SELECT * FROM pending_messages WHERE status = 'pending' ORDER BY created_at ASC LIMIT ?",[S]).map((M)=>this.mapRow(M))}getByStatus(S){return this.db.all("SELECT * FROM pending_messages WHERE status = ? ORDER BY created_at ASC",[S]).map((M)=>this.mapRow(M))}markProcessing(S){this.db.run("UPDATE pending_messages SET status = 'processing' WHERE id = ?",[S])}markCompleted(S){this.db.run("UPDATE pending_messages SET status = 'completed' WHERE id = ?",[S])}markFailed(S,M){this.db.run("UPDATE pending_messages SET status = 'failed', error = ?, retry_count = retry_count + 1 WHERE id = ?",[M,S])}resetStale(S=5){return this.db.all(`UPDATE pending_messages SET status = 'pending'
|
|
280
281
|
WHERE status = 'processing'
|
|
281
282
|
AND created_at < datetime('now', ? || ' minutes')
|
|
282
283
|
RETURNING id`,[`-${S}`]).length}deleteCompletedOlderThan(S){return this.db.all(`DELETE FROM pending_messages
|
|
283
284
|
WHERE status = 'completed'
|
|
284
285
|
AND created_at < datetime('now', '-' || ? || ' days')
|
|
285
|
-
RETURNING id`,[S]).length}mapRow(S){return{id:S.id,sessionId:S.session_id,toolName:S.tool_name,toolOutput:S.tool_output,callId:S.call_id,createdAt:S.created_at,status:S.status,retryCount:S.retry_count,error:S.error??null}}}var
|
|
286
|
+
RETURNING id`,[S]).length}mapRow(S){return{id:S.id,sessionId:S.session_id,toolName:S.tool_name,toolOutput:S.tool_output,callId:S.call_id,createdAt:S.created_at,status:S.status,retryCount:S.retry_count,error:S.error??null}}}var JO=[{version:1,name:"create-schema",up:`
|
|
286
287
|
-- Sessions table
|
|
287
288
|
CREATE TABLE IF NOT EXISTS sessions (
|
|
288
289
|
_rowid INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
@@ -576,15 +577,15 @@ ${J}`}return E}guide(){return["# open-mem Workflow Guide","","## Reading Memorie
|
|
|
576
577
|
INSERT INTO entities_fts(rowid, name, entity_type)
|
|
577
578
|
VALUES (new._rowid, new.name, new.entity_type);
|
|
578
579
|
END;
|
|
579
|
-
`}];function
|
|
580
|
+
`}];function OM(S,M){if(S.migrate(JO),M?.hasVectorExtension&&M?.embeddingDimension&&M.embeddingDimension>0)XO(S,M.embeddingDimension)}function XO(S,M){if(S.get("SELECT name FROM sqlite_master WHERE type='table' AND name='observation_embeddings'")){let f=S.get("SELECT value FROM _embedding_meta WHERE key = 'dimension'");if(f&&Number(f.value)!==M){console.warn(`[open-mem] vec0 table exists with dimension ${f.value}, but config specifies ${M}. Drop observation_embeddings to re-create with new dimension.`);return}}else S.exec(`CREATE VIRTUAL TABLE observation_embeddings USING vec0(
|
|
580
581
|
observation_id TEXT PRIMARY KEY,
|
|
581
582
|
embedding float[${M}] distance_metric=cosine
|
|
582
|
-
)`);S.run("INSERT OR REPLACE INTO _embedding_meta (key, value) VALUES (?, ?)",["dimension",String(M)])}class
|
|
583
|
-
VALUES (?, ?, ?, 'active')`,[S,M
|
|
583
|
+
)`);S.run("INSERT OR REPLACE INTO _embedding_meta (key, value) VALUES (?, ?)",["dimension",String(M)])}class QS{db;constructor(S){this.db=S}create(S,M){let $=new Date().toISOString();return this.db.run(`INSERT INTO sessions (id, project_path, started_at, status)
|
|
584
|
+
VALUES (?, ?, ?, 'active')`,[S,M,$]),this.getById(S)}getOrCreate(S,M){let $=this.getById(S);if($)return $;return this.create(S,M)}getById(S){let M=this.db.get("SELECT * FROM sessions WHERE id = ?",[S]);return M?this.mapRow(M):null}getRecent(S,M=10){return this.db.all("SELECT * FROM sessions WHERE project_path = ? ORDER BY started_at DESC LIMIT ?",[S,M]).map(($)=>this.mapRow($))}getAll(S){return this.db.all("SELECT * FROM sessions WHERE project_path = ? ORDER BY started_at DESC",[S]).map((M)=>this.mapRow(M))}getActive(){return this.db.all("SELECT * FROM sessions WHERE status = 'active' ORDER BY started_at DESC").map((S)=>this.mapRow(S))}updateStatus(S,M){this.db.run("UPDATE sessions SET status = ? WHERE id = ?",[M,S])}markCompleted(S){this.db.run("UPDATE sessions SET status = 'completed', ended_at = datetime('now') WHERE id = ?",[S])}incrementObservationCount(S){this.db.run("UPDATE sessions SET observation_count = observation_count + 1 WHERE id = ?",[S])}setSummary(S,M){this.db.run("UPDATE sessions SET summary_id = ? WHERE id = ?",[M,S])}mapRow(S){return{id:S.id,projectPath:S.project_path,startedAt:S.started_at,endedAt:S.ended_at??null,status:S.status,observationCount:S.observation_count,summaryId:S.summary_id??null}}}import{randomUUID as ZO}from"crypto";class BS{db;constructor(S){this.db=S}create(S){let M=ZO(),$=new Date().toISOString();return this.db.run(`INSERT INTO session_summaries
|
|
584
585
|
(id, session_id, summary, key_decisions, files_modified,
|
|
585
586
|
concepts, created_at, token_count,
|
|
586
587
|
request, investigated, learned, completed, next_steps)
|
|
587
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[M,S.sessionId,S.summary,JSON.stringify(S.keyDecisions),JSON.stringify(S.filesModified),JSON.stringify(S.concepts)
|
|
588
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[M,S.sessionId,S.summary,JSON.stringify(S.keyDecisions),JSON.stringify(S.filesModified),JSON.stringify(S.concepts),$,S.tokenCount,S.request??"",S.investigated??"",S.learned??"",S.completed??"",S.nextSteps??""]),{...S,id:M,createdAt:$}}importSummary(S){this.db.run(`INSERT INTO session_summaries
|
|
588
589
|
(id, session_id, summary, key_decisions, files_modified,
|
|
589
590
|
concepts, created_at, token_count,
|
|
590
591
|
request, investigated, learned, completed, next_steps)
|
|
@@ -593,7 +594,7 @@ ${J}`}return E}guide(){return["# open-mem Workflow Guide","","## Reading Memorie
|
|
|
593
594
|
JOIN summaries_fts fts ON ss._rowid = fts.rowid
|
|
594
595
|
WHERE summaries_fts MATCH ?
|
|
595
596
|
ORDER BY rank
|
|
596
|
-
LIMIT ?`,[S,M]).map((
|
|
597
|
+
LIMIT ?`,[S,M]).map(($)=>this.mapRow($))}mapRow(S){return{id:S.id,sessionId:S.session_id,summary:S.summary,keyDecisions:JSON.parse(S.key_decisions),filesModified:JSON.parse(S.files_modified),concepts:JSON.parse(S.concepts),createdAt:S.created_at,tokenCount:S.token_count,request:S.request||void 0,investigated:S.investigated||void 0,learned:S.learned||void 0,completed:S.completed||void 0,nextSteps:S.next_steps||void 0}}}import{randomUUID as EO}from"crypto";var QO=[{version:1,name:"create-user-observations",up:`
|
|
597
598
|
CREATE TABLE IF NOT EXISTS user_observations (
|
|
598
599
|
_rowid INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
599
600
|
id TEXT UNIQUE NOT NULL,
|
|
@@ -664,27 +665,27 @@ ${J}`}return E}guide(){return["# open-mem Workflow Guide","","## Reading Memorie
|
|
|
664
665
|
new.facts, new.concepts, new.files_read, new.files_modified
|
|
665
666
|
);
|
|
666
667
|
END;
|
|
667
|
-
`}];class
|
|
668
|
+
`}];class KS{db;constructor(S){let M=BO(S);this.db=O1(M),this.initializeUserSchema()}initializeUserSchema(){this.db.migrate(QO)}get database(){return this.db}close(){this.db.close()}}class WS{db;constructor(S){this.db=S}create(S){let M=EO(),$=new Date().toISOString();return this.db.run(`INSERT INTO user_observations
|
|
668
669
|
(id, type, title, subtitle, facts, narrative,
|
|
669
670
|
concepts, files_read, files_modified, tool_name,
|
|
670
671
|
created_at, token_count, importance, source_project)
|
|
671
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[M,S.type,S.title,S.subtitle,JSON.stringify(S.facts),S.narrative,JSON.stringify(S.concepts),JSON.stringify(S.filesRead),JSON.stringify(S.filesModified),S.toolName
|
|
672
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[M,S.type,S.title,S.subtitle,JSON.stringify(S.facts),S.narrative,JSON.stringify(S.concepts),JSON.stringify(S.filesRead),JSON.stringify(S.filesModified),S.toolName,$,S.tokenCount,S.importance??3,S.sourceProject]),{...S,id:M,createdAt:$,importance:S.importance??3}}search(S){try{let M=`
|
|
672
673
|
SELECT o.*, rank
|
|
673
674
|
FROM user_observations o
|
|
674
675
|
JOIN user_observations_fts fts ON o._rowid = fts.rowid
|
|
675
676
|
WHERE user_observations_fts MATCH ?
|
|
676
|
-
|
|
677
|
-
FROM user_observations
|
|
678
|
-
`).trim()}function
|
|
679
|
-
Key decisions:`);for(let
|
|
680
|
-
`)}function
|
|
681
|
-
Recent observation details:`);for(let
|
|
682
|
-
`)}function
|
|
683
|
-
|
|
684
|
-
${
|
|
677
|
+
`,$=[S.query];if(S.sourceProject)M+=" AND o.source_project = ?",$.push(S.sourceProject);return M+=" ORDER BY rank LIMIT ?",$.push(S.limit??10),this.db.all(M,$).map((f)=>({observation:this.mapRow(f),rank:f.rank}))}catch{return[]}}getIndex(S,M){let $=`SELECT id, type, title, token_count, created_at, importance, source_project
|
|
678
|
+
FROM user_observations`,f=[];if(M)$+=" WHERE source_project = ?",f.push(M);return $+=" ORDER BY created_at DESC LIMIT ?",f.push(S??20),this.db.all($,f).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(S){let M=this.db.get("SELECT * FROM user_observations WHERE id = ?",[S]);return M?this.mapRow(M):null}delete(S){return this.db.all("DELETE FROM user_observations WHERE id = ? RETURNING id",[S]).length>0}mapRow(S){return{id:S.id,type:S.type,title:S.title,subtitle:S.subtitle,facts:JSON.parse(S.facts),narrative:S.narrative,concepts:JSON.parse(S.concepts),filesRead:JSON.parse(S.files_read),filesModified:JSON.parse(S.files_modified),toolName:S.tool_name,createdAt:S.created_at,tokenCount:S.token_count,importance:S.importance??3,sourceProject:S.source_project}}}function BO(S){if(S.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 $=`${M}${S.slice(1)}`,f=$.substring(0,$.lastIndexOf("/"));return g("fs").mkdirSync(f,{recursive:!0}),$}return S}import{EventEmitter as KO}from"events";function AM(){return new KO}function A1(S,M=""){if(!S)return S;return S.replace(/<private>[\s\S]*?<\/private>/gi,M)}var VM=200,WO=/(\([\s\S]*[+*]\)\s*[+*?])|(\(\.\*\)\+)|(\(\.\+\)\+)/;function V1(S,M,$="[REDACTED]"){if(!S||M.length===0)return S;let f=S;for(let O of M){if(O.length>VM){console.warn(`[open-mem] Skipping oversized redaction pattern (${O.length} chars, max ${VM})`);continue}if(WO.test(O)){console.warn("[open-mem] Skipping potentially dangerous redaction pattern (nested quantifiers detected)");continue}try{f=f.replace(new RegExp(O,"g"),$)}catch{}}return f}var _O=20,NM=2000,yM=60;function YO(S){return typeof S==="object"&&S!==null&&"text"in S&&typeof S.text==="string"}function UO(S){let M=[];for(let $ of S)if(typeof $==="string")M.push($);else if(YO($))M.push($.text);return M.join(`
|
|
679
|
+
`).trim()}function RO(S){let M=S.toLowerCase().replace(/[^a-z0-9\s-]/g," ").split(/\s+/).filter(($)=>$.length>4);return[...new Set(M)].slice(0,5)}function zO(S){let{observations:M,sessions:$,projectPath:f,sessionId:O,text:A,agent:V,sensitivePatterns:y=[]}=S;if(V!==void 0&&V!=="user")return!1;let J=V1(A1(A),y);if(J.length<_O)return!1;$.getOrCreate(O,f);let X=`User request: ${J.length>yM?`${J.slice(0,yM)}...`:J}`,Z=J.length>NM?`${J.slice(0,NM)}...`:J;return M.create({sessionId:O,type:"discovery",title:X,subtitle:"",facts:[],narrative:Z,concepts:RO(J),filesRead:[],filesModified:[],rawToolOutput:"",toolName:"chat.message",tokenCount:Math.ceil(Z.length/4),discoveryTokens:0,importance:3}),!0}function JM(S,M,$,f=[]){return async(O,A)=>{try{let{sessionID:V,agent:y}=O;if(y!==void 0&&y!=="user")return;let J=UO(A.parts);zO({observations:S,sessions:M,projectPath:$,sessionId:V,text:J,agent:y,sensitivePatterns:f})}catch(V){console.error("[open-mem] Chat capture error:",V)}}}var _S={bugfix:"\uD83D\uDD34",feature:"\uD83D\uDFE3",refactor:"\uD83D\uDD04",change:"\u2705",discovery:"\uD83D\uDD35",decision:"\u2696\uFE0F"};function DO(S){if(S.length===0)return"";let M=[];M.push(`
|
|
680
|
+
Key decisions:`);for(let $ of S)M.push(`- ${_S[$.type]||"\uD83D\uDCDD"} ${$.title}: ${$.narrative}`);return M.join(`
|
|
681
|
+
`)}function XM(S){if(S.length===0)return"";let M=[];M.push(`
|
|
682
|
+
Recent observation details:`);for(let $ of S){let f=_S[$.type]||"\uD83D\uDCDD";if(M.push(`- ${f} ${$.title}: ${$.narrative}`),$.facts.length>0)M.push(` Facts: ${$.facts.join("; ")}`)}return M.join(`
|
|
683
|
+
`)}function ZM(S,M,$,f,O,A){return async(V,y)=>{try{if(!S.contextInjectionEnabled)return;let J=Math.floor(S.maxContextTokens/2),N=$.getRecent(O,3),X=N.map((z)=>z.summaryId?f.getBySessionId(z.id):null).filter((z)=>z!==null),Z=M.getIndex(O,20),E=[];try{E=M.listByProject(O,{limit:5,state:"current"})}catch{}if(X.length===0&&Z.length===0&&E.length===0)return;let Q=Math.floor(J*0.4),K=O0(N,X,Z,Q,E),B=i0(K),W=Math.floor(J*0.4),U=XM(E);if(U&&j(U)<=W)B+=U;else if(U){let z=[],w=0;for(let k of E){let I=`- ${_S[k.type]||"\uD83D\uDCDD"} ${k.title}: ${k.narrative}`,T=j(I);if(w+T>W)break;z.push(k),w+=T}if(z.length>0)B+=XM(z)}let G=Math.floor(J*0.2),H=E.filter((z)=>z.type==="decision");if(H.length>0){let z=DO(H);if(j(z)<=G)B+=z}if(S.userMemoryEnabled&&A){let z=A.getIndex(10),w=d0(z,Math.floor(S.userMemoryMaxContextTokens/2));if(w)B+=w}y.context.push(B)}catch(J){console.error("[open-mem] Compaction hook error:",J)}}}function EM(S,M,$,f,O,A){return async(V,y)=>{try{if(!S.contextInjectionEnabled)return;let J=$.getRecent(O,5);if(J.length===0)return;let N=J.map((W)=>W.summaryId?f.getBySessionId(W.id):null).filter((W)=>W!==null),X=M.getIndex(O,S.maxObservations);if(N.length===0&&X.length===0)return;let E=X.slice(0,S.contextFullObservationCount).map((W)=>W.id).map((W)=>M.getById(W)).filter((W)=>W!==null),Q=O0(J,N,X,S.maxContextTokens,E),K={showTokenCosts:S.contextShowTokenCosts,observationTypes:S.contextObservationTypes,fullObservationCount:S.contextFullObservationCount,showLastSummary:S.contextShowLastSummary},B=r0(Q,K);if(S.userMemoryEnabled&&A){let W=A.getIndex(S.maxObservations),U=t0(W,S.userMemoryMaxContextTokens);if(U)B+=`
|
|
684
|
+
|
|
685
|
+
${U}`}y.system.push(B)}catch(J){console.error("[open-mem] Context injection error:",J)}}}import{existsSync as GO}from"fs";import{readFile as HO,writeFile as LO}from"fs/promises";import{join as CO}from"path";function QM(S,M,$){if(S.retentionDays===0)return;try{let f=M.deleteOlderThan(S.retentionDays),O=$.deleteCompletedOlderThan(S.retentionDays);if(f>0||O>0)console.log(`[open-mem] Retention: deleted ${f} observations, ${O} pending messages`)}catch(f){console.error("[open-mem] Retention enforcement error:",f)}}async function FO(S,M,$){let{queue:f,sessions:O,projectPath:A,config:V,observations:y,pendingMessages:J}=S;switch(M){case"session.created":{if($)O.getOrCreate($,A);try{QM(V,y,J)}catch(N){console.error("[open-mem] Retention enforcement error:",N)}try{await jO(A)}catch(N){console.error("[open-mem] Gitignore entry error:",N)}break}case"session.idle":{if(f.processBatch().catch((N)=>{console.error("[open-mem] Background processing error:",N)}),$)O.updateStatus($,"idle"),BM($,A,V,y).catch((N)=>{console.error("[open-mem] Folder context error:",N)});break}case"session.completed":case"session.ended":{if($)await f.processBatch(),await f.summarizeSession($),O.markCompleted($),await BM($,A,V,y);break}}}function KM(S,M,$,f,O,A){return async(V)=>{try{let{event:y}=V,J=y.properties.sessionID,N=typeof J==="string"?J:void 0;if(y.type==="session.created"||y.type==="session.idle"||y.type==="session.completed"||y.type==="session.ended")await FO({queue:S,sessions:M,projectPath:$,config:f,observations:O,pendingMessages:A},y.type,N)}catch(y){console.error("[open-mem] Event handler error:",y)}}}async function BM(S,M,$,f){if(!$.folderContextEnabled)return;try{let O=f.getBySession(S);if(O.length>0)await o0(M,O,{mode:$.folderContextMode,filename:$.folderContextFilename,maxDepth:$.folderContextMaxDepth})}catch(O){console.error("[open-mem] Folder context update error:",O)}}async function jO(S){let M=CO(S,".gitignore");if(!GO(M))return;let $=await HO(M,"utf-8");if($.includes("AGENTS.md"))return;let f=`
|
|
685
686
|
# open-mem: Auto-generated folder context files.
|
|
686
687
|
# Uncomment to exclude from version control (recommended for large projects):
|
|
687
688
|
# **/AGENTS.md
|
|
688
|
-
`;await
|
|
689
|
-
`)
|
|
690
|
-
${$}`,"utf-8")}function r$(S){let{config:M,queue:f,sessions:$,projectPath:A,tool:O,sessionId:y,callId:N,toolOutput:V}=S;if(M.ignoredTools.includes(O))return!1;if(!V||V.length<M.minOutputLength)return!1;let E=$S(V,M.sensitivePatterns);return E=fS(E,"[PRIVATE]"),$.getOrCreate(y,A),f.enqueue(y,O,E,N),!0}function f2(S,M,f,$){return async(A,O)=>{try{let{tool:y,sessionID:N,callID:V}=A,{output:E}=O;r$({config:S,queue:M,sessions:f,projectPath:$,tool:y,sessionId:N,callId:V,toolOutput:E})}catch(y){console.error("[open-mem] Tool capture error:",y)}}}class W1{config;compressor;summarizer;pendingRepo;observationRepo;sessionRepo;summaryRepo;embeddingModel;conflictEvaluator;entityExtractor;entityRepo;observer;processing=!1;timer=null;mode="in-process";onEnqueue=null;constructor(S,M,f,$,A,O,y,N=null,V=null,E=null,J=null,Q=null){this.config=S;this.compressor=M;this.summarizer=f;this.pendingRepo=$;this.observationRepo=A;this.sessionRepo=O;this.summaryRepo=y;this.embeddingModel=N;this.conflictEvaluator=V;this.entityExtractor=E;this.entityRepo=J;this.observer=Q}setMode(S){if(this.mode=S,S==="enqueue-only")this.stop()}getMode(){return this.mode}setOnEnqueue(S){this.onEnqueue=S}enqueue(S,M,f,$){if(this.pendingRepo.create({sessionId:S,toolName:M,toolOutput:f,callId:$}),this.observer?.onEnqueue?.({sessionId:S,toolName:M,createdAt:new Date().toISOString()}),this.mode==="enqueue-only")this.onEnqueue?.()}async processBatch(){if(this.mode==="enqueue-only")return 0;if(this.processing)return 0;this.processing=!0;let S=0,M=0,f=Date.now();try{this.pendingRepo.resetStale(5);let $=this.pendingRepo.getPending(this.config.batchSize);if(this.observer?.onBatchStart?.({pending:$.length,mode:this.mode,startedAt:new Date(f).toISOString()}),$.length===0)return 0;for(let A of $)try{this.pendingRepo.markProcessing(A.id);let y=await this.compressor.compress(A.toolName,A.toolOutput)??this.compressor.createFallbackObservation(A.toolName,A.toolOutput),N=!1,V=null;if(this.embeddingModel)try{let J=y1({title:y.title,narrative:y.narrative,concepts:y.concepts}),Q=await e(this.embeddingModel,J);if(Q){let _=this.config.conflictResolutionEnabled&&this.conflictEvaluator,B=this.config.conflictSimilarityBandLow??0.7,X=this.config.conflictSimilarityBandHigh??0.92;if(_){let W=this.observationRepo.findSimilar(Q,y.type,B,5),R=W.find((Y)=>Y.similarity>X);if(R)console.log(`[open-mem] Dedup: skipping duplicate of ${R.id} (similarity: ${R.similarity.toFixed(3)})`),N=!0;else{let Y=W.filter((L)=>L.similarity>=B&&L.similarity<=X);if(Y.length>0)try{let L=Y.map((G)=>{let U=this.observationRepo.getById(G.id);return U?{id:U.id,title:U.title,narrative:U.narrative,concepts:U.concepts,type:U.type}:null}).filter((G)=>G!==null);if(L.length>0&&this.conflictEvaluator){let G=await this.conflictEvaluator.evaluate({title:y.title,narrative:y.narrative,concepts:y.concepts,type:y.type},L);if(G&&G.outcome==="duplicate")console.log(`[open-mem] Conflict eval: duplicate (${G.reason})`),N=!0;else if(G&&G.outcome==="update"&&G.supersedesId)console.log(`[open-mem] Conflict eval: update supersedes ${G.supersedesId} (${G.reason})`),V=G.supersedesId}}catch{}}}else{let W=this.observationRepo.findSimilar(Q,y.type,0.92,1);if(W.length>0)console.log(`[open-mem] Dedup: skipping duplicate of ${W[0].id} (similarity: ${W[0].similarity.toFixed(3)})`),N=!0}}}catch{}if(N){this.pendingRepo.markCompleted(A.id);continue}let E=this.observationRepo.create({sessionId:A.sessionId,type:y.type,title:y.title,subtitle:y.subtitle,facts:y.facts,narrative:y.narrative,concepts:y.concepts,filesRead:y.filesRead,filesModified:y.filesModified,rawToolOutput:A.toolOutput,toolName:A.toolName,tokenCount:T(`${y.title} ${y.narrative} ${y.facts.join(" ")}`),discoveryTokens:y.discoveryTokens??T(A.toolOutput),importance:y.importance??3});if(this.embeddingModel)try{let J=y1({title:E.title,narrative:E.narrative,concepts:E.concepts}),Q=await e(this.embeddingModel,J);if(Q)this.observationRepo.setEmbedding(E.id,Q)}catch{}if(V)try{this.observationRepo.supersede(V,E.id),console.log(`[open-mem] Superseded observation ${V} with ${E.id}`)}catch(J){console.error(`[open-mem] Failed to supersede ${V}:`,J)}if(this.config.entityExtractionEnabled&&this.entityExtractor&&this.entityRepo)try{let J=await this.entityExtractor.extract({title:E.title,narrative:E.narrative,concepts:E.concepts,facts:E.facts,filesRead:E.filesRead,filesModified:E.filesModified,type:E.type});if(J){let Q=new Map;for(let _ of J.entities){let B=this.entityRepo.upsertEntity(_.name,_.entityType);Q.set(_.name,B.id),this.entityRepo.linkObservation(B.id,E.id)}for(let _ of J.relations){let B=Q.get(_.sourceName),X=Q.get(_.targetName);if(B&&X)this.entityRepo.createRelation(B,X,_.relationship,E.id)}}}catch{}this.sessionRepo.incrementObservationCount(A.sessionId),this.pendingRepo.markCompleted(A.id),S++}catch(O){this.pendingRepo.markFailed(A.id,String(O)),M++,this.observer?.onItemFailed?.({pendingId:A.id,error:String(O),failedAt:new Date().toISOString()})}return S}finally{this.observer?.onBatchEnd?.({processed:S,failed:M,durationMs:Date.now()-f,finishedAt:new Date().toISOString()}),this.processing=!1}}async summarizeSession(S){let M=this.observationRepo.getBySession(S);if(!this.summarizer.shouldSummarize(M.length))return;if(this.summaryRepo.getBySessionId(S))return;let $=await this.summarizer.summarize(S,M);if(!$)return;let A=this.summaryRepo.create({sessionId:S,summary:$.summary,keyDecisions:$.keyDecisions,filesModified:$.filesModified,concepts:$.concepts,tokenCount:T($.summary)});this.sessionRepo.setSummary(S,A.id)}start(){if(this.mode==="enqueue-only")return;if(this.timer)return;this.timer=setInterval(async()=>{try{await this.processBatch()}catch{}},this.config.batchIntervalMs)}stop(){if(this.timer)clearInterval(this.timer),this.timer=null}get isRunning(){return this.timer!==null}get isProcessing(){return this.processing}getStats(){return{pending:this.pendingRepo.getPending(1000).length,processing:this.processing}}}class X1{startedAtMs=Date.now();enqueueCount=0;totalBatches=0;processedItems=0;failedItems=0;totalBatchDurationMs=0;lastBatchDurationMs=0;lastProcessedAt=null;lastFailedAt=null;lastError=null;createQueueObserver(){return{onEnqueue:()=>{this.enqueueCount+=1},onBatchEnd:(S)=>{if(this.totalBatches+=1,this.processedItems+=S.processed,this.failedItems+=S.failed,this.totalBatchDurationMs+=S.durationMs,this.lastBatchDurationMs=S.durationMs,S.processed>0)this.lastProcessedAt=S.finishedAt},onItemFailed:(S)=>{this.lastFailedAt=S.failedAt,this.lastError=S.error}}}snapshot(S){return{startedAt:new Date(this.startedAtMs).toISOString(),uptimeMs:Date.now()-this.startedAtMs,enqueueCount:this.enqueueCount,batches:{total:this.totalBatches,processedItems:this.processedItems,failedItems:this.failedItems,avgDurationMs:this.totalBatches>0?Math.round(this.totalBatchDurationMs/this.totalBatches):0},queue:{...S,lastBatchDurationMs:this.lastBatchDurationMs,lastProcessedAt:this.lastProcessedAt,lastFailedAt:this.lastFailedAt,lastError:this.lastError}}}}function $2(S){return{start:()=>S.start(),stop:()=>{S.setOnEnqueue(null),S.stop()},setInProcess:()=>{S.setMode("in-process"),S.start()},setEnqueueOnly:(M)=>{S.setMode("enqueue-only"),S.setOnEnqueue(M)}}}async function A2(S,M,f,$,A){if(!S.trim())return M;let O=t$(S),y=new Set;for(let E of O){let J=f.findByName(E);for(let Q of J){let _=f.traverseRelations(Q.id,1);for(let B of _){let X=f.getObservationsForEntity(B);for(let W of X)y.add(W)}}}if(y.size===0)return M;let N=new Set(M.map((E)=>E.observation.id)),V=[];for(let E of y){if(N.has(E))continue;let J=$.getById(E);if(!J)continue;if(J.supersededBy)continue;V.push({observation:J,rank:0,snippet:J.title,source:"project",rankingSource:"graph",explain:{strategy:"hybrid",matchedBy:["graph"]}})}return[...M,...V].slice(0,A)}function t$(S){let M=S.split(/\s+/).filter(($)=>$.length>=2),f=[];for(let $ of M)f.push($);for(let $=0;$<M.length-1;$++)f.push(`${M[$]} ${M[$+1]}`);return f}class R1{strategies=new Map;register(S,M){this.strategies.set(S,M)}get(S){return this.strategies.get(S)??null}list(){return[...this.strategies.keys()]}}function AS(S){return Array.from(new Set(S))}function O2(S,M){let f=[],$=new Set;for(let A of S){if($.has(A.observation.id))continue;if($.add(A.observation.id),f.push(A),f.length>=M)break}return f}function i$(S,M){let f=M.toLowerCase();return S.some(($)=>$.toLowerCase()===f)}function d$(S,M){let f=M.toLowerCase();return S.some(($)=>$.toLowerCase().includes(f))}function y2(S,M){let f=AS([...M.concept?[M.concept]:[],...M.concepts??[]]),$=AS([...M.file?[M.file]:[],...M.files??[]]);return S.filter((A)=>{let O=A.observation;if(M.type&&O.type!==M.type)return!1;if(M.importanceMin!==void 0&&O.importance<M.importanceMin)return!1;if(M.importanceMax!==void 0&&O.importance>M.importanceMax)return!1;if(M.createdAfter&&O.createdAt<M.createdAfter)return!1;if(M.createdBefore&&O.createdAt>M.createdBefore)return!1;if(f.length>0&&!f.some((y)=>i$(O.concepts,y)))return!1;if($.length>0){let y=[...O.filesRead,...O.filesModified];if(!$.some((N)=>d$(y,N)))return!1}return!0})}function N0(S,M,f,$){let A=AS([...f.concept?[f.concept]:[],...f.concepts??[]]);if(A.length>0){let y=A.flatMap((V)=>S.observations.searchByConcept(V,$,f.projectPath)),N=O2(y.map((V)=>({observation:V,rank:0,snippet:V.title,rankingSource:"graph",explain:{strategy:"filter-only",matchedBy:["concept-filter"]}})),$);return y2(N,f).slice(0,$)}let O=AS([...f.file?[f.file]:[],...f.files??[]]);if(O.length>0){let y=O.flatMap((V)=>S.observations.searchByFile(V,$,f.projectPath)),N=O2(y.map((V)=>({observation:V,rank:0,snippet:V.title,rankingSource:"graph",explain:{strategy:"filter-only",matchedBy:["file-filter"]}})),$);return y2(N,f).slice(0,$)}return S.observations.search({query:M,type:f.type,limit:$,projectPath:f.projectPath,importanceMin:f.importanceMin,importanceMax:f.importanceMax,createdAfter:f.createdAfter,createdBefore:f.createdBefore,concepts:f.concepts,files:f.files})}function V0(S,M){if(M.type&&S.type!==M.type)return!1;if(M.importanceMin!==void 0&&S.importance<M.importanceMin)return!1;if(M.importanceMax!==void 0&&S.importance>M.importanceMax)return!1;if(M.createdAfter&&S.createdAt<M.createdAfter)return!1;if(M.createdBefore&&S.createdAt>M.createdBefore)return!1;if(M.concepts&&M.concepts.length>0){if(!M.concepts.some(($)=>S.concepts.some((A)=>A.toLowerCase().includes($.toLowerCase()))))return!1}if(M.files&&M.files.length>0){let f=[...S.filesRead,...S.filesModified];if(!M.files.some((A)=>f.some((O)=>O.toLowerCase().includes(A.toLowerCase()))))return!1}return!0}var E2=60;async function N2(S,M,f,$){let A=$.limit??10,O=s$(M,S,$,A);if(!f)return O;let y=await e(f,S);if(!y)return O;let N=O.map((E)=>E.observation.id),V=a$(M,y,$.projectPath,$,A,$.hasVectorExtension??!1,N);if(V.length===0)return O;return SA(O,V,A)}function s$(S,M,f,$){try{return S.search({query:M,type:f.type,limit:$,projectPath:f.projectPath,importanceMin:f.importanceMin,importanceMax:f.importanceMax,createdAfter:f.createdAfter,createdBefore:f.createdBefore,concepts:f.concepts,files:f.files})}catch{return[]}}function a$(S,M,f,$,A,O,y){if(O)return e$(S,M,$,A,y);return o$(S,M,f,$,A)}function e$(S,M,f,$,A){try{let O;if(A.length>0){if(O=S.searchVecSubset(M,A,$*3),O.length===0)O=S.getVecEmbeddingMatches(M,$*3)}else O=S.getVecEmbeddingMatches(M,$*3);if(O.length===0)return[];let y=[];for(let{observationId:N,distance:V}of O){if(y.length>=$)break;let E=S.getById(N);if(!E)continue;if(!V0(E,f))continue;y.push({observation:E,rank:V-1,snippet:E.title,rankingSource:"vector",explain:{strategy:"hybrid",matchedBy:["vector"],vectorDistance:V}})}return y}catch{return[]}}function o$(S,M,f,$,A){let O=S.getWithEmbeddings(f,A*10);if(O.length===0)return[];let y=O.map((V)=>({id:V.id,similarity:E0(M,V.embedding)})).filter(({similarity:V})=>V>=0.3).sort((V,E)=>E.similarity-V.similarity),N=[];for(let{id:V,similarity:E}of y){if(N.length>=A)break;let J=S.getById(V);if(!J)continue;if(!V0(J,$))continue;N.push({observation:J,rank:-E,snippet:J.title,rankingSource:"vector",explain:{strategy:"hybrid",matchedBy:["vector"],vectorSimilarity:E}})}return N}function SA(S,M,f){let $=new Map;for(let A=0;A<S.length;A++){let O=S[A],y=1/(E2+A+1);$.set(O.observation.id,{score:y,result:{...O,rankingSource:"fts",explain:{strategy:"hybrid",matchedBy:["fts"],ftsRank:O.rank}}})}for(let A=0;A<M.length;A++){let O=M[A],y=1/(E2+A+1),N=$.get(O.observation.id);if(N)N.score+=y,N.result={...N.result,explain:{strategy:"hybrid",matchedBy:["fts","vector"],ftsRank:N.result.explain?.ftsRank??N.result.rank,vectorDistance:O.explain?.vectorDistance,vectorSimilarity:O.explain?.vectorSimilarity}};else $.set(O.observation.id,{score:y,result:{...O,explain:{strategy:"hybrid",matchedBy:["vector"],vectorDistance:O.explain?.vectorDistance,vectorSimilarity:O.explain?.vectorSimilarity}}})}return[...$.values()].sort((A,O)=>O.score-A.score).slice(0,f).map(({score:A,result:O})=>({...O,explain:{...O.explain??{strategy:"hybrid",matchedBy:[]},strategy:"hybrid",matchedBy:O.explain?.matchedBy??[],rrfScore:A,ftsRank:O.explain?.ftsRank,vectorDistance:O.explain?.vectorDistance,vectorSimilarity:O.explain?.vectorSimilarity}}))}async function V2(S,M,f,$){return N2(M,S.observations,S.embeddingModel,{type:f.type,limit:$,projectPath:f.projectPath,hasVectorExtension:S.hasVectorExtension,importanceMin:f.importanceMin,importanceMax:f.importanceMax,createdAfter:f.createdAfter,createdBefore:f.createdBefore,concepts:f.concepts,files:f.files})}async function J2(S,M,f,$){if(!S.embeddingModel)return N0(S,M,f,$);let A=await e(S.embeddingModel,M);if(!A)return N0(S,M,f,$);if(S.hasVectorExtension)try{let V=S.observations.getVecEmbeddingMatches(A,$*3);if(V.length===0)return[];let E=[];for(let{observationId:J,distance:Q}of V){if(E.length>=$)break;let _=S.observations.getById(J);if(!_)continue;if(!V0(_,f))continue;E.push({observation:_,rank:Q-1,snippet:_.title,rankingSource:"vector",explain:{strategy:"semantic",matchedBy:["vector"],vectorDistance:Q}})}return E}catch{return N0(S,M,f,$)}let O=S.observations.getWithEmbeddings(f.projectPath,$*10);if(O.length===0)return[];let y=O.map((V)=>({id:V.id,similarity:E0(A,V.embedding)})).filter(({similarity:V})=>V>=0.3).sort((V,E)=>E.similarity-V.similarity),N=[];for(let{id:V,similarity:E}of y){if(N.length>=$)break;let J=S.observations.getById(V);if(!J)continue;if(!V0(J,f))continue;N.push({observation:J,rank:-E,snippet:J.title,rankingSource:"vector",explain:{strategy:"semantic",matchedBy:["vector"],vectorSimilarity:E}})}return N}class Z1{observations;embeddingModel;hasVectorExtension;reranker;userObservationRepo;entityRepo;strategyRegistry;constructor(S,M,f,$=null,A=null,O=null,y=null){this.observations=S;this.embeddingModel=M;this.hasVectorExtension=f;this.reranker=$;this.userObservationRepo=A;this.entityRepo=O;if(this.strategyRegistry=y??new R1,!this.strategyRegistry.get("filter-only"))this.strategyRegistry.register("filter-only",(N,V)=>N0({observations:this.observations,embeddingModel:this.embeddingModel,hasVectorExtension:this.hasVectorExtension},V.query,N,V.limit));if(!this.strategyRegistry.get("semantic"))this.strategyRegistry.register("semantic",(N,V)=>J2({observations:this.observations,embeddingModel:this.embeddingModel,hasVectorExtension:this.hasVectorExtension},V.query,N,V.limit));if(!this.strategyRegistry.get("hybrid"))this.strategyRegistry.register("hybrid",(N,V)=>V2({observations:this.observations,embeddingModel:this.embeddingModel,hasVectorExtension:this.hasVectorExtension},V.query,N,V.limit))}async search(S,M){let f=M.strategy??"hybrid",$=M.limit??10,A=this.normalizeOptions(M),O=this.strategyRegistry.get(f);if(!O)throw Error(`Unknown search strategy: ${f}`);let y=await O(A,{query:S,limit:$});if(y=y.map((N)=>({...N,source:"project"})),this.entityRepo&&S.trim())y=await A2(S,y,this.entityRepo,this.observations,$);if(this.userObservationRepo){let N=this.searchUserMemory(S,$);y=this.mergeResults(y,N,$)}if(this.reranker&&y.length>1)return this.reranker.rerank(S,y,$);return y}normalizeOptions(S){let M=S.concept?Array.from(new Set([S.concept,...S.concepts??[]])):S.concepts,f=S.file?Array.from(new Set([S.file,...S.files??[]])):S.files;return{...S,concepts:M,files:f}}searchUserMemory(S,M){if(!this.userObservationRepo)return[];try{return this.userObservationRepo.search({query:S,limit:M}).map(({observation:$,rank:A})=>({observation:MA($),rank:A,snippet:$.title,source:"user",rankingSource:"user-memory",explain:{strategy:"filter-only",matchedBy:["user-memory"]}}))}catch{return[]}}mergeResults(S,M,f){let $=new Set(S.map((y)=>y.observation.id)),A=new Set(S.map((y)=>`${y.observation.title}::${y.observation.narrative}`)),O=M.filter((y)=>{if($.has(y.observation.id))return!1;let N=`${y.observation.title}::${y.observation.narrative}`;if(A.has(N))return!1;return A.add(N),!0});return[...S,...O].slice(0,f)}}function MA(S){return{id:S.id,sessionId:"",type:S.type,title:S.title,subtitle:S.subtitle,facts:S.facts,narrative:S.narrative,concepts:S.concepts,filesRead:S.filesRead,filesModified:S.filesModified,rawToolOutput:"",toolName:S.toolName,createdAt:S.createdAt,tokenCount:S.tokenCount,discoveryTokens:0,importance:S.importance}}import{generateText as fA}from"ai";class Q2{languageModel;maxCandidates;provider;modelName;rateLimitingEnabled;_generate=fA;constructor(S,M){this.languageModel=S,this.maxCandidates=M.rerankingMaxCandidates,this.provider=M.provider??"",this.modelName=M.model??"",this.rateLimitingEnabled=M.rateLimitingEnabled??!0}async rerank(S,M,f){if(M.length<=1)return M;let $=M.slice(0,this.maxCandidates),A=M.slice(this.maxCandidates),O=KM(S,$.map((N)=>({title:N.observation.title,narrative:N.observation.narrative}))),y=2;for(let N=0;N<=y;N++)try{if(this.provider==="google")await v(this.modelName,this.rateLimitingEnabled);let{text:V}=await this._generate({model:this.languageModel,maxOutputTokens:512,prompt:O}),E=QM(V);if(!E)return M.slice(0,f);let J=this.applyReranking($,E,f);for(let Q of A){if(J.length>=f)break;J.push(Q)}return J}catch(V){if($A(V)&&N<y){await AA(2**N*1000);continue}return M.slice(0,f)}return M.slice(0,f)}applyReranking(S,M,f){let $=[],A=new Set;for(let O of M)if(O>=0&&O<S.length&&!A.has(O)){if(A.add(O),$.push(S[O]),$.length>=f)break}if($.length<f){for(let O=0;O<S.length&&$.length<f;O++)if(!A.has(O))$.push(S[O])}return $}}class _2{async rerank(S,M,f){if(M.length<=1)return M.slice(0,f);let $=K1(S),A=M.map((O)=>({result:O,score:this.scoreCandidate(O,$)}));return A.sort((O,y)=>y.score-O.score),A.slice(0,f).map((O)=>O.result)}scoreCandidate(S,M){let f=S.observation,$=K1(f.title),A=K1(f.narrative),O=new Set(f.concepts.map((Y)=>Y.toLowerCase())),y=0,N=0,V=0;for(let Y of M){if($.has(Y))y++;if(A.has(Y))N++;if(O.has(Y))V++}let E=M.size||1,J=y/E*0.4,Q=N/E*0.3,_=V/E*0.15,X=(Date.now()-new Date(f.createdAt).getTime())/86400000,W=X<1?0.1:X<7?0.05:0,R=f.importance/5*0.05;return J+Q+_+W+R}}function B2(S,M){if(!S.rerankingEnabled)return null;if(M)return new Q2(M,S);return new _2}function K1(S){return new Set(S.toLowerCase().split(/[\s\-_./\\,;:!?()[\]{}'"]+/).filter((M)=>M.length>1))}function $A(S){if(typeof S!=="object"||S===null)return!1;let M=S,f=M.status;if(f===429||f===500||f===503)return!0;let $=M.error;if(typeof $==="object"&&$!==null&&$.type==="overloaded_error")return!0;return!1}function AA(S){return new Promise((M)=>setTimeout(M,S))}function W2(S){return S}function X2(S){return S}function R2(S){return S}function Z2(S){if(!S)return null;return S}import{spawnSync as K2}from"child_process";import{dirname as OA,resolve as Y2}from"path";function yA(S){try{let M=K2("git",["rev-parse","--git-common-dir"],{cwd:S,encoding:"utf-8",timeout:5000});if(M.status!==0||!M.stdout)return null;let f=M.stdout.trim();if(f===".git")return null;let $=K2("git",["rev-parse","--git-dir"],{cwd:S,encoding:"utf-8",timeout:5000});if($.status!==0||!$.stdout)return null;let A=$.stdout.trim(),O=Y2(S,f),y=Y2(S,A);if(O===y)return null;let N=OA(O);if(N===O||N==="/")return null;return N}catch{return null}}function z2(S){return yA(S)??S}function _A(){try{let M=import.meta.url;if(M&&!M.includes("[eval]")){let f=JA(QA(M));return f.endsWith("dist")||f.endsWith("dist/")||f.endsWith("dist\\")?f:o(f,"..","dist")}}catch{}let S=[o(process.env.HOME||"",".config","opencode","node_modules","open-mem","dist"),o(process.cwd(),"node_modules","open-mem","dist")];for(let M of S)if(VA(o(M,"daemon.js")))return M;return o(process.cwd(),"node_modules","open-mem","dist")}async function BA(S,M){let f=M.provider!=="bedrock";if(!M.compressionEnabled||!f||M.apiKey)return;try{let $=S;if(!$?.config?.providers)return;let O=(await $.config.providers())?.data;if(!Array.isArray(O)||O.length===0)return;let y=O.map((N)=>N.id||N.name||"unknown").filter((N)=>N!=="unknown");if(y.length>0)console.warn("[open-mem] AI compression disabled \u2014 no API key found in environment."),console.warn(`[open-mem] OpenCode has providers configured: ${y.join(", ")}`),console.warn("[open-mem] These may use OAuth tokens that open-mem can't access directly."),console.warn("[open-mem] Tip: Get a free Gemini API key for compression:"),console.warn("[open-mem] \u2192 https://aistudio.google.com/apikey"),console.warn("[open-mem] \u2192 export GOOGLE_GENERATIVE_AI_API_KEY=your-key")}catch{}}async function WA(S){let M=_A(),f=z2(S.directory),$=R0(f),A=s1($);for(let I of A)console.warn(`[open-mem] ${I}`);await a1($),SS.enableExtensionSupport();let O=MS($.dbPath);pM(O,{hasVectorExtension:O.hasVectorExtension,embeddingDimension:$.embeddingDimension});let y=new V1(O),N=new E1(O),V=new J1(O),E=new N1(O),J=new f1(O),Q=new O1(O),_=null,B=null;if($.userMemoryEnabled)try{_=new Q1($.userMemoryDbPath),B=new _1(_.database)}catch(I){console.warn(`[open-mem] Failed to initialize user-level memory: ${I}`)}let X=new Y0($),W=new lS($),R=$.provider!=="bedrock",Y=null;if($.compressionEnabled&&R&&!$.apiKey)try{let{createOpenCodeBridge:I}=await Promise.resolve().then(() => U2);if(Y=I(S.client),Y){let j={modelId:"opencode-bridge",provider:"opencode"};X._generate=Y.generateText,X.model=j,W._generate=Y.generateText,W.model=j,console.log("[open-mem] AI compression: using OpenCode session model (no separate API key needed)")}}catch{}if(!Y)BA(S.client,$).catch(()=>{});let L=$.compressionEnabled&&(!R||$.apiKey)?zM({provider:$.provider,model:$.model,apiKey:$.apiKey}):null,G=new X1,U=$.conflictResolutionEnabled&&(!R||$.apiKey)?new PS({provider:$.provider,apiKey:$.apiKey,model:$.model,rateLimitingEnabled:$.rateLimitingEnabled}):null,k=$.entityExtractionEnabled&&(!R||$.apiKey)?new vS({provider:$.provider,apiKey:$.apiKey,model:$.model,rateLimitingEnabled:$.rateLimitingEnabled}):null,w=new A1(O),x=new W1($,X,W,E,N,y,V,L,U,k,w,G.createQueueObserver()),u=$2(x);u.start();let L0=()=>{let I=x.getStats(),j=G.snapshot({mode:x.getMode(),running:x.isRunning,processing:I.processing,pending:I.pending});return{status:j.queue.lastError?"degraded":"ok",timestamp:new Date().toISOString(),uptimeMs:j.uptimeMs,queue:j.queue,batches:j.batches,enqueueCount:j.enqueueCount}},g=B2($,$.rerankingEnabled&&(!R||$.apiKey)?P({provider:$.provider,model:$.model,apiKey:$.apiKey},q($)):null),OS=new Z1(N,L,O.hasVectorExtension,g,B,w),yS=new eS({observations:W2(N),sessions:X2(y),summaries:R2(V),searchOrchestrator:OS,projectPath:f,config:$,userObservationRepo:Z2(B),runtimeSnapshotProvider:L0,configAuditStore:J,maintenanceHistoryStore:Q}),D2=NM(yS),l=null,S0=null;if($.daemonEnabled)if(PM($.dbPath),l=new S1({dbPath:$.dbPath,projectPath:f,daemonScript:o(M,"daemon.js")}),l.start())u.setEnqueueOnly(()=>l?.signal("PROCESS_NOW")),console.log("[open-mem] Background daemon started \u2014 processing delegated"),S0=setInterval(()=>{if(l&&!l.isRunning()){if(console.warn("[open-mem] Daemon died, falling back to in-process processing"),u.setInProcess(),S0)clearInterval(S0),S0=null}},30000);else console.warn("[open-mem] Daemon failed to start \u2014 using in-process processing"),l=null;let ES=null,NS=null,G0=null;if($.dashboardEnabled){NS=nM(),G0=new mS(NS);let I=OM({config:$,projectPath:f,embeddingModel:L,memoryEngine:yS,runtimeStatusProvider:L0,sseHandler:EM(G0),dashboardDir:o(M,"dashboard")}),j=$.dashboardPort,VS="127.0.0.1";D1(VS,"Dashboard server");let JS=j,Y1=!1;for(let J0=0;J0<10;J0++){JS=j+J0;try{ES=Bun.serve({port:JS,hostname:VS,idleTimeout:0,fetch:I.fetch}),Y1=!0;break}catch{}}if(Y1)console.log(`[open-mem] Dashboard available at http://${VS}:${JS}`);else console.warn(`[open-mem] Could not start dashboard \u2014 ports ${j}-${j+9} all busy`);let G2=NS,C2=N.create.bind(N);N.create=(...J0)=>{let z1=C2(...J0);return G2.emit("observation:created",z1),z1}}let L2=()=>{if(Y)Y.cleanup().catch(()=>{});if(S0)clearInterval(S0);if(l)l.stop();if(u.stop(),ES)ES.stop();if(G0)G0.destroy();if(_)_.close();O.close()};return process.on("beforeExit",L2),{"tool.execute.after":f2($,x,y,f),"chat.message":dM(N,y,f,$.sensitivePatterns),event:M2(x,y,f,$,N,E),"experimental.chat.system.transform":eM($,N,y,V,f,B),"experimental.session.compacting":aM($,N,y,V,f,B),tool:{...D2}}}export{WA as default};
|
|
689
|
+
`;await LO(M,$.endsWith(`
|
|
690
|
+
`)?$+f:`${$}
|
|
691
|
+
${f}`,"utf-8")}function TO(S){let{config:M,queue:$,sessions:f,projectPath:O,tool:A,sessionId:V,callId:y,toolOutput:J}=S;if(M.ignoredTools.includes(A))return!1;if(!J||J.length<M.minOutputLength)return!1;let N=V1(J,M.sensitivePatterns);return N=A1(N,"[PRIVATE]"),f.getOrCreate(V,O),$.enqueue(V,A,N,y),!0}function WM(S,M,$,f){return async(O,A)=>{try{let{tool:V,sessionID:y,callID:J}=O,{output:N}=A;TO({config:S,queue:M,sessions:$,projectPath:f,tool:V,sessionId:y,callId:J,toolOutput:N})}catch(V){console.error("[open-mem] Tool capture error:",V)}}}class YS{config;compressor;summarizer;pendingRepo;observationRepo;sessionRepo;summaryRepo;embeddingModel;conflictEvaluator;entityExtractor;entityRepo;observer;processing=!1;timer=null;mode="in-process";onEnqueue=null;constructor(S,M,$,f,O,A,V,y=null,J=null,N=null,X=null,Z=null){this.config=S;this.compressor=M;this.summarizer=$;this.pendingRepo=f;this.observationRepo=O;this.sessionRepo=A;this.summaryRepo=V;this.embeddingModel=y;this.conflictEvaluator=J;this.entityExtractor=N;this.entityRepo=X;this.observer=Z}setMode(S){if(this.mode=S,S==="enqueue-only")this.stop()}getMode(){return this.mode}setOnEnqueue(S){this.onEnqueue=S}enqueue(S,M,$,f){if(this.pendingRepo.create({sessionId:S,toolName:M,toolOutput:$,callId:f}),this.observer?.onEnqueue?.({sessionId:S,toolName:M,createdAt:new Date().toISOString()}),this.mode==="enqueue-only")this.onEnqueue?.()}async processBatch(){if(this.mode==="enqueue-only")return 0;if(this.processing)return 0;this.processing=!0;let S=0,M=0,$=Date.now();try{this.pendingRepo.resetStale(5);let f=this.pendingRepo.getPending(this.config.batchSize);if(this.observer?.onBatchStart?.({pending:f.length,mode:this.mode,startedAt:new Date($).toISOString()}),f.length===0)return 0;for(let O of f)try{this.pendingRepo.markProcessing(O.id);let V=await this.compressor.compress(O.toolName,O.toolOutput)??this.compressor.createFallbackObservation(O.toolName,O.toolOutput),y=!1,J=null;if(this.embeddingModel)try{let X=XS({title:V.title,narrative:V.narrative,concepts:V.concepts}),Z=await e(this.embeddingModel,X);if(Z){let E=this.config.conflictResolutionEnabled&&this.conflictEvaluator,Q=this.config.conflictSimilarityBandLow??0.7,K=this.config.conflictSimilarityBandHigh??0.92;if(E){let B=this.observationRepo.findSimilar(Z,V.type,Q,5),W=B.find((U)=>U.similarity>K);if(W)console.log(`[open-mem] Dedup: skipping duplicate of ${W.id} (similarity: ${W.similarity.toFixed(3)})`),y=!0;else{let U=B.filter((G)=>G.similarity>=Q&&G.similarity<=K);if(U.length>0)try{let G=U.map((H)=>{let z=this.observationRepo.getById(H.id);return z?{id:z.id,title:z.title,narrative:z.narrative,concepts:z.concepts,type:z.type}:null}).filter((H)=>H!==null);if(G.length>0&&this.conflictEvaluator){let H=await this.conflictEvaluator.evaluate({title:V.title,narrative:V.narrative,concepts:V.concepts,type:V.type},G);if(H&&H.outcome==="duplicate")console.log(`[open-mem] Conflict eval: duplicate (${H.reason})`),y=!0;else if(H&&H.outcome==="update"&&H.supersedesId)console.log(`[open-mem] Conflict eval: update supersedes ${H.supersedesId} (${H.reason})`),J=H.supersedesId}}catch{}}}else{let B=this.observationRepo.findSimilar(Z,V.type,0.92,1);if(B.length>0)console.log(`[open-mem] Dedup: skipping duplicate of ${B[0].id} (similarity: ${B[0].similarity.toFixed(3)})`),y=!0}}}catch{}if(y){this.pendingRepo.markCompleted(O.id);continue}let N=this.observationRepo.create({sessionId:O.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:O.toolOutput,toolName:O.toolName,tokenCount:j(`${V.title} ${V.narrative} ${V.facts.join(" ")}`),discoveryTokens:V.discoveryTokens??j(O.toolOutput),importance:V.importance??3});if(this.embeddingModel)try{let X=XS({title:N.title,narrative:N.narrative,concepts:N.concepts}),Z=await e(this.embeddingModel,X);if(Z)this.observationRepo.setEmbedding(N.id,Z)}catch{}if(J)try{this.observationRepo.supersede(J,N.id),console.log(`[open-mem] Superseded observation ${J} with ${N.id}`)}catch(X){console.error(`[open-mem] Failed to supersede ${J}:`,X)}if(this.config.entityExtractionEnabled&&this.entityExtractor&&this.entityRepo)try{let X=await this.entityExtractor.extract({title:N.title,narrative:N.narrative,concepts:N.concepts,facts:N.facts,filesRead:N.filesRead,filesModified:N.filesModified,type:N.type});if(X){let Z=new Map;for(let E of X.entities){let Q=this.entityRepo.upsertEntity(E.name,E.entityType);Z.set(E.name,Q.id),this.entityRepo.linkObservation(Q.id,N.id)}for(let E of X.relations){let Q=Z.get(E.sourceName),K=Z.get(E.targetName);if(Q&&K)this.entityRepo.createRelation(Q,K,E.relationship,N.id)}}}catch{}this.sessionRepo.incrementObservationCount(O.sessionId),this.pendingRepo.markCompleted(O.id),S++}catch(A){this.pendingRepo.markFailed(O.id,String(A)),M++,this.observer?.onItemFailed?.({pendingId:O.id,error:String(A),failedAt:new Date().toISOString()})}return S}finally{this.observer?.onBatchEnd?.({processed:S,failed:M,durationMs:Date.now()-$,finishedAt:new Date().toISOString()}),this.processing=!1}}async summarizeSession(S){let M=this.observationRepo.getBySession(S);if(!this.summarizer.shouldSummarize(M.length))return;if(this.summaryRepo.getBySessionId(S))return;let f=await this.summarizer.summarize(S,M);if(!f)return;let O=this.summaryRepo.create({sessionId:S,summary:f.summary,keyDecisions:f.keyDecisions,filesModified:f.filesModified,concepts:f.concepts,tokenCount:j(f.summary)});this.sessionRepo.setSummary(S,O.id)}start(){if(this.mode==="enqueue-only")return;if(this.timer)return;this.timer=setInterval(async()=>{try{await this.processBatch()}catch{}},this.config.batchIntervalMs)}stop(){if(this.timer)clearInterval(this.timer),this.timer=null}get isRunning(){return this.timer!==null}get isProcessing(){return this.processing}getStats(){return{pending:this.pendingRepo.getPending(1000).length,processing:this.processing}}}class US{startedAtMs=Date.now();enqueueCount=0;totalBatches=0;processedItems=0;failedItems=0;totalBatchDurationMs=0;lastBatchDurationMs=0;lastProcessedAt=null;lastFailedAt=null;lastError=null;createQueueObserver(){return{onEnqueue:()=>{this.enqueueCount+=1},onBatchEnd:(S)=>{if(this.totalBatches+=1,this.processedItems+=S.processed,this.failedItems+=S.failed,this.totalBatchDurationMs+=S.durationMs,this.lastBatchDurationMs=S.durationMs,S.processed>0)this.lastProcessedAt=S.finishedAt},onItemFailed:(S)=>{this.lastFailedAt=S.failedAt,this.lastError=S.error}}}snapshot(S){return{startedAt:new Date(this.startedAtMs).toISOString(),uptimeMs:Date.now()-this.startedAtMs,enqueueCount:this.enqueueCount,batches:{total:this.totalBatches,processedItems:this.processedItems,failedItems:this.failedItems,avgDurationMs:this.totalBatches>0?Math.round(this.totalBatchDurationMs/this.totalBatches):0},queue:{...S,lastBatchDurationMs:this.lastBatchDurationMs,lastProcessedAt:this.lastProcessedAt,lastFailedAt:this.lastFailedAt,lastError:this.lastError}}}}function _M(S){return{start:()=>S.start(),stop:()=>{S.setOnEnqueue(null),S.stop()},setInProcess:()=>{S.setOnEnqueue(null),S.setMode("in-process"),S.start()},setEnqueueOnly:(M)=>{S.setMode("enqueue-only"),S.setOnEnqueue(M)}}}async function YM(S,M,$,f,O){if(!S.trim())return M;let A=xO(S),V=new Set;for(let N of A){let X=$.findByName(N);for(let Z of X){let E=$.traverseRelations(Z.id,1);for(let Q of E){let K=$.getObservationsForEntity(Q);for(let B of K)V.add(B)}}}if(V.size===0)return M;let y=new Set(M.map((N)=>N.observation.id)),J=[];for(let N of V){if(y.has(N))continue;let X=f.getById(N);if(!X)continue;if(X.supersededBy)continue;J.push({observation:X,rank:0,snippet:X.title,source:"project",rankingSource:"graph",explain:{strategy:"hybrid",matchedBy:["graph"]}})}return[...M,...J].slice(0,O)}function xO(S){let M=S.split(/\s+/).filter((f)=>f.length>=2),$=[];for(let f of M)$.push(f);for(let f=0;f<M.length-1;f++)$.push(`${M[f]} ${M[f+1]}`);return $}class RS{strategies=new Map;register(S,M){this.strategies.set(S,M)}get(S){return this.strategies.get(S)??null}list(){return[...this.strategies.keys()]}}function N1(S){return Array.from(new Set(S))}function UM(S,M){let $=[],f=new Set;for(let O of S){if(f.has(O.observation.id))continue;if(f.add(O.observation.id),$.push(O),$.length>=M)break}return $}function IO(S,M){let $=M.toLowerCase();return S.some((f)=>f.toLowerCase()===$)}function uO(S,M){let $=M.toLowerCase();return S.some((f)=>f.toLowerCase().includes($))}function RM(S,M){let $=N1([...M.concept?[M.concept]:[],...M.concepts??[]]),f=N1([...M.file?[M.file]:[],...M.files??[]]);return S.filter((O)=>{let A=O.observation;if(M.type&&A.type!==M.type)return!1;if(M.importanceMin!==void 0&&A.importance<M.importanceMin)return!1;if(M.importanceMax!==void 0&&A.importance>M.importanceMax)return!1;if(M.createdAfter&&A.createdAt<M.createdAfter)return!1;if(M.createdBefore&&A.createdAt>M.createdBefore)return!1;if($.length>0&&!$.some((V)=>IO(A.concepts,V)))return!1;if(f.length>0){let V=[...A.filesRead,...A.filesModified];if(!f.some((y)=>uO(V,y)))return!1}return!0})}function J0(S,M,$,f){let O=N1([...$.concept?[$.concept]:[],...$.concepts??[]]);if(O.length>0){let V=O.flatMap((J)=>S.observations.searchByConcept(J,f,$.projectPath)),y=UM(V.map((J)=>({observation:J,rank:0,snippet:J.title,rankingSource:"graph",explain:{strategy:"filter-only",matchedBy:["concept-filter"]}})),f);return RM(y,$).slice(0,f)}let A=N1([...$.file?[$.file]:[],...$.files??[]]);if(A.length>0){let V=A.flatMap((J)=>S.observations.searchByFile(J,f,$.projectPath)),y=UM(V.map((J)=>({observation:J,rank:0,snippet:J.title,rankingSource:"graph",explain:{strategy:"filter-only",matchedBy:["file-filter"]}})),f);return RM(y,$).slice(0,f)}return S.observations.search({query:M,type:$.type,limit:f,projectPath:$.projectPath,importanceMin:$.importanceMin,importanceMax:$.importanceMax,createdAfter:$.createdAfter,createdBefore:$.createdBefore,concepts:$.concepts,files:$.files})}function X0(S,M){if(M.type&&S.type!==M.type)return!1;if(M.importanceMin!==void 0&&S.importance<M.importanceMin)return!1;if(M.importanceMax!==void 0&&S.importance>M.importanceMax)return!1;if(M.createdAfter&&S.createdAt<M.createdAfter)return!1;if(M.createdBefore&&S.createdAt>M.createdBefore)return!1;if(M.concepts&&M.concepts.length>0){if(!M.concepts.some((f)=>S.concepts.some((O)=>O.toLowerCase().includes(f.toLowerCase()))))return!1}if(M.files&&M.files.length>0){let $=[...S.filesRead,...S.filesModified];if(!M.files.some((O)=>$.some((A)=>A.toLowerCase().includes(O.toLowerCase()))))return!1}return!0}var zM=60;async function DM(S,M,$,f){let O=f.limit??10,A=wO(M,S,f,O);if(!$)return A;let V=await e($,S);if(!V)return A;let y=A.map((N)=>N.observation.id),J=kO(M,V,f.projectPath,f,O,f.hasVectorExtension??!1,y);if(J.length===0)return A;return vO(A,J,O)}function wO(S,M,$,f){try{return S.search({query:M,type:$.type,limit:f,projectPath:$.projectPath,importanceMin:$.importanceMin,importanceMax:$.importanceMax,createdAfter:$.createdAfter,createdBefore:$.createdBefore,concepts:$.concepts,files:$.files})}catch{return[]}}function kO(S,M,$,f,O,A,V){if(A)return qO(S,M,f,O,V);return gO(S,M,$,f,O)}function qO(S,M,$,f,O){try{let A;if(O.length>0){if(A=S.searchVecSubset(M,O,f*3),A.length===0)A=S.getVecEmbeddingMatches(M,f*3)}else A=S.getVecEmbeddingMatches(M,f*3);if(A.length===0)return[];let V=[];for(let{observationId:y,distance:J}of A){if(V.length>=f)break;let N=S.getById(y);if(!N)continue;if(!X0(N,$))continue;V.push({observation:N,rank:J-1,snippet:N.title,rankingSource:"vector",explain:{strategy:"hybrid",matchedBy:["vector"],vectorDistance:J}})}return V}catch{return[]}}function gO(S,M,$,f,O){let A=S.getWithEmbeddings($,O*10);if(A.length===0)return[];let V=A.map((J)=>({id:J.id,similarity:y0(M,J.embedding)})).filter(({similarity:J})=>J>=0.3).sort((J,N)=>N.similarity-J.similarity),y=[];for(let{id:J,similarity:N}of V){if(y.length>=O)break;let X=S.getById(J);if(!X)continue;if(!X0(X,f))continue;y.push({observation:X,rank:-N,snippet:X.title,rankingSource:"vector",explain:{strategy:"hybrid",matchedBy:["vector"],vectorSimilarity:N}})}return y}function vO(S,M,$){let f=new Map;for(let O=0;O<S.length;O++){let A=S[O],V=1/(zM+O+1);f.set(A.observation.id,{score:V,result:{...A,rankingSource:"fts",explain:{strategy:"hybrid",matchedBy:["fts"],ftsRank:A.rank}}})}for(let O=0;O<M.length;O++){let A=M[O],V=1/(zM+O+1),y=f.get(A.observation.id);if(y)y.score+=V,y.result={...y.result,explain:{strategy:"hybrid",matchedBy:["fts","vector"],ftsRank:y.result.explain?.ftsRank??y.result.rank,vectorDistance:A.explain?.vectorDistance,vectorSimilarity:A.explain?.vectorSimilarity}};else f.set(A.observation.id,{score:V,result:{...A,explain:{strategy:"hybrid",matchedBy:["vector"],vectorDistance:A.explain?.vectorDistance,vectorSimilarity:A.explain?.vectorSimilarity}}})}return[...f.values()].sort((O,A)=>A.score-O.score).slice(0,$).map(({score:O,result:A})=>({...A,explain:{...A.explain??{strategy:"hybrid",matchedBy:[]},strategy:"hybrid",matchedBy:A.explain?.matchedBy??[],rrfScore:O,ftsRank:A.explain?.ftsRank,vectorDistance:A.explain?.vectorDistance,vectorSimilarity:A.explain?.vectorSimilarity}}))}async function GM(S,M,$,f){return DM(M,S.observations,S.embeddingModel,{type:$.type,limit:f,projectPath:$.projectPath,hasVectorExtension:S.hasVectorExtension,importanceMin:$.importanceMin,importanceMax:$.importanceMax,createdAfter:$.createdAfter,createdBefore:$.createdBefore,concepts:$.concepts,files:$.files})}async function HM(S,M,$,f){if(!S.embeddingModel)return J0(S,M,$,f);let O=await e(S.embeddingModel,M);if(!O)return J0(S,M,$,f);if(S.hasVectorExtension)try{let J=S.observations.getVecEmbeddingMatches(O,f*3);if(J.length===0)return[];let N=[];for(let{observationId:X,distance:Z}of J){if(N.length>=f)break;let E=S.observations.getById(X);if(!E)continue;if(!X0(E,$))continue;N.push({observation:E,rank:Z-1,snippet:E.title,rankingSource:"vector",explain:{strategy:"semantic",matchedBy:["vector"],vectorDistance:Z}})}return N}catch{return J0(S,M,$,f)}let A=S.observations.getWithEmbeddings($.projectPath,f*10);if(A.length===0)return[];let V=A.map((J)=>({id:J.id,similarity:y0(O,J.embedding)})).filter(({similarity:J})=>J>=0.3).sort((J,N)=>N.similarity-J.similarity),y=[];for(let{id:J,similarity:N}of V){if(y.length>=f)break;let X=S.observations.getById(J);if(!X)continue;if(!X0(X,$))continue;y.push({observation:X,rank:-N,snippet:X.title,rankingSource:"vector",explain:{strategy:"semantic",matchedBy:["vector"],vectorSimilarity:N}})}return y}class zS{observations;embeddingModel;hasVectorExtension;reranker;userObservationRepo;entityRepo;strategyRegistry;constructor(S,M,$,f=null,O=null,A=null,V=null){this.observations=S;this.embeddingModel=M;this.hasVectorExtension=$;this.reranker=f;this.userObservationRepo=O;this.entityRepo=A;if(this.strategyRegistry=V??new RS,!this.strategyRegistry.get("filter-only"))this.strategyRegistry.register("filter-only",(y,J)=>J0({observations:this.observations,embeddingModel:this.embeddingModel,hasVectorExtension:this.hasVectorExtension},J.query,y,J.limit));if(!this.strategyRegistry.get("semantic"))this.strategyRegistry.register("semantic",(y,J)=>HM({observations:this.observations,embeddingModel:this.embeddingModel,hasVectorExtension:this.hasVectorExtension},J.query,y,J.limit));if(!this.strategyRegistry.get("hybrid"))this.strategyRegistry.register("hybrid",(y,J)=>GM({observations:this.observations,embeddingModel:this.embeddingModel,hasVectorExtension:this.hasVectorExtension},J.query,y,J.limit))}async search(S,M){let $=M.strategy??"hybrid",f=M.limit??10,O=this.normalizeOptions(M),A=this.strategyRegistry.get($);if(!A)throw Error(`Unknown search strategy: ${$}`);let V=await A(O,{query:S,limit:f});if(V=V.map((y)=>({...y,source:"project"})),this.entityRepo&&S.trim())V=await YM(S,V,this.entityRepo,this.observations,f);if(this.userObservationRepo){let y=this.searchUserMemory(S,f);V=this.mergeResults(V,y,f)}if(this.reranker&&V.length>1)return this.reranker.rerank(S,V,f);return V}normalizeOptions(S){let M=S.concept?Array.from(new Set([S.concept,...S.concepts??[]])):S.concepts,$=S.file?Array.from(new Set([S.file,...S.files??[]])):S.files;return{...S,concepts:M,files:$}}searchUserMemory(S,M){if(!this.userObservationRepo)return[];try{return this.userObservationRepo.search({query:S,limit:M}).map(({observation:f,rank:O})=>({observation:hO(f),rank:O,snippet:f.title,source:"user",rankingSource:"user-memory",explain:{strategy:"filter-only",matchedBy:["user-memory"]}}))}catch{return[]}}mergeResults(S,M,$){let f=new Set(S.map((V)=>V.observation.id)),O=new Set(S.map((V)=>`${V.observation.title}::${V.observation.narrative}`)),A=M.filter((V)=>{if(f.has(V.observation.id))return!1;let y=`${V.observation.title}::${V.observation.narrative}`;if(O.has(y))return!1;return O.add(y),!0});return[...S,...A].slice(0,$)}}function hO(S){return{id:S.id,sessionId:"",type:S.type,title:S.title,subtitle:S.subtitle,facts:S.facts,narrative:S.narrative,concepts:S.concepts,filesRead:S.filesRead,filesModified:S.filesModified,rawToolOutput:"",toolName:S.toolName,createdAt:S.createdAt,tokenCount:S.tokenCount,discoveryTokens:0,importance:S.importance}}import{generateText as PO}from"ai";class LM{languageModel;maxCandidates;provider;modelName;rateLimitingEnabled;_generate=PO;constructor(S,M){this.languageModel=S,this.maxCandidates=M.rerankingMaxCandidates,this.provider=M.provider??"",this.modelName=M.model??"",this.rateLimitingEnabled=M.rateLimitingEnabled??!0}async rerank(S,M,$){if(M.length<=1)return M;let f=M.slice(0,this.maxCandidates),O=M.slice(this.maxCandidates),A=G2(S,f.map((y)=>({title:y.observation.title,narrative:y.observation.narrative}))),V=2;for(let y=0;y<=V;y++)try{if(this.provider==="google")await m(this.modelName,this.rateLimitingEnabled);let{text:J}=await this._generate({model:this.languageModel,maxOutputTokens:512,prompt:A}),N=W2(J);if(!N)return M.slice(0,$);let X=this.applyReranking(f,N,$);for(let Z of O){if(X.length>=$)break;X.push(Z)}return X}catch(J){if(mO(J)&&y<V){await bO(2**y*1000);continue}return M.slice(0,$)}return M.slice(0,$)}applyReranking(S,M,$){let f=[],O=new Set;for(let A of M)if(A>=0&&A<S.length&&!O.has(A)){if(O.add(A),f.push(S[A]),f.length>=$)break}if(f.length<$){for(let A=0;A<S.length&&f.length<$;A++)if(!O.has(A))f.push(S[A])}return f}}class CM{async rerank(S,M,$){if(M.length<=1)return M.slice(0,$);let f=DS(S),O=M.map((A)=>({result:A,score:this.scoreCandidate(A,f)}));return O.sort((A,V)=>V.score-A.score),O.slice(0,$).map((A)=>A.result)}scoreCandidate(S,M){let $=S.observation,f=DS($.title),O=DS($.narrative),A=new Set($.concepts.map((U)=>U.toLowerCase())),V=0,y=0,J=0;for(let U of M){if(f.has(U))V++;if(O.has(U))y++;if(A.has(U))J++}let N=M.size||1,X=V/N*0.4,Z=y/N*0.3,E=J/N*0.15,K=(Date.now()-new Date($.createdAt).getTime())/86400000,B=K<1?0.1:K<7?0.05:0,W=$.importance/5*0.05;return X+Z+E+B+W}}function FM(S,M){if(!S.rerankingEnabled)return null;if(M)return new LM(M,S);return new CM}function DS(S){return new Set(S.toLowerCase().split(/[\s\-_./\\,;:!?()[\]{}'"]+/).filter((M)=>M.length>1))}function mO(S){if(typeof S!=="object"||S===null)return!1;let M=S,$=M.status;if($===429||$===500||$===503)return!0;let f=M.error;if(typeof f==="object"&&f!==null&&f.type==="overloaded_error")return!0;return!1}function bO(S){return new Promise((M)=>setTimeout(M,S))}function jM(S){return S}function TM(S){return S}function xM(S){return S}function IM(S){if(!S)return null;return S}import{spawnSync as uM}from"child_process";import{dirname as cO,resolve as wM}from"path";function lO(S){try{let M=uM("git",["rev-parse","--git-common-dir"],{cwd:S,encoding:"utf-8",timeout:5000});if(M.status!==0||!M.stdout)return null;let $=M.stdout.trim();if($===".git")return null;let f=uM("git",["rev-parse","--git-dir"],{cwd:S,encoding:"utf-8",timeout:5000});if(f.status!==0||!f.stdout)return null;let O=f.stdout.trim(),A=wM(S,$),V=wM(S,O);if(A===V)return null;let y=cO(A);if(y===A||y==="/")return null;return y}catch{return null}}function kM(S){return lO(S)??S}function dO(){try{let M=import.meta.url;if(M&&!M.includes("[eval]")){let $=iO(tO(M));return $.endsWith("dist")||$.endsWith("dist/")||$.endsWith("dist\\")?$:S0($,"..","dist")}}catch{}let S=[S0(process.env.HOME||"",".config","opencode","node_modules","open-mem","dist"),S0(process.cwd(),"node_modules","open-mem","dist")];for(let M of S)if(rO(S0(M,"daemon.js")))return M;return S0(process.cwd(),"node_modules","open-mem","dist")}async function sO(S,M){let $=M.provider!=="bedrock";if(!M.compressionEnabled||!$||M.apiKey)return;try{let f=S;if(!f?.config?.providers)return;let A=(await f.config.providers())?.data;if(!Array.isArray(A)||A.length===0)return;let V=A.map((y)=>y.id||y.name||"unknown").filter((y)=>y!=="unknown");if(V.length>0)console.warn("[open-mem] AI compression disabled \u2014 no API key found in environment."),console.warn(`[open-mem] OpenCode has providers configured: ${V.join(", ")}`),console.warn("[open-mem] These may use OAuth tokens that open-mem can't access directly."),console.warn("[open-mem] Tip: Get a free Gemini API key for compression:"),console.warn("[open-mem] \u2192 https://aistudio.google.com/apikey"),console.warn("[open-mem] \u2192 export GOOGLE_GENERATIVE_AI_API_KEY=your-key")}catch{}}async function aO(S){let M=dO(),$=kM(S.directory),f=_0($),O=M2(f);for(let u of O)console.warn(`[open-mem] ${u}`);await $2(f),f1.enableExtensionSupport();let A=O1(f.dbPath,{processRole:"plugin"});OM(A,{hasVectorExtension:A.hasVectorExtension,embeddingDimension:f.embeddingDimension});let V=new QS(A),y=new ZS(A),J=new BS(A),N=new ES(A),X=new AS(A),Z=new JS(A),E=null,Q=null;if(f.userMemoryEnabled)try{E=new KS(f.userMemoryDbPath),Q=new WS(E.database)}catch(u){console.warn(`[open-mem] Failed to initialize user-level memory: ${u}`)}let K=new R0(f),B=new p1(f),W=f.provider!=="bedrock",U=null;if(f.compressionEnabled&&W&&!f.apiKey)try{let{createOpenCodeBridge:u}=await Promise.resolve().then(() => qM);if(U=u(S.client),U){let x={modelId:"opencode-bridge",provider:"opencode"};K._generate=U.generateText,K.model=x,B._generate=U.generateText,B.model=x,console.log("[open-mem] AI compression: using OpenCode session model (no separate API key needed)")}}catch{}if(!U)sO(S.client,f).catch(()=>{});let G=f.compressionEnabled&&(!W||f.apiKey)?L2({provider:f.provider,model:f.model,apiKey:f.apiKey}):null,H=new US,z=f.conflictResolutionEnabled&&(!W||f.apiKey)?new c1({provider:f.provider,apiKey:f.apiKey,model:f.model,rateLimitingEnabled:f.rateLimitingEnabled}):null,w=f.entityExtractionEnabled&&(!W||f.apiKey)?new l1({provider:f.provider,apiKey:f.apiKey,model:f.model,rateLimitingEnabled:f.rateLimitingEnabled}):null,k=new yS(A),I=new YS(f,K,B,N,y,V,J,G,z,w,k,H.createQueueObserver()),T=_M(I);T.start();let L0=()=>{let u=I.getStats(),x=H.snapshot({mode:I.getMode(),running:I.isRunning,processing:u.processing,pending:u.pending});return{status:x.queue.lastError?"degraded":"ok",timestamp:new Date().toISOString(),uptimeMs:x.uptimeMs,queue:x.queue,batches:x.batches,enqueueCount:x.enqueueCount}},q=FM(f,f.rerankingEnabled&&(!W||f.apiKey)?P({provider:f.provider,model:f.model,apiKey:f.apiKey},h(f)):null),y1=new zS(y,G,A.hasVectorExtension,q,Q,k),J1=new MS({observations:jM(y),sessions:TM(V),summaries:xM(J),searchOrchestrator:y1,projectPath:$,config:f,userObservationRepo:IM(Q),runtimeSnapshotProvider:L0,configAuditStore:X,maintenanceHistoryStore:Z}),gM=Q2(J1),b=null,M0=null,GS=(u)=>{if(console.warn(`[open-mem] ${u}`),T.setInProcess(),M0)clearInterval(M0),M0=null};if(f.daemonEnabled)if(r2(f.dbPath),b=new fS({dbPath:f.dbPath,projectPath:$,daemonScript:S0(M,"daemon.js")}),b.start())T.setEnqueueOnly(()=>{let x=b?.signal("PROCESS_NOW");if(!x?.ok)GS(`Daemon signal failed (${x?.state??"no-daemon"}), falling back to in-process processing`)}),console.log("[open-mem] Background daemon started \u2014 processing delegated"),M0=setInterval(()=>{if(b&&!b.isRunning())GS("Daemon died, falling back to in-process processing")},30000);else console.warn("[open-mem] Daemon failed to start \u2014 using in-process processing"),b=null;let X1=null,Z1=null,C0=null;if(f.dashboardEnabled){Z1=AM(),C0=new P1(Z1);let u=X2({config:f,projectPath:$,embeddingModel:G,memoryEngine:J1,runtimeStatusProvider:L0,sseHandler:E2(C0),dashboardDir:S0(M,"dashboard")}),x=f.dashboardPort,E1="127.0.0.1";FS(E1,"Dashboard server");let Q1=x,HS=!1;for(let Z0=0;Z0<10;Z0++){Q1=x+Z0;try{X1=Bun.serve({port:Q1,hostname:E1,idleTimeout:0,fetch:u.fetch}),HS=!0;break}catch{}}if(HS)console.log(`[open-mem] Dashboard available at http://${E1}:${Q1}`);else console.warn(`[open-mem] Could not start dashboard \u2014 ports ${x}-${x+9} all busy`);let hM=Z1,PM=y.create.bind(y);y.create=(...Z0)=>{let LS=PM(...Z0);return hM.emit("observation:created",LS),LS}}let vM=()=>{if(U)U.cleanup().catch(()=>{});if(M0)clearInterval(M0);if(b)b.stop();if(T.stop(),X1)X1.stop();if(C0)C0.destroy();if(E)E.close();A.close()};return process.on("beforeExit",vM),{"tool.execute.after":WM(f,I,V,$),"chat.message":JM(y,V,$,f.sensitivePatterns),event:KM(I,V,$,f,y,N),"experimental.chat.system.transform":EM(f,y,V,J,$,Q),"experimental.session.compacting":ZM(f,y,V,J,$,Q),tool:{...gM}}}export{aO as default};
|