open-mem 0.14.0 → 0.14.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cursor.js CHANGED
@@ -1,48 +1,48 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
- var D=import.meta.require;import{createInterface as L0}from"readline";import{parseArgs as X0}from"util";var Ny=new Set(["127.0.0.1","::1","localhost"]);function Ey(u){return u.trim().toLowerCase()}function Wy(u){return Ny.has(Ey(u))}function Zu(u,y){if(Wy(u))return;throw Error(`[open-mem] ${y} must bind to loopback only (127.0.0.1, ::1, localhost). Received "${u}".`)}var Su={name:"claude-code",version:"0.1",capabilities:{nativeSessionLifecycle:!0,nativeToolCapture:!0,nativeChatCapture:!0,emulatedIdleFlush:!0}},Uu={name:"cursor",version:"0.1",capabilities:{nativeSessionLifecycle:!1,nativeToolCapture:!0,nativeChatCapture:!0,emulatedIdleFlush:!0}};function d(){return new Date().toISOString()}function I(u){if(!u||typeof u!=="object"||Array.isArray(u))return null;return u}function L(u){return typeof u==="string"&&u.trim().length>0?u:null}function n(u,y){let B=I(y);if(!B)return null;let $=L(B.kind),A=L(B.sessionId);if(!$||!A)return null;if($==="session.start"||$==="session.end"||$==="idle.flush")return{kind:$,platform:u,sessionId:A,occurredAt:L(B.occurredAt)??d(),metadata:I(B.metadata)??void 0};if($==="chat.message"){let J=L(B.text);if(!J)return null;let K=L(B.role);return{kind:$,platform:u,sessionId:A,text:J,role:K==="assistant"||K==="system"?K:"user",occurredAt:L(B.occurredAt)??d(),metadata:I(B.metadata)??void 0}}if($==="tool.execute"){let J=L(B.toolName),K=L(B.output);if(!J||!K)return null;return{kind:$,platform:u,sessionId:A,callId:L(B.callId)??`${u}-${Date.now()}`,toolName:J,output:K,occurredAt:L(B.occurredAt)??d(),metadata:I(B.metadata)??void 0}}return null}function Hy(u){let y=u.type??u.event;if(!y)return null;if(y==="session.start")return"session.start";if(y==="session.end")return"session.end";if(y==="idle.flush")return"idle.flush";if(y==="tool.execute")return"tool.execute";if(y==="chat.message")return"chat.message";return null}class ku{descriptor=Su;normalize(u){if(!u||typeof u!=="object"||Array.isArray(u))return null;let y=u,B=Hy(y);if(!B||!y.sessionId)return null;return n("claude-code",{kind:B,sessionId:y.sessionId,callId:y.callId,toolName:y.toolName,output:y.output,role:y.role,text:y.text,occurredAt:y.occurredAt,metadata:y.metadata})}}function Mu(){return new ku}function Qy(u){let y=u.eventName??u.event;if(!y)return null;if(y==="sessionStart")return"session.start";if(y==="sessionEnd")return"session.end";if(y==="idleFlush")return"idle.flush";if(y==="toolExecute")return"tool.execute";if(y==="chatMessage")return"chat.message";return null}class fu{descriptor=Uu;normalize(u){if(!u||typeof u!=="object"||Array.isArray(u))return null;let y=u,B=Qy(y),$=y.sessionId??y.session;if(!B||!$)return null;return n("cursor",{kind:B,sessionId:$,callId:y.callId??y.invocationId,toolName:y.toolName??y.tool,output:y.output,role:y.role,text:y.text??y.message,occurredAt:y.occurredAt??y.timestamp,metadata:y.metadata??y.meta})}}function Lu(){return new fu}function g(u,y=""){if(!u)return u;return u.replace(/<private>[\s\S]*?<\/private>/gi,y)}var Xu=200,Zy=/(\([\s\S]*[+*]\)\s*[+*?])|(\(\.\*\)\+)|(\(\.\+\)\+)/;function c(u,y,B="[REDACTED]"){if(!u||y.length===0)return u;let $=u;for(let A of y){if(A.length>Xu){console.warn(`[open-mem] Skipping oversized redaction pattern (${A.length} chars, max ${Xu})`);continue}if(Zy.test(A)){console.warn("[open-mem] Skipping potentially dangerous redaction pattern (nested quantifiers detected)");continue}try{$=$.replace(new RegExp(A,"g"),B)}catch{}}return $}var Sy=20,Yu=2000,Du=60;function Uy(u){let y=u.toLowerCase().replace(/[^a-z0-9\s-]/g," ").split(/\s+/).filter((B)=>B.length>4);return[...new Set(y)].slice(0,5)}function mu(u){let{observations:y,sessions:B,projectPath:$,sessionId:A,text:J,agent:K,sensitivePatterns:V=[]}=u;if(K!==void 0&&K!=="user")return!1;let R=c(g(J),V);if(R.length<Sy)return!1;B.getOrCreate(A,$);let N=`User request: ${R.length>Du?`${R.slice(0,Du)}...`:R}`,E=R.length>Yu?`${R.slice(0,Yu)}...`:R;return y.create({sessionId:A,type:"discovery",title:N,subtitle:"",facts:[],narrative:E,concepts:Uy(R),filesRead:[],filesModified:[],rawToolOutput:"",toolName:"chat.message",tokenCount:Math.ceil(E.length/4),discoveryTokens:0,importance:3}),!0}import{existsSync as Fy}from"fs";import{readFile as Gy,writeFile as Oy}from"fs/promises";import{join as Py}from"path";import{existsSync as Cu}from"fs";import{mkdir as ky,readFile as My,rename as fy,unlink as Ly,writeFile as Xy}from"fs/promises";import{dirname as v,isAbsolute as t,join as h,normalize as Yy,relative as o,resolve as j,sep as i}from"path";var p="<!-- open-mem-context -->",G="<!-- /open-mem-context -->",Fu={bugfix:"\uD83D\uDD34",feature:"\uD83D\uDFE3",refactor:"\uD83D\uDD04",change:"\u2705",discovery:"\uD83D\uDD35",decision:"\u2696\uFE0F"},_u=new Map,Dy=new Set(["node_modules",".git","dist","coverage",".open-mem","build","__pycache__",".next",".nuxt"]);async function Gu(u,y,B){if(y.length===0)return;if(B.mode==="single")return my(u,y,B);let{maxDepth:$,filename:A}=B,J=[];for(let R of y){for(let z of R.filesModified)J.push(z);for(let z of R.filesRead)J.push(z)}let K=Pu(J,u,$);if(K.size===0)return;let V=Tu(y,K,u);for(let[R,z]of V)try{let N=_y(R,z,u);await Ou(R,N,A)}catch(N){console.error(`[open-mem] Failed to update AGENTS.md in ${R}:`,N)}}async function my(u,y,B){let{maxDepth:$,filename:A}=B,J=y.filter(s);if(J.length===0)return;let K=[];for(let Q of J){for(let U of Q.filesModified)K.push(U);for(let U of Q.filesRead)K.push(U)}let V=Pu(K,u,$),R=Tu(J,V,u),z=J.filter((Q)=>{return[...Q.filesModified,...Q.filesRead].some((k)=>{if(!k)return!1;let M=t(k)?k:h(u,k);return j(v(M))===j(u)})});if(z.length>0)R.set(j(u),z);if(R.size===0)return;let N=[];N.push("## Project Activity (auto-generated by open-mem)"),N.push("");let E=[...R.entries()].map(([Q,U])=>({relPath:o(u,Q)||".",observations:U})).sort((Q,U)=>Q.relPath.localeCompare(U.relPath));for(let{relPath:Q,observations:U}of E){let k=U.filter(s).sort((Z,S)=>S.createdAt.localeCompare(Z.createdAt)).slice(0,10);if(k.length===0)continue;N.push(`### ${Q}/`),N.push("| ID | Type | Title | Date |"),N.push("|----|------|-------|------|");for(let Z of k){let S=Fu[Z.type]||"\uD83D\uDCDD",Y=Z.createdAt.split("T")[0],Vy=Z.title.replace(/\|/g,"\\|");N.push(`| ${Z.id} | ${S} ${Z.type} | ${Vy} | ${Y} |`)}let M=new Set;for(let Z of k)for(let S of Z.concepts)M.add(S);if(M.size>0){let Z=[...M].slice(0,10).join(", ");N.push(""),N.push(`**Key concepts:** ${Z}`)}let f=k.filter((Z)=>Z.type==="decision").map((Z)=>Z.title);if(f.length>0)N.push(""),N.push(`**Recent decisions:** ${f.slice(0,5).join("; ")}`);N.push("")}N.push("\uD83D\uDCA1 *Use `mem-find` to search full details. Use `mem-create` to save important decisions.*");let H=N.join(`
4
- `);await Ou(u,H,A)}function s(u){return!/^\w[\w-]*\s+execution$/i.test(u.title)}function _y(u,y,B){let $=[...y].filter(s).sort((z,N)=>N.createdAt.localeCompare(z.createdAt)).slice(0,10),A=o(B,u)||".",J=[];J.push(`## Recent Activity in \`${A}/\` (auto-generated by open-mem)`),J.push(""),J.push("| ID | Type | Title | Date |"),J.push("|----|------|-------|------|");for(let z of $){let N=Fu[z.type]||"\uD83D\uDCDD",E=z.createdAt.split("T")[0],H=z.title.replace(/\|/g,"\\|");J.push(`| ${z.id} | ${N} ${z.type} | ${H} | ${E} |`)}let K=new Set;for(let z of $)for(let N of z.concepts)K.add(N);if(K.size>0){let z=[...K].slice(0,10).join(", ");J.push(""),J.push(`**Key concepts:** ${z}`)}let V=$.filter((z)=>z.type==="decision").map((z)=>z.title);if(V.length>0)J.push(""),J.push(`**Recent decisions:** ${V.slice(0,5).join("; ")}`);let R=$.filter((z)=>z.type==="decision"&&z.narrative).slice(0,3);if(R.length>0){J.push(""),J.push("**Decision details:**");for(let z of R){let N=z.narrative.split(/[.!?]\s/)[0],E=N.length>120?`${N.slice(0,117)}...`:N;J.push(`- \u2696\uFE0F ${z.title}: ${E}`)}}return J.push(""),J.push("\uD83D\uDCA1 *Use `mem-find` to search full details across all sessions. Use `mem-create` to save important decisions.*"),J.join(`
5
- `)}async function Ou(u,y,B){if(!Cu(u))return;let A=(_u.get(u)??Promise.resolve()).then(async()=>{let J=h(u,B),K=h(u,`.${B}.tmp`),V="";try{V=await My(J,"utf-8")}catch{}let R=Cy(V,y);try{await ky(v(K),{recursive:!0}),await Xy(K,R,"utf-8"),await fy(K,J)}catch(z){try{await Ly(K)}catch{}throw z}});return _u.set(u,A.catch(()=>{})),A}function Cy(u,y){if(!u)return`${p}
6
- ${y}
7
- ${G}
8
- `;let B=u.indexOf(p),$=u.indexOf(G);if(B!==-1&&$!==-1&&$>B){let J=u.substring(0,B),K=u.substring($+G.length);return`${J}${p}
9
- ${y}
10
- ${G}${K}`}let A=u;if(B!==-1&&$===-1)A=A.replace(p,"").trim();else if(B===-1&&$!==-1)A=A.replace(G,"").trim();else if(B!==-1&&$!==-1&&$<=B)A=A.replace(G,"").replace(p,"").trim();return`${A}
11
-
12
- ${p}
13
- ${y}
14
- ${G}
15
- `}function Pu(u,y,B){let $=new Set,A=j(y);for(let J of u){if(!J||!J.trim())continue;if(J.startsWith("~")||J.startsWith("http"))continue;let K=t(J)?J:h(y,J),V=v(K),R=j(V);if(!R.startsWith(A+i)&&R!==A)continue;if(R===A)continue;let z=o(A,R);if(z.split(i).length>B)continue;if(Yy(z).split(i).some((H)=>Dy.has(H)))continue;if(!Cu(R))continue;$.add(R)}return $}function Tu(u,y,B){let $=new Map;for(let A of u){let J=[...A.filesModified,...A.filesRead],K=new Set;for(let V of J){if(!V)continue;let R=t(V)?V:h(B,V),z=j(v(R));if(y.has(z))K.add(z)}for(let V of K){let R=$.get(V)??[];R.push(A),$.set(V,R)}}return $}function pu(u,y,B){if(u.retentionDays===0)return;try{let $=y.deleteOlderThan(u.retentionDays),A=B.deleteCompletedOlderThan(u.retentionDays);if($>0||A>0)console.log(`[open-mem] Retention: deleted ${$} observations, ${A} pending messages`)}catch($){console.error("[open-mem] Retention enforcement error:",$)}}async function l(u,y,B){let{queue:$,sessions:A,projectPath:J,config:K,observations:V,pendingMessages:R}=u;switch(y){case"session.created":{if(B)A.getOrCreate(B,J);try{pu(K,V,R)}catch(z){console.error("[open-mem] Retention enforcement error:",z)}try{await Ty(J)}catch(z){console.error("[open-mem] Gitignore entry error:",z)}break}case"session.idle":{if($.processBatch().catch((z)=>{console.error("[open-mem] Background processing error:",z)}),B)A.updateStatus(B,"idle"),ju(B,J,K,V).catch((z)=>{console.error("[open-mem] Folder context error:",z)});break}case"session.completed":case"session.ended":{if(B)await $.processBatch(),await $.summarizeSession(B),A.markCompleted(B),await ju(B,J,K,V);break}}}async function ju(u,y,B,$){if(!B.folderContextEnabled)return;try{let A=$.getBySession(u);if(A.length>0)await Gu(y,A,{mode:B.folderContextMode,filename:B.folderContextFilename,maxDepth:B.folderContextMaxDepth})}catch(A){console.error("[open-mem] Folder context update error:",A)}}async function Ty(u){let y=Py(u,".gitignore");if(!Fy(y))return;let B=await Gy(y,"utf-8");if(B.includes("AGENTS.md"))return;let $=`
3
+ var E=import.meta.require;import{createInterface as jJ}from"readline";import{parseArgs as qJ}from"util";var h1=new Set(["127.0.0.1","::1","localhost"]);function g1($){return $.trim().toLowerCase()}function m1($){return h1.has(g1($))}function T$($,J){if(m1($))return;throw Error(`[open-mem] ${J} must bind to loopback only (127.0.0.1, ::1, localhost). Received "${$}".`)}var j$={name:"claude-code",version:"0.1",capabilities:{nativeSessionLifecycle:!0,nativeToolCapture:!0,nativeChatCapture:!0,emulatedIdleFlush:!0}},q$={name:"cursor",version:"0.1",capabilities:{nativeSessionLifecycle:!1,nativeToolCapture:!0,nativeChatCapture:!0,emulatedIdleFlush:!0}};function $$(){return new Date().toISOString()}function l($){if(!$||typeof $!=="object"||Array.isArray($))return null;return $}function C($){return typeof $==="string"&&$.trim().length>0?$:null}function d($,J){let V=l(J);if(!V)return null;let Z=C(V.kind),X=C(V.sessionId);if(!Z||!X)return null;if(Z==="session.start"||Z==="session.end"||Z==="idle.flush")return{kind:Z,platform:$,sessionId:X,occurredAt:C(V.occurredAt)??$$(),metadata:l(V.metadata)??void 0};if(Z==="chat.message"){let H=C(V.text);if(!H)return null;let K=C(V.role);return{kind:Z,platform:$,sessionId:X,text:H,role:K==="assistant"||K==="system"?K:"user",occurredAt:C(V.occurredAt)??$$(),metadata:l(V.metadata)??void 0}}if(Z==="tool.execute"){let H=C(V.toolName),K=C(V.output);if(!H||!K)return null;return{kind:Z,platform:$,sessionId:X,callId:C(V.callId)??`${$}-${Date.now()}`,toolName:H,output:K,occurredAt:C(V.occurredAt)??$$(),metadata:l(V.metadata)??void 0}}return null}function b1($){let J=$.type??$.event;if(!J)return null;if(J==="session.start")return"session.start";if(J==="session.end")return"session.end";if(J==="idle.flush")return"idle.flush";if(J==="tool.execute")return"tool.execute";if(J==="chat.message")return"chat.message";return null}class x${descriptor=j$;normalize($){if(!$||typeof $!=="object"||Array.isArray($))return null;let J=$,V=b1(J);if(!V||!J.sessionId)return null;return d("claude-code",{kind:V,sessionId:J.sessionId,callId:J.callId,toolName:J.toolName,output:J.output,role:J.role,text:J.text,occurredAt:J.occurredAt,metadata:J.metadata})}}function f$(){return new x$}function p1($){let J=$.eventName??$.event;if(!J)return null;if(J==="sessionStart")return"session.start";if(J==="sessionEnd")return"session.end";if(J==="idleFlush")return"idle.flush";if(J==="toolExecute")return"tool.execute";if(J==="chatMessage")return"chat.message";return null}class I${descriptor=q$;normalize($){if(!$||typeof $!=="object"||Array.isArray($))return null;let J=$,V=p1(J),Z=J.sessionId??J.session;if(!V||!Z)return null;return d("cursor",{kind:V,sessionId:Z,callId:J.callId??J.invocationId,toolName:J.toolName??J.tool,output:J.output,role:J.role,text:J.text??J.message,occurredAt:J.occurredAt??J.timestamp,metadata:J.metadata??J.meta})}}function u$(){return new I$}function n($,J=""){if(!$)return $;return $.replace(/<private>[\s\S]*?<\/private>/gi,J)}var w$=200,c1=/(\([\s\S]*[+*]\)\s*[+*?])|(\(\.\*\)\+)|(\(\.\+\)\+)/;function i($,J,V="[REDACTED]"){if(!$||J.length===0)return $;let Z=$;for(let X of J){if(X.length>w$){console.warn(`[open-mem] Skipping oversized redaction pattern (${X.length} chars, max ${w$})`);continue}if(c1.test(X)){console.warn("[open-mem] Skipping potentially dangerous redaction pattern (nested quantifiers detected)");continue}try{Z=Z.replace(new RegExp(X,"g"),V)}catch{}}return Z}var l1=20,P$=2000,v$=60;function d1($){let J=$.toLowerCase().replace(/[^a-z0-9\s-]/g," ").split(/\s+/).filter((V)=>V.length>4);return[...new Set(J)].slice(0,5)}function h$($){let{observations:J,sessions:V,projectPath:Z,sessionId:X,text:H,agent:K,sensitivePatterns:z=[]}=$;if(K!==void 0&&K!=="user")return!1;let B=i(n(H),z);if(B.length<l1)return!1;V.getOrCreate(X,Z);let Q=`User request: ${B.length>v$?`${B.slice(0,v$)}...`:B}`,U=B.length>P$?`${B.slice(0,P$)}...`:B;return J.create({sessionId:X,type:"discovery",title:Q,subtitle:"",facts:[],narrative:U,concepts:d1(B),filesRead:[],filesModified:[],rawToolOutput:"",toolName:"chat.message",tokenCount:Math.ceil(U.length/4),discoveryTokens:0,importance:3}),!0}import{existsSync as V0}from"fs";import{readFile as Z0,writeFile as X0}from"fs/promises";import{join as H0}from"path";import{existsSync as m$}from"fs";import{mkdir as n1,readFile as i1,rename as r1,unlink as s1,writeFile as o1}from"fs/promises";import{dirname as r,isAbsolute as Z$,join as h,normalize as t1,relative as X$,resolve as w,sep as J$}from"path";var u="<!-- open-mem-context -->",q="<!-- /open-mem-context -->",b$={bugfix:"\uD83D\uDD34",feature:"\uD83D\uDFE3",refactor:"\uD83D\uDD04",change:"\u2705",discovery:"\uD83D\uDD35",decision:"\u2696\uFE0F"},g$=new Map,a1=new Set(["node_modules",".git","dist","coverage",".open-mem","build","__pycache__",".next",".nuxt"]);async function p$($,J,V){if(J.length===0)return;if(V.mode==="single")return e1($,J,V);let{maxDepth:Z,filename:X}=V,H=[];for(let B of J){for(let Y of B.filesModified)H.push(Y);for(let Y of B.filesRead)H.push(Y)}let K=l$(H,$,Z);if(K.size===0)return;let z=d$(J,K,$);for(let[B,Y]of z)try{let Q=$0(B,Y,$);await c$(B,Q,X)}catch(Q){console.error(`[open-mem] Failed to update AGENTS.md in ${B}:`,Q)}}async function e1($,J,V){let{maxDepth:Z,filename:X}=V,H=J.filter(V$);if(H.length===0)return;let K=[];for(let W of H){for(let M of W.filesModified)K.push(M);for(let M of W.filesRead)K.push(M)}let z=l$(K,$,Z),B=d$(H,z,$),Y=H.filter((W)=>{return[...W.filesModified,...W.filesRead].some((D)=>{if(!D)return!1;let L=Z$(D)?D:h($,D);return w(r(L))===w($)})});if(Y.length>0)B.set(w($),Y);if(B.size===0)return;let Q=[];Q.push("## Project Activity (auto-generated by open-mem)"),Q.push("");let U=[...B.entries()].map(([W,M])=>({relPath:X$($,W)||".",observations:M})).sort((W,M)=>W.relPath.localeCompare(M.relPath));for(let{relPath:W,observations:M}of U){let D=M.filter(V$).sort((G,F)=>F.createdAt.localeCompare(G.createdAt)).slice(0,10);if(D.length===0)continue;Q.push(`### ${W}/`),Q.push("| ID | Type | Title | Date |"),Q.push("|----|------|-------|------|");for(let G of D){let F=b$[G.type]||"\uD83D\uDCDD",R=G.createdAt.split("T")[0],e=G.title.replace(/\|/g,"\\|");Q.push(`| ${G.id} | ${F} ${G.type} | ${e} | ${R} |`)}let L=new Set;for(let G of D)for(let F of G.concepts)L.add(F);if(L.size>0){let G=[...L].slice(0,10).join(", ");Q.push(""),Q.push(`**Key concepts:** ${G}`)}let _=D.filter((G)=>G.type==="decision").map((G)=>G.title);if(_.length>0)Q.push(""),Q.push(`**Recent decisions:** ${_.slice(0,5).join("; ")}`);Q.push("")}Q.push("\uD83D\uDCA1 *Use `mem-find` to search full details. Use `mem-create` to save important decisions.*");let A=Q.join(`
4
+ `);await c$($,A,X)}function V$($){return!/^\w[\w-]*\s+execution$/i.test($.title)}function $0($,J,V){let Z=[...J].filter(V$).sort((Y,Q)=>Q.createdAt.localeCompare(Y.createdAt)).slice(0,10),X=X$(V,$)||".",H=[];H.push(`## Recent Activity in \`${X}/\` (auto-generated by open-mem)`),H.push(""),H.push("| ID | Type | Title | Date |"),H.push("|----|------|-------|------|");for(let Y of Z){let Q=b$[Y.type]||"\uD83D\uDCDD",U=Y.createdAt.split("T")[0],A=Y.title.replace(/\|/g,"\\|");H.push(`| ${Y.id} | ${Q} ${Y.type} | ${A} | ${U} |`)}let K=new Set;for(let Y of Z)for(let Q of Y.concepts)K.add(Q);if(K.size>0){let Y=[...K].slice(0,10).join(", ");H.push(""),H.push(`**Key concepts:** ${Y}`)}let z=Z.filter((Y)=>Y.type==="decision").map((Y)=>Y.title);if(z.length>0)H.push(""),H.push(`**Recent decisions:** ${z.slice(0,5).join("; ")}`);let B=Z.filter((Y)=>Y.type==="decision"&&Y.narrative).slice(0,3);if(B.length>0){H.push(""),H.push("**Decision details:**");for(let Y of B){let Q=Y.narrative.split(/[.!?]\s/)[0],U=Q.length>120?`${Q.slice(0,117)}...`:Q;H.push(`- \u2696\uFE0F ${Y.title}: ${U}`)}}return H.push(""),H.push("\uD83D\uDCA1 *Use `mem-find` to search full details across all sessions. Use `mem-create` to save important decisions.*"),H.join(`
5
+ `)}async function c$($,J,V){if(!m$($))return;let X=(g$.get($)??Promise.resolve()).then(async()=>{let H=h($,V),K=h($,`.${V}.tmp`),z="";try{z=await i1(H,"utf-8")}catch{}let B=J0(z,J);try{await n1(r(K),{recursive:!0}),await o1(K,B,"utf-8"),await r1(K,H)}catch(Y){try{await s1(K)}catch{}throw Y}});return g$.set($,X.catch(()=>{})),X}function J0($,J){if(!$)return`${u}
6
+ ${J}
7
+ ${q}
8
+ `;let V=$.indexOf(u),Z=$.indexOf(q);if(V!==-1&&Z!==-1&&Z>V){let H=$.substring(0,V),K=$.substring(Z+q.length);return`${H}${u}
9
+ ${J}
10
+ ${q}${K}`}let X=$;if(V!==-1&&Z===-1)X=X.replace(u,"").trim();else if(V===-1&&Z!==-1)X=X.replace(q,"").trim();else if(V!==-1&&Z!==-1&&Z<=V)X=X.replace(q,"").replace(u,"").trim();return`${X}
11
+
12
+ ${u}
13
+ ${J}
14
+ ${q}
15
+ `}function l$($,J,V){let Z=new Set,X=w(J);for(let H of $){if(!H||!H.trim())continue;if(H.startsWith("~")||H.startsWith("http"))continue;let K=Z$(H)?H:h(J,H),z=r(K),B=w(z);if(!B.startsWith(X+J$)&&B!==X)continue;if(B===X)continue;let Y=X$(X,B);if(Y.split(J$).length>V)continue;if(t1(Y).split(J$).some((A)=>a1.has(A)))continue;if(!m$(B))continue;Z.add(B)}return Z}function d$($,J,V){let Z=new Map;for(let X of $){let H=[...X.filesModified,...X.filesRead],K=new Set;for(let z of H){if(!z)continue;let B=Z$(z)?z:h(V,z),Y=w(r(B));if(J.has(Y))K.add(Y)}for(let z of K){let B=Z.get(z)??[];B.push(X),Z.set(z,B)}}return Z}function n$($,J,V){if($.retentionDays===0)return;try{let Z=J.deleteOlderThan($.retentionDays),X=V.deleteCompletedOlderThan($.retentionDays);if(Z>0||X>0)console.log(`[open-mem] Retention: deleted ${Z} observations, ${X} pending messages`)}catch(Z){console.error("[open-mem] Retention enforcement error:",Z)}}async function s($,J,V){let{queue:Z,sessions:X,projectPath:H,config:K,observations:z,pendingMessages:B}=$;switch(J){case"session.created":{if(V)X.getOrCreate(V,H);try{n$(K,z,B)}catch(Y){console.error("[open-mem] Retention enforcement error:",Y)}try{await K0(H)}catch(Y){console.error("[open-mem] Gitignore entry error:",Y)}break}case"session.idle":{if(Z.processBatch().catch((Y)=>{console.error("[open-mem] Background processing error:",Y)}),V)X.updateStatus(V,"idle"),i$(V,H,K,z).catch((Y)=>{console.error("[open-mem] Folder context error:",Y)});break}case"session.completed":case"session.ended":{if(V)await Z.processBatch(),await Z.summarizeSession(V),X.markCompleted(V),await i$(V,H,K,z);break}}}async function i$($,J,V,Z){if(!V.folderContextEnabled)return;try{let X=Z.getBySession($);if(X.length>0)await p$(J,X,{mode:V.folderContextMode,filename:V.folderContextFilename,maxDepth:V.folderContextMaxDepth})}catch(X){console.error("[open-mem] Folder context update error:",X)}}async function K0($){let J=H0($,".gitignore");if(!V0(J))return;let V=await Z0(J,"utf-8");if(V.includes("AGENTS.md"))return;let Z=`
16
16
  # open-mem: Auto-generated folder context files.
17
17
  # Uncomment to exclude from version control (recommended for large projects):
18
18
  # **/AGENTS.md
19
- `;await Oy(y,B.endsWith(`
20
- `)?B+$:`${B}
21
- ${$}`,"utf-8")}function qu(u){let{config:y,queue:B,sessions:$,projectPath:A,tool:J,sessionId:K,callId:V,toolOutput:R}=u;if(y.ignoredTools.includes(J))return!1;if(!R||R.length<y.minOutputLength)return!1;let z=c(R,y.sensitivePatterns);return z=g(z,"[PRIVATE]"),$.getOrCreate(K,A),B.enqueue(K,J,z,V),!0}class e{adapter;lifecycleDeps;queue;sessions;observations;projectPath;config;constructor(u){this.adapter=u.adapter,this.queue=u.queue,this.sessions=u.sessions,this.observations=u.observations,this.projectPath=u.projectPath,this.config=u.config,this.lifecycleDeps={queue:u.queue,sessions:u.sessions,projectPath:u.projectPath,config:u.config,observations:u.observations,pendingMessages:u.pendingMessages}}platform(){return this.adapter.descriptor.name}normalize(u){return this.adapter.normalize(u)}async ingestRaw(u){let y=this.normalize(u);if(!y)return!1;return await this.ingestNormalized(y),!0}async ingestNormalized(u){switch(u.kind){case"session.start":await l(this.lifecycleDeps,"session.created",u.sessionId);return;case"session.end":await l(this.lifecycleDeps,"session.ended",u.sessionId);return;case"idle.flush":await l(this.lifecycleDeps,"session.idle",u.sessionId);return;case"tool.execute":qu({config:this.config,queue:this.queue,sessions:this.sessions,projectPath:this.projectPath,tool:u.toolName,sessionId:u.sessionId,callId:u.callId,toolOutput:u.output});return;case"chat.message":mu({observations:this.observations,sessions:this.sessions,projectPath:this.projectPath,sessionId:u.sessionId,text:u.text,agent:u.role==="user"?"user":u.role,sensitivePatterns:this.config.sensitivePatterns});return}}}import{generateText as cy}from"ai";function m(u){if(typeof u!=="object"||u===null)return!1;let y=u,B=y.status;if(B===429||B===500||B===503)return!0;let $=y.error;if(typeof $==="object"&&$!==null&&$.type==="overloaded_error")return!0;return!1}function x(u){if(u&&typeof u==="object"){let y=u.status;if(typeof y==="number")return y===400||y===401||y===403}return!1}function O(u){return new Promise((y)=>setTimeout(y,u))}var py=new Set(["decision","bugfix","feature","refactor","discovery","change"]);function W(u,y){let B=new RegExp(`<${y}[^>]*>([\\s\\S]*?)</${y}>`,"i"),$=u.match(B);return $?$[1].trim():""}function X(u,y){let B=new RegExp(`<${y}[^>]*>([\\s\\S]*?)</${y}>`,"gi"),$=[];for(let A of u.matchAll(B)){let J=A[1].trim();if(J)$.push(J)}return $}function hu(u){let y=W(u,"observation");if(!y)return null;let B=W(y,"type").toLowerCase(),$=py.has(B)?B:"discovery",A=W(y,"title")||"Untitled observation",J=W(y,"subtitle"),K=W(y,"narrative"),V=X(W(y,"facts"),"fact"),R=X(W(y,"concepts"),"concept"),z=X(W(y,"files_read"),"file"),N=X(W(y,"files_modified"),"file"),E=W(y,"importance"),H=Number.parseInt(E,10),Q=Number.isNaN(H)?3:Math.max(1,Math.min(5,H));return{type:$,title:A,subtitle:J,facts:V,narrative:K,concepts:R,filesRead:z,filesModified:N,importance:Q}}function xu(u){let y=W(u,"session_summary");if(!y)return null;let B=W(y,"summary")||"No summary available",$=X(W(y,"key_decisions"),"decision"),A=X(W(y,"files_modified"),"file"),J=X(W(y,"concepts"),"concept"),K=W(y,"request")||void 0,V=W(y,"investigated")||void 0,R=W(y,"learned")||void 0,z=W(y,"completed")||void 0,N=W(y,"next_steps")||void 0;return{summary:B,keyDecisions:$,filesModified:A,concepts:J,request:K,investigated:V,learned:R,completed:z,nextSteps:N}}var jy=new Set(["new_fact","update","duplicate"]);function wu(u){let y=W(u,"evaluation");if(!y)return null;let B=W(y,"outcome").toLowerCase().trim();if(!jy.has(B))return null;let $=B,A=W(y,"reason");if(!A)return null;let J=W(y,"supersedes"),K={outcome:$,reason:A};if($==="update"&&J)K.supersedesId=J;if($==="update"&&!K.supersedesId)return null;return K}var qy=new Set(["technology","library","pattern","concept","file","person","project","other"]),hy=new Set(["uses","depends_on","implements","extends","related_to","replaces","configures"]);function Iu(u){let y=W(u,"extraction");if(!y)return null;let B=W(y,"entities"),$=W(y,"relations"),A=X(B,"entity"),J=[];for(let R of A){let z=W(R,"name");if(!z)continue;let N=W(R,"type").toLowerCase(),E=qy.has(N)?N:"other";J.push({name:z,entityType:E})}let K=X($,"relation"),V=[];for(let R of K){let z=W(R,"source"),N=W(R,"target"),E=W(R,"relationship").toLowerCase();if(!z||!N||!E)continue;if(!hy.has(E))continue;V.push({sourceName:z,targetName:N,relationship:E})}return{entities:J,relations:V}}function P(u){return Math.ceil(u.length/4)}function nu(u,y,B,$){let A=B?`<session_context>
22
- ${B}
19
+ `;await X0(J,V.endsWith(`
20
+ `)?V+Z:`${V}
21
+ ${Z}`,"utf-8")}function r$($){let{config:J,queue:V,sessions:Z,projectPath:X,tool:H,sessionId:K,callId:z,toolOutput:B}=$;if(J.ignoredTools.includes(H))return!1;if(!B||B.length<J.minOutputLength)return!1;let Y=i(B,J.sensitivePatterns);return Y=n(Y,"[PRIVATE]"),Z.getOrCreate(K,X),V.enqueue(K,H,Y,z),!0}class H${adapter;lifecycleDeps;queue;sessions;observations;projectPath;config;constructor($){this.adapter=$.adapter,this.queue=$.queue,this.sessions=$.sessions,this.observations=$.observations,this.projectPath=$.projectPath,this.config=$.config,this.lifecycleDeps={queue:$.queue,sessions:$.sessions,projectPath:$.projectPath,config:$.config,observations:$.observations,pendingMessages:$.pendingMessages}}platform(){return this.adapter.descriptor.name}normalize($){return this.adapter.normalize($)}async ingestRaw($){let J=this.normalize($);if(!J)return!1;return await this.ingestNormalized(J),!0}async ingestNormalized($){switch($.kind){case"session.start":await s(this.lifecycleDeps,"session.created",$.sessionId);return;case"session.end":await s(this.lifecycleDeps,"session.ended",$.sessionId);return;case"idle.flush":await s(this.lifecycleDeps,"session.idle",$.sessionId);return;case"tool.execute":r$({config:this.config,queue:this.queue,sessions:this.sessions,projectPath:this.projectPath,tool:$.toolName,sessionId:$.sessionId,callId:$.callId,toolOutput:$.output});return;case"chat.message":h$({observations:this.observations,sessions:this.sessions,projectPath:this.projectPath,sessionId:$.sessionId,text:$.text,agent:$.role==="user"?"user":$.role,sensitivePatterns:this.config.sensitivePatterns});return}}}import{generateText as F0}from"ai";function S($){if(typeof $!=="object"||$===null)return!1;let J=$,V=J.status;if(V===429||V===500||V===503)return!0;let Z=J.error;if(typeof Z==="object"&&Z!==null&&Z.type==="overloaded_error")return!0;return!1}function g($){if($&&typeof $==="object"){let J=$.status;if(typeof J==="number")return J===400||J===401||J===403}return!1}function x($){return new Promise((J)=>setTimeout(J,$))}var Y0=new Set(["decision","bugfix","feature","refactor","discovery","change"]);function N($,J){let V=new RegExp(`<${J}[^>]*>([\\s\\S]*?)</${J}>`,"i"),Z=$.match(V);return Z?Z[1].trim():""}function O($,J){let V=new RegExp(`<${J}[^>]*>([\\s\\S]*?)</${J}>`,"gi"),Z=[];for(let X of $.matchAll(V)){let H=X[1].trim();if(H)Z.push(H)}return Z}function s$($){let J=N($,"observation");if(!J)return null;let V=N(J,"type").toLowerCase(),Z=Y0.has(V)?V:"discovery",X=N(J,"title")||"Untitled observation",H=N(J,"subtitle"),K=N(J,"narrative"),z=O(N(J,"facts"),"fact"),B=O(N(J,"concepts"),"concept"),Y=O(N(J,"files_read"),"file"),Q=O(N(J,"files_modified"),"file"),U=N(J,"importance"),A=Number.parseInt(U,10),W=Number.isNaN(A)?3:Math.max(1,Math.min(5,A));return{type:Z,title:X,subtitle:H,facts:z,narrative:K,concepts:B,filesRead:Y,filesModified:Q,importance:W}}function o$($){let J=N($,"session_summary");if(!J)return null;let V=N(J,"summary")||"No summary available",Z=O(N(J,"key_decisions"),"decision"),X=O(N(J,"files_modified"),"file"),H=O(N(J,"concepts"),"concept"),K=N(J,"request")||void 0,z=N(J,"investigated")||void 0,B=N(J,"learned")||void 0,Y=N(J,"completed")||void 0,Q=N(J,"next_steps")||void 0;return{summary:V,keyDecisions:Z,filesModified:X,concepts:H,request:K,investigated:z,learned:B,completed:Y,nextSteps:Q}}var z0=new Set(["new_fact","update","duplicate"]);function t$($){let J=N($,"evaluation");if(!J)return null;let V=N(J,"outcome").toLowerCase().trim();if(!z0.has(V))return null;let Z=V,X=N(J,"reason");if(!X)return null;let H=N(J,"supersedes"),K={outcome:Z,reason:X};if(Z==="update"&&H)K.supersedesId=H;if(Z==="update"&&!K.supersedesId)return null;return K}var B0=new Set(["technology","library","pattern","concept","file","person","project","other"]),Q0=new Set(["uses","depends_on","implements","extends","related_to","replaces","configures"]);function a$($){let J=N($,"extraction");if(!J)return null;let V=N(J,"entities"),Z=N(J,"relations"),X=O(V,"entity"),H=[];for(let B of X){let Y=N(B,"name");if(!Y)continue;let Q=N(B,"type").toLowerCase(),U=B0.has(Q)?Q:"other";H.push({name:Y,entityType:U})}let K=O(Z,"relation"),z=[];for(let B of K){let Y=N(B,"source"),Q=N(B,"target"),U=N(B,"relationship").toLowerCase();if(!Y||!Q||!U)continue;if(!Q0.has(U))continue;z.push({sourceName:Y,targetName:Q,relationship:U})}return{entities:H,relations:z}}function f($){return Math.ceil($.length/4)}function e$($,J,V,Z){let X=V?`<session_context>
22
+ ${V}
23
23
  </session_context>
24
24
 
25
- `:"",J=$?$.observationTypes.join("|"):"decision|bugfix|feature|refactor|discovery|change",V=($?$.conceptVocabulary:["how-it-works","why-it-exists","what-changed","problem-solution","gotcha","pattern","trade-off"]).map((R)=>{let N={"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"}[R];return N?`- ${R}: ${N}`:`- ${R}`}).join(`
25
+ `:"",H=Z?Z.observationTypes.join("|"):"decision|bugfix|feature|refactor|discovery|change",z=(Z?Z.conceptVocabulary:["how-it-works","why-it-exists","what-changed","problem-solution","gotcha","pattern","trade-off"]).map((B)=>{let Q={"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"}[B];return Q?`- ${B}: ${Q}`:`- ${B}`}).join(`
26
26
  `);return`<task>
27
27
  Analyze the following tool output and extract a structured observation.
28
28
  </task>
29
29
 
30
- <tool_name>${u}</tool_name>
30
+ <tool_name>${$}</tool_name>
31
31
 
32
32
  <tool_output>
33
- ${y}
33
+ ${J}
34
34
  </tool_output>
35
35
 
36
- ${A}<instructions>
36
+ ${X}<instructions>
37
37
  Extract a structured observation from the tool output. Determine the most appropriate type and provide a concise but informative summary.
38
38
 
39
39
  When extracting concepts, prefer established vocabulary where appropriate:
40
- ${V}
40
+ ${z}
41
41
  You may also use any domain-specific concepts relevant to the observation.
42
42
 
43
43
  Respond with EXACTLY this XML format:
44
44
  <observation>
45
- <type>${J}</type>
45
+ <type>${H}</type>
46
46
  <title>Brief descriptive title (max 80 chars)</title>
47
47
  <subtitle>One-line elaboration</subtitle>
48
48
  <importance>1-5 (1=trivial/routine, 2=low, 3=normal, 4=significant, 5=critical decision or discovery)</importance>
@@ -62,18 +62,18 @@ Respond with EXACTLY this XML format:
62
62
  <file>path/to/file/modified</file>
63
63
  </files_modified>
64
64
  </observation>
65
- </instructions>`}function gu(u,y){let B=u.map(($,A)=>` <obs index="${A+1}" type="${$.type}">
66
- <title>${$.title}</title>
67
- <narrative>${$.narrative}</narrative>
65
+ </instructions>`}function $1($,J){let V=$.map((Z,X)=>` <obs index="${X+1}" type="${Z.type}">
66
+ <title>${Z.title}</title>
67
+ <narrative>${Z.narrative}</narrative>
68
68
  </obs>`).join(`
69
69
  `);return`<task>
70
70
  Summarize the following coding session based on its observations.
71
71
  </task>
72
72
 
73
- <session_id>${y}</session_id>
73
+ <session_id>${J}</session_id>
74
74
 
75
75
  <observations>
76
- ${B}
76
+ ${V}
77
77
  </observations>
78
78
 
79
79
  <instructions>
@@ -97,21 +97,21 @@ Respond with EXACTLY this XML format:
97
97
  <concept>key-concept</concept>
98
98
  </concepts>
99
99
  </session_summary>
100
- </instructions>`}function cu(u,y){let B=y.map(($)=>` <candidate id="${$.id}">
101
- <title>${$.title}</title>
102
- <narrative>${$.narrative}</narrative>
103
- <concepts>${$.concepts.join(", ")}</concepts>
104
- <type>${$.type}</type>
100
+ </instructions>`}function J1($,J){let V=J.map((Z)=>` <candidate id="${Z.id}">
101
+ <title>${Z.title}</title>
102
+ <narrative>${Z.narrative}</narrative>
103
+ <concepts>${Z.concepts.join(", ")}</concepts>
104
+ <type>${Z.type}</type>
105
105
  </candidate>`).join(`
106
106
  `);return`<conflict_evaluation>
107
107
  <new_observation>
108
- <title>${u.title}</title>
109
- <narrative>${u.narrative}</narrative>
110
- <concepts>${u.concepts.join(", ")}</concepts>
111
- <type>${u.type}</type>
108
+ <title>${$.title}</title>
109
+ <narrative>${$.narrative}</narrative>
110
+ <concepts>${$.concepts.join(", ")}</concepts>
111
+ <type>${$.type}</type>
112
112
  </new_observation>
113
113
  <existing_candidates>
114
- ${B}
114
+ ${V}
115
115
  </existing_candidates>
116
116
  <instructions>
117
117
  Evaluate whether the new observation represents:
@@ -126,22 +126,22 @@ Respond with EXACTLY this XML format:
126
126
  <reason>Brief explanation</reason>
127
127
  </evaluation>
128
128
  </instructions>
129
- </conflict_evaluation>`}function vu(u,y){let B=[...u.filesRead,...u.filesModified],$=y?y.entityTypes.join(", "):"technology, library, pattern, concept, file, person, project, other",A=y?y.relationshipTypes.join(", "):"uses, depends_on, implements, extends, related_to, replaces, configures";return`<entity_extraction>
129
+ </conflict_evaluation>`}function V1($,J){let V=[...$.filesRead,...$.filesModified],Z=J?J.entityTypes.join(", "):"technology, library, pattern, concept, file, person, project, other",X=J?J.relationshipTypes.join(", "):"uses, depends_on, implements, extends, related_to, replaces, configures";return`<entity_extraction>
130
130
  <observation>
131
- <title>${u.title}</title>
132
- <type>${u.type}</type>
133
- <narrative>${u.narrative}</narrative>
134
- <facts>${u.facts.join(`
131
+ <title>${$.title}</title>
132
+ <type>${$.type}</type>
133
+ <narrative>${$.narrative}</narrative>
134
+ <facts>${$.facts.join(`
135
135
  `)}</facts>
136
- <files>${B.join(`
136
+ <files>${V.join(`
137
137
  `)}</files>
138
- <concepts>${u.concepts.join(", ")}</concepts>
138
+ <concepts>${$.concepts.join(", ")}</concepts>
139
139
  </observation>
140
140
  <instructions>
141
141
  Extract entities and relationships from this observation.
142
142
 
143
- Entity types: ${$}
144
- Relationship types: ${A}
143
+ Entity types: ${Z}
144
+ Relationship types: ${X}
145
145
 
146
146
  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.
147
147
  Respond with EXACTLY this XML format:
@@ -155,102 +155,103 @@ Respond with EXACTLY this XML format:
155
155
  </relations>
156
156
  </extraction>
157
157
  </instructions>
158
- </entity_extraction>`}class a{shouldFailover(u){let{error:y,attemptIndex:B,totalProviders:$}=u;if(x(y))return!1;if(B>=$-1)return!1;return m(y)}onFailover(u){let y=u.error?.status??"unknown";if(!u.nextProvider)return;console.error(`[open-mem] Provider ${u.provider} failed (${y}), falling over to ${u.nextProvider}`)}}class uu{specificationVersion;provider;modelId;supportedUrls;providers;policy;constructor(u,y=new a){if(u.length===0)throw Error("At least one provider required");let B=u[0].model;this.specificationVersion=B.specificationVersion,this.provider=B.provider,this.modelId=B.modelId,this.supportedUrls=B.supportedUrls,this.providers=u,this.policy=y}async doGenerate(u){let y;for(let B=0;B<this.providers.length;B++){let $=this.providers[B];try{return this.policy.onAttempt?.({error:null,provider:$.name,nextProvider:this.providers[B+1]?.name,attemptIndex:B,totalProviders:this.providers.length}),await $.model.doGenerate(u)}catch(A){if(y=A,x(A))throw A;let J=this.providers[B+1]?.name,K={error:A,provider:$.name,nextProvider:J,attemptIndex:B,totalProviders:this.providers.length};if(this.policy.shouldFailover(K)){this.policy.onFailover(K);continue}throw this.policy.onFinalFailure?.(K),A}}throw y}async doStream(u){let y;for(let B=0;B<this.providers.length;B++){let $=this.providers[B];try{return this.policy.onAttempt?.({error:null,provider:$.name,nextProvider:this.providers[B+1]?.name,attemptIndex:B,totalProviders:this.providers.length}),await $.model.doStream(u)}catch(A){if(y=A,x(A))throw A;let J=this.providers[B+1]?.name,K={error:A,provider:$.name,nextProvider:J,attemptIndex:B,totalProviders:this.providers.length};if(this.policy.shouldFailover(K)){this.policy.onFailover(K);continue}throw this.policy.onFinalFailure?.(K),A}}throw y}}var xy={"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 wy(u){if(u.includes("."))return u;return xy[u]||`us.anthropic.${u}-v1:0`}function lu(u){switch(u.provider){case"anthropic":{let{createAnthropic:y}=D("@ai-sdk/anthropic");return y({apiKey:u.apiKey})(u.model)}case"bedrock":{let{createAmazonBedrock:y}=D("@ai-sdk/amazon-bedrock");return y()(wy(u.model))}case"openai":{let{createOpenAI:y}=D("@ai-sdk/openai");return y({apiKey:u.apiKey})(u.model)}case"google":{let{createGoogleGenerativeAI:y}=D("@ai-sdk/google");return y({apiKey:u.apiKey})(u.model)}case"openrouter":{let{createOpenRouter:y}=D("@openrouter/ai-sdk-provider");return y({apiKey:u.apiKey})(u.model)}default:throw Error(`Unknown provider: ${u.provider}. Supported: anthropic, bedrock, openai, google, openrouter`)}}function bu(u){try{switch(u.provider){case"google":{let{createGoogleGenerativeAI:y}=D("@ai-sdk/google");return y({apiKey:u.apiKey}).embedding("text-embedding-004")}case"openai":{let{createOpenAI:y}=D("@ai-sdk/openai");return y({apiKey:u.apiKey}).embedding("text-embedding-3-small")}case"bedrock":{let{createAmazonBedrock:y}=D("@ai-sdk/amazon-bedrock");return y().embedding("amazon.titan-embed-text-v2:0")}case"anthropic":return null;case"openrouter":return null;default:return null}}catch{return null}}var Iy={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 ny(u){switch(u){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 _(u){if(!u.fallbackProviders||u.fallbackProviders.length===0)return[];return u.fallbackProviders.map((y)=>({provider:y,model:Iy[y]??"gemini-2.5-flash-lite",apiKey:ny(y)}))}function C(u,y=[],B){let $=lu(u);if(y.length===0)return $;let A=[{name:u.provider,model:$},...y.map((J)=>({name:J.provider,model:lu(J)}))];return new uu(A,B)}var gy={"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},ru=0;async function F(u,y){if(!y)return;let B=gy[u]||5,$=Math.ceil(60000/B)+100,J=Date.now()-ru;if(J<$){let K=$-J;await new Promise((V)=>setTimeout(V,K))}ru=Date.now()}class w{model;config;_generate=cy;constructor(u){this.config=u,this.model=null;let y=u.provider!=="bedrock";if(u.compressionEnabled&&(!y||u.apiKey))try{this.model=C({provider:u.provider,model:u.model,apiKey:u.apiKey},_(u))}catch{}}static MAX_INPUT_LENGTH=50000;async compress(u,y,B){if(!this.config.compressionEnabled||!this.model)return null;if(y.length<this.config.minOutputLength)return null;let $=P(y),A=y.length>w.MAX_INPUT_LENGTH?`${y.substring(0,w.MAX_INPUT_LENGTH)}
158
+ </entity_extraction>`}class K${shouldFailover($){let{error:J,attemptIndex:V,totalProviders:Z}=$;if(g(J))return!1;if(V>=Z-1)return!1;return S(J)}onFailover($){let J=$.error?.status??"unknown";if(!$.nextProvider)return;console.error(`[open-mem] Provider ${$.provider} failed (${J}), falling over to ${$.nextProvider}`)}}class Y${specificationVersion;provider;modelId;supportedUrls;providers;policy;constructor($,J=new K$){if($.length===0)throw Error("At least one provider required");let V=$[0].model;this.specificationVersion=V.specificationVersion,this.provider=V.provider,this.modelId=V.modelId,this.supportedUrls=V.supportedUrls,this.providers=$,this.policy=J}async doGenerate($){let J;for(let V=0;V<this.providers.length;V++){let Z=this.providers[V];try{return this.policy.onAttempt?.({error:null,provider:Z.name,nextProvider:this.providers[V+1]?.name,attemptIndex:V,totalProviders:this.providers.length}),await Z.model.doGenerate($)}catch(X){if(J=X,g(X))throw X;let H=this.providers[V+1]?.name,K={error:X,provider:Z.name,nextProvider:H,attemptIndex:V,totalProviders:this.providers.length};if(this.policy.shouldFailover(K)){this.policy.onFailover(K);continue}throw this.policy.onFinalFailure?.(K),X}}throw J}async doStream($){let J;for(let V=0;V<this.providers.length;V++){let Z=this.providers[V];try{return this.policy.onAttempt?.({error:null,provider:Z.name,nextProvider:this.providers[V+1]?.name,attemptIndex:V,totalProviders:this.providers.length}),await Z.model.doStream($)}catch(X){if(J=X,g(X))throw X;let H=this.providers[V+1]?.name,K={error:X,provider:Z.name,nextProvider:H,attemptIndex:V,totalProviders:this.providers.length};if(this.policy.shouldFailover(K)){this.policy.onFailover(K);continue}throw this.policy.onFinalFailure?.(K),X}}throw J}}var U0={"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 W0($){if($.includes("."))return $;return U0[$]||`us.anthropic.${$}-v1:0`}function Z1($){switch($.provider){case"anthropic":{let{createAnthropic:J}=E("@ai-sdk/anthropic");return J({apiKey:$.apiKey})($.model)}case"bedrock":{let{createAmazonBedrock:J}=E("@ai-sdk/amazon-bedrock");return J()(W0($.model))}case"openai":{let{createOpenAI:J}=E("@ai-sdk/openai");return J({apiKey:$.apiKey})($.model)}case"google":{let{createGoogleGenerativeAI:J}=E("@ai-sdk/google");return J({apiKey:$.apiKey})($.model)}case"openrouter":{let{createOpenRouter:J}=E("@openrouter/ai-sdk-provider");return J({apiKey:$.apiKey})($.model)}default:throw Error(`Unknown provider: ${$.provider}. Supported: anthropic, bedrock, openai, google, openrouter`)}}function X1($){try{switch($.provider){case"google":{let{createGoogleGenerativeAI:J}=E("@ai-sdk/google");return J({apiKey:$.apiKey}).embedding("text-embedding-004")}case"openai":{let{createOpenAI:J}=E("@ai-sdk/openai");return J({apiKey:$.apiKey}).embedding("text-embedding-3-small")}case"bedrock":{let{createAmazonBedrock:J}=E("@ai-sdk/amazon-bedrock");return J().embedding("amazon.titan-embed-text-v2:0")}case"anthropic":return null;case"openrouter":return null;default:return null}}catch{return null}}var A0={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 N0($){switch($){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 k($){if(!$.fallbackProviders||$.fallbackProviders.length===0)return[];return $.fallbackProviders.map((J)=>({provider:J,model:A0[J]??"gemini-2.5-flash-lite",apiKey:N0(J)}))}function T($,J=[],V){let Z=Z1($);if(J.length===0)return Z;let X=[{name:$.provider,model:Z},...J.map((H)=>({name:H.provider,model:Z1(H)}))];return new Y$(X,V)}var G0={"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},H1=0;async function j($,J){if(!J)return;let V=G0[$]||5,Z=Math.ceil(60000/V)+100,H=Date.now()-H1;if(H<Z){let K=Z-H;await new Promise((z)=>setTimeout(z,K))}H1=Date.now()}class m{model;config;_generate=F0;constructor($){this.config=$,this.model=null;let J=$.provider!=="bedrock";if($.compressionEnabled&&(!J||$.apiKey))try{this.model=T({provider:$.provider,model:$.model,apiKey:$.apiKey},k($))}catch{}}static MAX_INPUT_LENGTH=50000;async compress($,J,V){if(!this.config.compressionEnabled||!this.model)return null;if(J.length<this.config.minOutputLength)return null;let Z=f(J),X=J.length>m.MAX_INPUT_LENGTH?`${J.substring(0,m.MAX_INPUT_LENGTH)}
159
159
 
160
- [... truncated ...]`:y,J=nu(u,A,B),K=2;for(let V=0;V<=K;V++)try{if(this.config.provider==="google")await F(this.config.model,this.config.rateLimitingEnabled);let{text:R}=await this._generate({model:this.model,maxOutputTokens:this.config.maxTokensPerCompression,prompt:J}),z=hu(R);if(z)z.discoveryTokens=$;return z}catch(R){if(m(R)&&V<K){let z=2**V*1000;await O(z);continue}return null}return null}async compressBatch(u){let y=new Map;for(let B=0;B<u.length;B++){let $=u[B],A=await this.compress($.toolName,$.toolOutput,$.sessionContext);if(y.set($.callId,A),B<u.length-1)await O(200)}return y}createFallbackObservation(u,y){let B=by(y),$=vy[u]??"discovery";return{type:$,title:`${u} execution`,subtitle:y.substring(0,100).replace(/\n/g," "),facts:[],narrative:`Tool ${u} was executed. Output length: ${y.length} chars.`,concepts:[],filesRead:$==="discovery"?B:[],filesModified:$==="change"?B:[],discoveryTokens:P(y),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 vy={Read:"discovery",Write:"change",Edit:"change",Bash:"change",Glob:"discovery",Grep:"discovery"},ly=/(?:^|\s)((?:\.\/|\/|src\/|tests\/|lib\/)\S+\.\w+)/gm;function by(u){let y=[];for(let B of u.matchAll(ly))y.push(B[1]);return[...new Set(y)]}import{generateText as ry}from"ai";class yu{model;config;_generate=ry;constructor(u){if(this.config=u,this.model=null,u.provider==="bedrock"||u.apiKey)try{this.model=C({provider:u.provider,model:u.model,apiKey:u.apiKey},_(u))}catch{}}async evaluate(u,y){if(!this.model||y.length===0)return null;let B=cu(u,y),$=2;for(let A=0;A<=$;A++)try{if(this.config.provider==="google")await F(this.config.model,this.config.rateLimitingEnabled);let{text:J}=await this._generate({model:this.model,maxOutputTokens:512,prompt:B});return wu(J)}catch(J){if(m(J)&&A<$){let K=2**A*1000;await O(K);continue}return null}return null}}import{generateText as dy}from"ai";class Bu{model;config;_generate=dy;constructor(u){if(this.config=u,this.model=null,u.provider==="bedrock"||u.apiKey)try{this.model=C({provider:u.provider,model:u.model,apiKey:u.apiKey},_(u))}catch{}}async extract(u){if(!this.model)return null;let y=vu(u),B=2;for(let $=0;$<=B;$++)try{if(this.config.provider==="google")await F(this.config.model,this.config.rateLimitingEnabled);let{text:A}=await this._generate({model:this.model,maxOutputTokens:1024,prompt:y});return Iu(A)}catch(A){if(m(A)&&$<B){let J=2**$*1000;await O(J);continue}return null}return null}}import{generateText as iy}from"ai";class $u{model;config;_generate=iy;constructor(u){this.config=u,this.model=null;let y=u.provider!=="bedrock";if(u.compressionEnabled&&(!y||u.apiKey))try{this.model=C({provider:u.provider,model:u.model,apiKey:u.apiKey},_(u))}catch{}}async summarize(u,y){if(y.length===0)return null;if(!this.config.compressionEnabled||!this.model)return this.createFallbackSummary(y);let B=gu(y.map(($)=>({type:$.type,title:$.title,narrative:$.narrative})),u);try{if(this.config.provider==="google")await F(this.config.model,this.config.rateLimitingEnabled);let{text:$}=await this._generate({model:this.model,maxOutputTokens:this.config.maxTokensPerCompression,prompt:B}),A=xu($);if(!A)return this.createFallbackSummary(y);return A}catch{return this.createFallbackSummary(y)}}createFallbackSummary(u){let y=new Set,B=new Set,$=[];for(let V of u){for(let R of V.filesModified)y.add(R);for(let R of V.concepts)B.add(R);if(V.type==="decision")$.push(V.title)}let A=new Map;for(let V of u)A.set(V.type,(A.get(V.type)??0)+1);let J=Array.from(A.entries()).map(([V,R])=>`${R} ${V}${R>1?"s":""}`).join(", "),K=Array.from(B).slice(0,5).join(", ");return{summary:`Session with ${u.length} observations: ${J}. Files modified: ${y.size}. Key concepts: ${K}.`,keyDecisions:$.slice(0,5),filesModified:Array.from(y),concepts:Array.from(B)}}shouldSummarize(u){return u>=2}}import{existsSync as J0,readFileSync as K0}from"fs";import{join as y0}from"path";import{existsSync as sy,readdirSync as ty,readFileSync as oy}from"fs";import{join as ey}from"path";var q={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"]};function T(u){return{...u,observationTypes:[...u.observationTypes],conceptVocabulary:[...u.conceptVocabulary],entityTypes:[...u.entityTypes],relationshipTypes:[...u.relationshipTypes],promptOverrides:u.promptOverrides?{...u.promptOverrides}:void 0}}function ay(u){if(!u||typeof u!=="object")return!1;let y=u,B=(A)=>Array.isArray(A)&&A.every((J)=>typeof J==="string"),$=(A)=>typeof A==="object"&&A!==null&&!Array.isArray(A)&&Object.values(A).every((J)=>typeof J==="string");return typeof y.id==="string"&&(y.extends===void 0||typeof y.extends==="string")&&(y.locale===void 0||typeof y.locale==="string")&&(y.name===void 0||typeof y.name==="string")&&(y.description===void 0||typeof y.description==="string")&&(y.observationTypes===void 0||B(y.observationTypes))&&(y.conceptVocabulary===void 0||B(y.conceptVocabulary))&&(y.entityTypes===void 0||B(y.entityTypes))&&(y.relationshipTypes===void 0||B(y.relationshipTypes))&&(y.promptOverrides===void 0||$(y.promptOverrides))}function u0(u){return typeof u.name==="string"&&typeof u.description==="string"&&Array.isArray(u.observationTypes)&&Array.isArray(u.conceptVocabulary)&&Array.isArray(u.entityTypes)&&Array.isArray(u.relationshipTypes)}function du(u,y){return{...u,...y,id:y.id,name:y.name??u.name,description:y.description??u.description,observationTypes:y.observationTypes??u.observationTypes,conceptVocabulary:y.conceptVocabulary??u.conceptVocabulary,entityTypes:y.entityTypes??u.entityTypes,relationshipTypes:y.relationshipTypes??u.relationshipTypes,promptOverrides:{...u.promptOverrides??{},...y.promptOverrides??{}}}}class Au{modesDir;constructor(u){this.modesDir=u}loadAllRaw(){let u=new Map;if(!sy(this.modesDir))return u;for(let y of ty(this.modesDir)){if(!y.endsWith(".json"))continue;let B=ey(this.modesDir,y);try{let $=oy(B,"utf-8"),A=JSON.parse($);if(!ay(A))continue;if(u.has(A.id))console.warn(`[open-mem] Duplicate mode id "${A.id}" in ${B}; overriding previous definition.`);u.set(A.id,A)}catch{}}return u}resolveById(u,y){let B=new Set,$=!1,A=(K)=>{if(B.has(K))return $=!0,T(q);B.add(K);let V=y.get(K);if(!V)return T(q);if(!V.extends){if(!u0(V))return T(q);return du(T(q),V)}let R=A(V.extends);if($)return T(q);return du(R,V)},J=A(u);return $?T(q):T(J)}}var B0=y0(import.meta.dir,"."),$0=new Au(B0),b=null;function A0(){if(b)return b;return b=$0.loadAllRaw(),b}function iu(){return[...A0().keys()].sort()}var z0={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"};function R0(){let u={};if(process.env.OPEN_MEM_DB_PATH)u.dbPath=process.env.OPEN_MEM_DB_PATH;if(process.env.OPEN_MEM_PROVIDER)u.provider=process.env.OPEN_MEM_PROVIDER;if(process.env.OPEN_MEM_MODEL)u.model=process.env.OPEN_MEM_MODEL;if(process.env.OPEN_MEM_MAX_CONTEXT_TOKENS)u.maxContextTokens=Number.parseInt(process.env.OPEN_MEM_MAX_CONTEXT_TOKENS,10);if(process.env.OPEN_MEM_COMPRESSION==="false")u.compressionEnabled=!1;if(process.env.OPEN_MEM_CONTEXT_INJECTION==="false")u.contextInjectionEnabled=!1;if(process.env.OPEN_MEM_IGNORED_TOOLS)u.ignoredTools=process.env.OPEN_MEM_IGNORED_TOOLS.split(",").map((y)=>y.trim());if(process.env.OPEN_MEM_BATCH_SIZE)u.batchSize=Number.parseInt(process.env.OPEN_MEM_BATCH_SIZE,10);if(process.env.OPEN_MEM_RETENTION_DAYS)u.retentionDays=Number.parseInt(process.env.OPEN_MEM_RETENTION_DAYS,10);if(process.env.OPEN_MEM_LOG_LEVEL)u.logLevel=process.env.OPEN_MEM_LOG_LEVEL;if(process.env.OPEN_MEM_CONTEXT_SHOW_TOKEN_COSTS==="false")u.contextShowTokenCosts=!1;if(process.env.OPEN_MEM_CONTEXT_TYPES)u.contextObservationTypes=process.env.OPEN_MEM_CONTEXT_TYPES==="all"?"all":process.env.OPEN_MEM_CONTEXT_TYPES.split(",").map((y)=>y.trim());if(process.env.OPEN_MEM_CONTEXT_FULL_COUNT)u.contextFullObservationCount=Number.parseInt(process.env.OPEN_MEM_CONTEXT_FULL_COUNT,10);if(process.env.OPEN_MEM_MAX_OBSERVATIONS)u.maxObservations=Number.parseInt(process.env.OPEN_MEM_MAX_OBSERVATIONS,10);if(process.env.OPEN_MEM_CONTEXT_SHOW_LAST_SUMMARY==="false")u.contextShowLastSummary=!1;if(process.env.OPEN_MEM_RATE_LIMITING==="false")u.rateLimitingEnabled=!1;if(process.env.OPEN_MEM_FOLDER_CONTEXT==="false")u.folderContextEnabled=!1;if(process.env.OPEN_MEM_FOLDER_CONTEXT_MAX_DEPTH)u.folderContextMaxDepth=Number.parseInt(process.env.OPEN_MEM_FOLDER_CONTEXT_MAX_DEPTH,10);if(process.env.OPEN_MEM_FOLDER_CONTEXT_MODE==="single")u.folderContextMode="single";if(process.env.OPEN_MEM_FOLDER_CONTEXT_MODE==="dispersed")u.folderContextMode="dispersed";if(process.env.OPEN_MEM_FOLDER_CONTEXT_FILENAME)u.folderContextFilename=process.env.OPEN_MEM_FOLDER_CONTEXT_FILENAME;if(process.env.OPEN_MEM_DAEMON==="true")u.daemonEnabled=!0;if(process.env.OPEN_MEM_DASHBOARD==="true")u.dashboardEnabled=!0;if(process.env.OPEN_MEM_DASHBOARD_PORT)u.dashboardPort=Number.parseInt(process.env.OPEN_MEM_DASHBOARD_PORT,10);if(process.env.OPEN_MEM_PLATFORM_OPENCODE==="false")u.platformOpenCodeEnabled=!1;if(process.env.OPEN_MEM_PLATFORM_CLAUDE_CODE==="true")u.platformClaudeCodeEnabled=!0;if(process.env.OPEN_MEM_PLATFORM_CURSOR==="true")u.platformCursorEnabled=!0;if(process.env.OPEN_MEM_MCP_PROTOCOL_VERSION)u.mcpProtocolVersion=process.env.OPEN_MEM_MCP_PROTOCOL_VERSION;if(process.env.OPEN_MEM_MCP_SUPPORTED_PROTOCOLS)u.mcpSupportedProtocolVersions=process.env.OPEN_MEM_MCP_SUPPORTED_PROTOCOLS.split(",").map((y)=>y.trim()).filter(Boolean);if(process.env.OPEN_MEM_EMBEDDING_DIMENSION)u.embeddingDimension=Number.parseInt(process.env.OPEN_MEM_EMBEDDING_DIMENSION,10);if(process.env.OPEN_MEM_CONFLICT_RESOLUTION==="true")u.conflictResolutionEnabled=!0;if(process.env.OPEN_MEM_CONFLICT_BAND_LOW){let y=Number.parseFloat(process.env.OPEN_MEM_CONFLICT_BAND_LOW);if(!Number.isNaN(y))u.conflictSimilarityBandLow=y}if(process.env.OPEN_MEM_CONFLICT_BAND_HIGH){let y=Number.parseFloat(process.env.OPEN_MEM_CONFLICT_BAND_HIGH);if(!Number.isNaN(y))u.conflictSimilarityBandHigh=y}if(process.env.OPEN_MEM_USER_MEMORY==="true")u.userMemoryEnabled=!0;if(process.env.OPEN_MEM_USER_MEMORY_DB_PATH)u.userMemoryDbPath=process.env.OPEN_MEM_USER_MEMORY_DB_PATH;if(process.env.OPEN_MEM_USER_MEMORY_MAX_TOKENS)u.userMemoryMaxContextTokens=Number.parseInt(process.env.OPEN_MEM_USER_MEMORY_MAX_TOKENS,10);if(process.env.OPEN_MEM_RERANKING==="true")u.rerankingEnabled=!0;if(process.env.OPEN_MEM_RERANKING_MAX_CANDIDATES)u.rerankingMaxCandidates=Number.parseInt(process.env.OPEN_MEM_RERANKING_MAX_CANDIDATES,10);if(process.env.OPEN_MEM_ENTITY_EXTRACTION==="true")u.entityExtractionEnabled=!0;if(process.env.OPEN_MEM_FALLBACK_PROVIDERS)u.fallbackProviders=process.env.OPEN_MEM_FALLBACK_PROVIDERS.split(",").map((y)=>y.trim()).filter(Boolean);if(process.env.OPEN_MEM_MODE)u.mode=process.env.OPEN_MEM_MODE;return u}function V0(u){let y=`${u}/.open-mem/config.json`;if(!J0(y))return{};try{let B=K0(y,"utf-8"),$=JSON.parse(B);if(!$||typeof $!=="object"||Array.isArray($))return{};return $}catch{return{}}}function N0(u){switch(u){case"google":return 768;case"openai":return 1536;case"bedrock":return 1024;case"anthropic":return 0;case"openrouter":return 0;default:return 768}}function su(u,y){let B=V0(u),$=R0(),A={...z0,...B,...$,...y};if(!A.dbPath.startsWith("/"))A.dbPath=`${u}/${A.dbPath}`;if(!process.env.OPEN_MEM_PROVIDER&&!y?.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=N0(A.provider);if(A.mode&&!iu().includes(A.mode))A.mode="code";return A}import{Database as tu}from"bun:sqlite";import{existsSync as Ju,mkdirSync as E0,unlinkSync as ou}from"fs";import*as eu from"sqlite-vec";class r{db;dbPath;_hasVectorExtension=!1;static enableExtensionSupport(){let u=["/opt/homebrew/opt/sqlite/lib/libsqlite3.dylib","/usr/local/opt/sqlite/lib/libsqlite3.dylib"];for(let y of u)try{if(Ju(y))return tu.setCustomSQLite(y),!0}catch{return!1}return!1}constructor(u){this.dbPath=u,this.db=this.open(u),this.configure()}open(u){let y=u.lastIndexOf("/");if(y>0){let B=u.substring(0,y);E0(B,{recursive:!0})}return new tu(u,{create:!0})}configure(){try{this.applyPragmas(),this.loadExtensions()}catch(u){console.warn("[open-mem] Database configure failed, attempting recovery by removing WAL/SHM files:",u.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(y){console.warn("[open-mem] WAL/SHM cleanup insufficient, recreating database from scratch:",y.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(B){throw console.warn("[open-mem] All recovery attempts failed, filesystem may be broken:",B.message),u}}}}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{eu.load(this.db),this._hasVectorExtension=!0}catch{this._hasVectorExtension=!1}}get hasVectorExtension(){return this._hasVectorExtension}deleteSidecarFiles(){for(let u of["-wal","-shm"]){let y=this.dbPath+u;try{if(Ju(y))ou(y)}catch{}}}deleteDatabaseFiles(){this.deleteSidecarFiles();try{if(Ju(this.dbPath))ou(this.dbPath)}catch{}}ensureMigrationTable(){this.db.exec(`
160
+ [... truncated ...]`:J,H=e$($,X,V),K=2;for(let z=0;z<=K;z++)try{if(this.config.provider==="google")await j(this.config.model,this.config.rateLimitingEnabled);let{text:B}=await this._generate({model:this.model,maxOutputTokens:this.config.maxTokensPerCompression,prompt:H}),Y=s$(B);if(Y)Y.discoveryTokens=Z;return Y}catch(B){if(S(B)&&z<K){let Y=2**z*1000;await x(Y);continue}return null}return null}async compressBatch($){let J=new Map;for(let V=0;V<$.length;V++){let Z=$[V],X=await this.compress(Z.toolName,Z.toolOutput,Z.sessionContext);if(J.set(Z.callId,X),V<$.length-1)await x(200)}return J}createFallbackObservation($,J){let V=L0(J),Z=M0[$]??"discovery";return{type:Z,title:`${$} execution`,subtitle:J.substring(0,100).replace(/\n/g," "),facts:[],narrative:`Tool ${$} was executed. Output length: ${J.length} chars.`,concepts:[],filesRead:Z==="discovery"?V:[],filesModified:Z==="change"?V:[],discoveryTokens:f(J),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 M0={Read:"discovery",Write:"change",Edit:"change",Bash:"change",Glob:"discovery",Grep:"discovery"},D0=/(?:^|\s)((?:\.\/|\/|src\/|tests\/|lib\/)\S+\.\w+)/gm;function L0($){let J=[];for(let V of $.matchAll(D0))J.push(V[1]);return[...new Set(J)]}import{generateText as _0}from"ai";class z${model;config;_generate=_0;constructor($){if(this.config=$,this.model=null,$.provider==="bedrock"||$.apiKey)try{this.model=T({provider:$.provider,model:$.model,apiKey:$.apiKey},k($))}catch{}}async evaluate($,J){if(!this.model||J.length===0)return null;let V=J1($,J),Z=2;for(let X=0;X<=Z;X++)try{if(this.config.provider==="google")await j(this.config.model,this.config.rateLimitingEnabled);let{text:H}=await this._generate({model:this.model,maxOutputTokens:512,prompt:V});return t$(H)}catch(H){if(S(H)&&X<Z){let K=2**X*1000;await x(K);continue}return null}return null}}import{generateText as R0}from"ai";class B${model;config;_generate=R0;constructor($){if(this.config=$,this.model=null,$.provider==="bedrock"||$.apiKey)try{this.model=T({provider:$.provider,model:$.model,apiKey:$.apiKey},k($))}catch{}}async extract($){if(!this.model)return null;let J=V1($),V=2;for(let Z=0;Z<=V;Z++)try{if(this.config.provider==="google")await j(this.config.model,this.config.rateLimitingEnabled);let{text:X}=await this._generate({model:this.model,maxOutputTokens:1024,prompt:J});return a$(X)}catch(X){if(S(X)&&Z<V){let H=2**Z*1000;await x(H);continue}return null}return null}}import{generateText as C0}from"ai";class Q${model;config;_generate=C0;constructor($){this.config=$,this.model=null;let J=$.provider!=="bedrock";if($.compressionEnabled&&(!J||$.apiKey))try{this.model=T({provider:$.provider,model:$.model,apiKey:$.apiKey},k($))}catch{}}async summarize($,J){if(J.length===0)return null;if(!this.config.compressionEnabled||!this.model)return this.createFallbackSummary(J);let V=$1(J.map((Z)=>({type:Z.type,title:Z.title,narrative:Z.narrative})),$);try{if(this.config.provider==="google")await j(this.config.model,this.config.rateLimitingEnabled);let{text:Z}=await this._generate({model:this.model,maxOutputTokens:this.config.maxTokensPerCompression,prompt:V}),X=o$(Z);if(!X)return this.createFallbackSummary(J);return X}catch{return this.createFallbackSummary(J)}}createFallbackSummary($){let J=new Set,V=new Set,Z=[];for(let z of $){for(let B of z.filesModified)J.add(B);for(let B of z.concepts)V.add(B);if(z.type==="decision")Z.push(z.title)}let X=new Map;for(let z of $)X.set(z.type,(X.get(z.type)??0)+1);let H=Array.from(X.entries()).map(([z,B])=>`${B} ${z}${B>1?"s":""}`).join(", "),K=Array.from(V).slice(0,5).join(", ");return{summary:`Session with ${$.length} observations: ${H}. Files modified: ${J.size}. Key concepts: ${K}.`,keyDecisions:Z.slice(0,5),filesModified:Array.from(J),concepts:Array.from(V)}}shouldSummarize($){return $>=2}}import{existsSync as I0,readFileSync as u0}from"fs";import{join as j0}from"path";import{existsSync as y0,readdirSync as O0,readFileSync as E0}from"fs";import{join as S0}from"path";var P={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"]};function I($){return{...$,observationTypes:[...$.observationTypes],conceptVocabulary:[...$.conceptVocabulary],entityTypes:[...$.entityTypes],relationshipTypes:[...$.relationshipTypes],promptOverrides:$.promptOverrides?{...$.promptOverrides}:void 0}}function k0($){if(!$||typeof $!=="object")return!1;let J=$,V=(X)=>Array.isArray(X)&&X.every((H)=>typeof H==="string"),Z=(X)=>typeof X==="object"&&X!==null&&!Array.isArray(X)&&Object.values(X).every((H)=>typeof H==="string");return typeof J.id==="string"&&(J.extends===void 0||typeof J.extends==="string")&&(J.locale===void 0||typeof J.locale==="string")&&(J.name===void 0||typeof J.name==="string")&&(J.description===void 0||typeof J.description==="string")&&(J.observationTypes===void 0||V(J.observationTypes))&&(J.conceptVocabulary===void 0||V(J.conceptVocabulary))&&(J.entityTypes===void 0||V(J.entityTypes))&&(J.relationshipTypes===void 0||V(J.relationshipTypes))&&(J.promptOverrides===void 0||Z(J.promptOverrides))}function T0($){return typeof $.name==="string"&&typeof $.description==="string"&&Array.isArray($.observationTypes)&&Array.isArray($.conceptVocabulary)&&Array.isArray($.entityTypes)&&Array.isArray($.relationshipTypes)}function K1($,J){return{...$,...J,id:J.id,name:J.name??$.name,description:J.description??$.description,observationTypes:J.observationTypes??$.observationTypes,conceptVocabulary:J.conceptVocabulary??$.conceptVocabulary,entityTypes:J.entityTypes??$.entityTypes,relationshipTypes:J.relationshipTypes??$.relationshipTypes,promptOverrides:{...$.promptOverrides??{},...J.promptOverrides??{}}}}class U${modesDir;constructor($){this.modesDir=$}loadAllRaw(){let $=new Map;if(!y0(this.modesDir))return $;for(let J of O0(this.modesDir)){if(!J.endsWith(".json"))continue;let V=S0(this.modesDir,J);try{let Z=E0(V,"utf-8"),X=JSON.parse(Z);if(!k0(X))continue;if($.has(X.id))console.warn(`[open-mem] Duplicate mode id "${X.id}" in ${V}; overriding previous definition.`);$.set(X.id,X)}catch{}}return $}resolveById($,J){let V=new Set,Z=!1,X=(K)=>{if(V.has(K))return Z=!0,I(P);V.add(K);let z=J.get(K);if(!z)return I(P);if(!z.extends){if(!T0(z))return I(P);return K1(I(P),z)}let B=X(z.extends);if(Z)return I(P);return K1(B,z)},H=X($);return Z?I(P):I(H)}}var q0=j0(import.meta.dir,"."),x0=new U$(q0),o=null;function f0(){if(o)return o;return o=x0.loadAllRaw(),o}function Y1(){return[...f0().keys()].sort()}var w0={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"};function P0(){let $={};if(process.env.OPEN_MEM_DB_PATH)$.dbPath=process.env.OPEN_MEM_DB_PATH;if(process.env.OPEN_MEM_PROVIDER)$.provider=process.env.OPEN_MEM_PROVIDER;if(process.env.OPEN_MEM_MODEL)$.model=process.env.OPEN_MEM_MODEL;if(process.env.OPEN_MEM_MAX_CONTEXT_TOKENS)$.maxContextTokens=Number.parseInt(process.env.OPEN_MEM_MAX_CONTEXT_TOKENS,10);if(process.env.OPEN_MEM_COMPRESSION==="false")$.compressionEnabled=!1;if(process.env.OPEN_MEM_CONTEXT_INJECTION==="false")$.contextInjectionEnabled=!1;if(process.env.OPEN_MEM_IGNORED_TOOLS)$.ignoredTools=process.env.OPEN_MEM_IGNORED_TOOLS.split(",").map((J)=>J.trim());if(process.env.OPEN_MEM_BATCH_SIZE)$.batchSize=Number.parseInt(process.env.OPEN_MEM_BATCH_SIZE,10);if(process.env.OPEN_MEM_RETENTION_DAYS)$.retentionDays=Number.parseInt(process.env.OPEN_MEM_RETENTION_DAYS,10);if(process.env.OPEN_MEM_LOG_LEVEL)$.logLevel=process.env.OPEN_MEM_LOG_LEVEL;if(process.env.OPEN_MEM_CONTEXT_SHOW_TOKEN_COSTS==="false")$.contextShowTokenCosts=!1;if(process.env.OPEN_MEM_CONTEXT_TYPES)$.contextObservationTypes=process.env.OPEN_MEM_CONTEXT_TYPES==="all"?"all":process.env.OPEN_MEM_CONTEXT_TYPES.split(",").map((J)=>J.trim());if(process.env.OPEN_MEM_CONTEXT_FULL_COUNT)$.contextFullObservationCount=Number.parseInt(process.env.OPEN_MEM_CONTEXT_FULL_COUNT,10);if(process.env.OPEN_MEM_MAX_OBSERVATIONS)$.maxObservations=Number.parseInt(process.env.OPEN_MEM_MAX_OBSERVATIONS,10);if(process.env.OPEN_MEM_CONTEXT_SHOW_LAST_SUMMARY==="false")$.contextShowLastSummary=!1;if(process.env.OPEN_MEM_RATE_LIMITING==="false")$.rateLimitingEnabled=!1;if(process.env.OPEN_MEM_FOLDER_CONTEXT==="false")$.folderContextEnabled=!1;if(process.env.OPEN_MEM_FOLDER_CONTEXT_MAX_DEPTH)$.folderContextMaxDepth=Number.parseInt(process.env.OPEN_MEM_FOLDER_CONTEXT_MAX_DEPTH,10);if(process.env.OPEN_MEM_FOLDER_CONTEXT_MODE==="single")$.folderContextMode="single";if(process.env.OPEN_MEM_FOLDER_CONTEXT_MODE==="dispersed")$.folderContextMode="dispersed";if(process.env.OPEN_MEM_FOLDER_CONTEXT_FILENAME)$.folderContextFilename=process.env.OPEN_MEM_FOLDER_CONTEXT_FILENAME;if(process.env.OPEN_MEM_DAEMON==="true")$.daemonEnabled=!0;if(process.env.OPEN_MEM_DASHBOARD==="true")$.dashboardEnabled=!0;if(process.env.OPEN_MEM_DASHBOARD_PORT)$.dashboardPort=Number.parseInt(process.env.OPEN_MEM_DASHBOARD_PORT,10);if(process.env.OPEN_MEM_PLATFORM_OPENCODE==="false")$.platformOpenCodeEnabled=!1;if(process.env.OPEN_MEM_PLATFORM_CLAUDE_CODE==="true")$.platformClaudeCodeEnabled=!0;if(process.env.OPEN_MEM_PLATFORM_CURSOR==="true")$.platformCursorEnabled=!0;if(process.env.OPEN_MEM_MCP_PROTOCOL_VERSION)$.mcpProtocolVersion=process.env.OPEN_MEM_MCP_PROTOCOL_VERSION;if(process.env.OPEN_MEM_MCP_SUPPORTED_PROTOCOLS)$.mcpSupportedProtocolVersions=process.env.OPEN_MEM_MCP_SUPPORTED_PROTOCOLS.split(",").map((J)=>J.trim()).filter(Boolean);if(process.env.OPEN_MEM_EMBEDDING_DIMENSION)$.embeddingDimension=Number.parseInt(process.env.OPEN_MEM_EMBEDDING_DIMENSION,10);if(process.env.OPEN_MEM_CONFLICT_RESOLUTION==="true")$.conflictResolutionEnabled=!0;if(process.env.OPEN_MEM_CONFLICT_BAND_LOW){let J=Number.parseFloat(process.env.OPEN_MEM_CONFLICT_BAND_LOW);if(!Number.isNaN(J))$.conflictSimilarityBandLow=J}if(process.env.OPEN_MEM_CONFLICT_BAND_HIGH){let J=Number.parseFloat(process.env.OPEN_MEM_CONFLICT_BAND_HIGH);if(!Number.isNaN(J))$.conflictSimilarityBandHigh=J}if(process.env.OPEN_MEM_USER_MEMORY==="true")$.userMemoryEnabled=!0;if(process.env.OPEN_MEM_USER_MEMORY_DB_PATH)$.userMemoryDbPath=process.env.OPEN_MEM_USER_MEMORY_DB_PATH;if(process.env.OPEN_MEM_USER_MEMORY_MAX_TOKENS)$.userMemoryMaxContextTokens=Number.parseInt(process.env.OPEN_MEM_USER_MEMORY_MAX_TOKENS,10);if(process.env.OPEN_MEM_RERANKING==="true")$.rerankingEnabled=!0;if(process.env.OPEN_MEM_RERANKING_MAX_CANDIDATES)$.rerankingMaxCandidates=Number.parseInt(process.env.OPEN_MEM_RERANKING_MAX_CANDIDATES,10);if(process.env.OPEN_MEM_ENTITY_EXTRACTION==="true")$.entityExtractionEnabled=!0;if(process.env.OPEN_MEM_FALLBACK_PROVIDERS)$.fallbackProviders=process.env.OPEN_MEM_FALLBACK_PROVIDERS.split(",").map((J)=>J.trim()).filter(Boolean);if(process.env.OPEN_MEM_MODE)$.mode=process.env.OPEN_MEM_MODE;return $}function v0($){let J=`${$}/.open-mem/config.json`;if(!I0(J))return{};try{let V=u0(J,"utf-8"),Z=JSON.parse(V);if(!Z||typeof Z!=="object"||Array.isArray(Z))return{};return Z}catch{return{}}}function h0($){switch($){case"google":return 768;case"openai":return 1536;case"bedrock":return 1024;case"anthropic":return 0;case"openrouter":return 0;default:return 768}}function z1($,J){let V=v0($),Z=P0(),X={...w0,...V,...Z,...J};if(!X.dbPath.startsWith("/"))X.dbPath=`${$}/${X.dbPath}`;if(!process.env.OPEN_MEM_PROVIDER&&!J?.provider){if(process.env.GOOGLE_GENERATIVE_AI_API_KEY||process.env.GEMINI_API_KEY)X.provider="google";else if(process.env.ANTHROPIC_API_KEY)X.provider="anthropic";else if(process.env.AWS_BEARER_TOKEN_BEDROCK||process.env.AWS_ACCESS_KEY_ID||process.env.AWS_PROFILE)X.provider="bedrock";else if(process.env.OPENROUTER_API_KEY)X.provider="openrouter"}if(!X.apiKey)switch(X.provider){case"google":X.apiKey=process.env.GOOGLE_GENERATIVE_AI_API_KEY||process.env.GEMINI_API_KEY;break;case"anthropic":X.apiKey=process.env.ANTHROPIC_API_KEY;break;case"openai":X.apiKey=process.env.OPENAI_API_KEY;break;case"openrouter":X.apiKey=process.env.OPENROUTER_API_KEY;break;case"bedrock":break}if(X.provider==="openrouter"&&X.model==="gemini-2.5-flash-lite")X.model="google/gemini-2.5-flash-lite";if(X.embeddingDimension===void 0)X.embeddingDimension=h0(X.provider);if(X.mode&&!Y1().includes(X.mode))X.mode="code";return X}import{existsSync as i0}from"fs";import{existsSync as g0}from"fs";import{homedir as m0}from"os";import{join as B1}from"path";function b0(){let $=[],J=process.env.BUN_INSTALL;if(J)$.push(B1(J,"bin","bun"));let V=m0();return $.push(B1(V,".bun","bin","bun")),$.push("/usr/local/bin/bun"),$.push("/opt/homebrew/bin/bun"),$.push("/home/linuxbrew/.linuxbrew/bin/bun"),$}function p0(){let $=Bun.which("bun");if($)return $;for(let J of b0())if(g0(J))return console.debug(`[open-mem] Resolved bun path via candidate scan: ${J}`),J;return"bun"}var W$=null;function Q1(){if(W$===null)W$=p0();return W$}import{existsSync as c0,mkdirSync as l0,readFileSync as d0,unlinkSync as U1,writeFileSync as n0}from"fs";function W1($){let J=$.lastIndexOf("/");if(J>0){let V=$.substring(0,J);l0(V,{recursive:!0})}n0($,String(process.pid),"utf-8")}function b($){if(!c0($))return null;let J=d0($,"utf-8").trim(),V=Number.parseInt(J,10);if(Number.isNaN(V))return null;return V}function p($){try{return process.kill($,0),!0}catch(J){if(J instanceof Error&&"code"in J&&J.code==="EPERM")return!0;return!1}}function A1($,J){let V=b($);if(V===null)return{state:"missing",pid:null,stalePid:null,stalePidRemoved:!1};if(p(V))return{state:"alive",pid:V,stalePid:null,stalePidRemoved:!1};if(!J)return{state:"dead",pid:null,stalePid:V,stalePidRemoved:!1};let Z=A$($,V);return{state:"dead",pid:null,stalePid:V,stalePidRemoved:Z}}function N1($){try{U1($)}catch{}}function A$($,J){let V=b($);if(V===null||V!==J)return!1;try{return U1($),!0}catch{return!1}}function G1($){let J=$.lastIndexOf("/");if(J>=0)return`${$.substring(0,J)}/worker.pid`;return"worker.pid"}function F1($,J){let V=$.lastIndexOf("/");return`${V>=0?$.substring(0,V):"."}/platform-worker-${J}.pid`}var r0=100,s0=2000;class N${pidPath;projectPath;daemonScript;subprocess=null;constructor($){this.pidPath=G1($.dbPath),this.projectPath=$.projectPath,this.daemonScript=$.daemonScript}start(){if(this.isRunning())return!1;this.subprocess=Bun.spawn([Q1(),"run",this.daemonScript,"--project",this.projectPath],{detached:!0,stdio:["ignore","ignore","ignore"],ipc(J){}}),this.subprocess.unref();let $=Date.now()+s0;while(Date.now()<$)if(Bun.sleepSync(r0),i0(this.pidPath)){let J=b(this.pidPath);if(J!==null&&p(J))return!0}return!1}signal($){let J=()=>{try{return this.getStatus()}catch{return null}};try{if(this.subprocess)return this.subprocess.send($),{ok:!0,state:"delivered",via:"ipc",pid:J()?.pid??null,message:$};if($!=="PROCESS_NOW")return{ok:!1,state:"unsupported-signal",via:"none",pid:null,message:$};let V=this.getStatus();if(V.state==="missing")return{ok:!1,state:"no-daemon",via:"none",pid:null,message:$};if(V.state==="dead")return{ok:!1,state:"daemon-dead",via:"none",pid:V.stalePid,message:$};if(V.pid!==null)return process.kill(V.pid,"SIGUSR1"),{ok:!0,state:"delivered",via:"os-signal",pid:V.pid,message:$};return{ok:!1,state:"delivery-failed",via:"none",pid:null,message:$,error:"Daemon was reported running but did not expose a PID"}}catch(V){return{ok:!1,state:"delivery-failed",via:"none",pid:J()?.pid??null,message:$,error:String(V)}}}stop(){let $=b(this.pidPath);if($!==null)try{process.kill($,"SIGTERM")}catch{}this.subprocess=null,N1(this.pidPath)}isRunning(){return this.getStatus().running}getStatus(){return o0(this.pidPath,!0)}}function o0($,J){let V=A1($,J);if(V.state==="missing")return{state:"missing",running:!1,pid:null,stalePid:null,stalePidRemoved:!1};if(V.state==="dead")return{state:"dead",running:!1,pid:null,stalePid:V.stalePid,stalePidRemoved:V.stalePidRemoved};return{state:"running",running:!0,pid:V.pid,stalePid:null,stalePidRemoved:!1}}import{Database as O1}from"bun:sqlite";import{existsSync as zJ,mkdirSync as BJ}from"fs";import*as S1 from"sqlite-vec";import{closeSync as t0,fsyncSync as a0,openSync as e0,readFileSync as $J,unlinkSync as D1,writeFileSync as JJ}from"fs";import{hostname as L1}from"os";var _1="plugin";class t extends Error{lockPath;role;waitDurationMs;owner;constructor($){super(`Timed out acquiring advisory write lock after ${$.waitDurationMs}ms (role=${$.role}, lockPath=${$.lockPath})`);this.name="AdvisoryLockTimeoutError",this.lockPath=$.lockPath,this.role=$.role,this.waitDurationMs=$.waitDurationMs,this.owner=$.owner}}var VJ=5000,ZJ=50,v=new Map;function XJ($){if($<=0)return;Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,$)}function M1($,J){if(typeof $!=="number"||!Number.isFinite($)||$<=0)return J;return Math.floor($)}function R1($){try{let J=$J($,"utf8").trim();if(!J)return null;let V=JSON.parse(J);if(typeof V!=="object"||V===null||typeof V.pid!=="number"||typeof V.role!=="string"||typeof V.hostname!=="string"||typeof V.acquiredAt!=="string")return null;return{pid:V.pid,role:V.role,hostname:V.hostname,acquiredAt:V.acquiredAt,ownerId:typeof V.ownerId==="string"?V.ownerId:void 0}}catch{return null}}function HJ($,J){if(!$||!J)return!1;return $.pid===J.pid&&$.role===J.role&&$.hostname===J.hostname&&$.acquiredAt===J.acquiredAt&&$.ownerId===J.ownerId}function KJ($,J){if(!J)return!1;if(J.hostname!==L1())return!1;if(p(J.pid))return!1;let V=R1($);if(!HJ(V,J))return!1;try{return D1($),!0}catch(Z){if(Z.code==="ENOENT")return!1;throw Z}}function G$($,J){t0(J);try{D1($)}catch(V){if(V.code!=="ENOENT")throw V}}function C1($){return`${$}.write.lock`}function YJ($,J){let V=J.now??Date.now,Z=M1(J.timeoutMs,VJ),X=M1(J.retryIntervalMs,ZJ),H=v.get($);if(H){H.count+=1;let Y=!1;return{lockPath:$,role:J.role,waitDurationMs:0,reentrant:!0,release:()=>{if(Y)return;Y=!0;let Q=v.get($);if(!Q)return;if(Q.count-=1,Q.count===0)v.delete($),G$($,Q.fd)}}}let K={pid:process.pid,role:J.role,hostname:L1(),acquiredAt:new Date(V()).toISOString(),ownerId:J.ownerId},z=V(),B=null;for(;;)try{let Y=e0($,"wx");try{JJ(Y,JSON.stringify(K),"utf8"),a0(Y)}catch(U){throw G$($,Y),U}v.set($,{count:1,fd:Y});let Q=!1;return{lockPath:$,role:J.role,waitDurationMs:V()-z,reentrant:!1,release:()=>{if(Q)return;Q=!0;let U=v.get($);if(!U)return;if(U.count-=1,U.count===0)v.delete($),G$($,U.fd)}}}catch(Y){if(Y.code!=="EEXIST")throw Y;if(B=R1($),KJ($,B))continue;let U=V()-z;if(U>=Z)throw new t({lockPath:$,role:J.role,waitDurationMs:U,owner:B});XJ(Math.min(X,Z-U))}}function y1($,J,V){let Z=YJ($,J);try{return V()}finally{Z.release()}}var QJ=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"]),UJ=3,E1=50,WJ=new Set(["INSERT","UPDATE","DELETE","REPLACE","CREATE","ALTER","DROP","VACUUM","REINDEX","ANALYZE","ATTACH","DETACH"]),AJ=new Set(["WAL_CHECKPOINT","OPTIMIZE","INCREMENTAL_VACUUM","SHRINK_MEMORY"]),NJ=/^(?:\s+|--[^\n]*(?:\n|$)|\/\*[\s\S]*?\*\/)+/;function GJ($){let J=$;for(;;){let V=J.replace(NJ,"");if(V===J)return J.trimStart();J=V}}function FJ($){let J=[],V=0,Z=!1,X=!1,H=!1,K=!1,z=!1,B=!1;for(let Q=0;Q<$.length;Q+=1){let U=$[Q],A=$[Q+1];if(z){if(U===`
161
+ `)z=!1;continue}if(B){if(U==="*"&&A==="/")B=!1,Q+=1;continue}if(Z){if(U==="'")if(A==="'")Q+=1;else Z=!1;continue}if(X){if(U==='"')if(A==='"')Q+=1;else X=!1;continue}if(H){if(U==="`")H=!1;continue}if(K){if(U==="]")K=!1;continue}if(U==="-"&&A==="-"){z=!0,Q+=1;continue}if(U==="/"&&A==="*"){B=!0,Q+=1;continue}if(U==="'"){Z=!0;continue}if(U==='"'){X=!0;continue}if(U==="`"){H=!0;continue}if(U==="["){K=!0;continue}if(U===";"){let W=$.slice(V,Q).trim();if(W.length>0)J.push(W);V=Q+1}}let Y=$.slice(V).trim();if(Y.length>0)J.push(Y);return J}function MJ($){let J=GJ($);if(!J)return!1;let V=J.toUpperCase();if(/\bRETURNING\b/.test(V))return!0;if(V.startsWith("PRAGMA")){if(/^PRAGMA\s+(?:[A-Z0-9_]+\.)?[A-Z0-9_]+\s*=/.test(V))return!0;let X=/^PRAGMA\s+(?:[A-Z0-9_]+\.)?([A-Z0-9_]+)/.exec(V)?.[1];if(!X)return!1;return AJ.has(X)}let Z=/^[A-Z]+/.exec(V)?.[0];if(!Z)return!1;if(WJ.has(Z))return!0;if(Z==="WITH")return/\b(INSERT|UPDATE|DELETE|REPLACE)\b/.test(V);return!1}function F$($){let J=FJ($);if(J.length===0)return!1;for(let V of J)if(MJ(V))return!0;return!1}var DJ=new Set(["PASSIVE","FULL","RESTART","TRUNCATE"]);function c($){if($ instanceof Error){let J=$.code;return{code:typeof J==="string"?J:"UNKNOWN",message:$.message}}return{code:"UNKNOWN",message:String($)}}function LJ($){if($&&typeof $==="object"&&"code"in $){let J=$.code;return QJ.has(J)}return!1}class a{db;dbPath;advisoryWriteLockPath;processRole;transactionDepth=0;_hasVectorExtension=!1;static enableExtensionSupport(){let $=["/opt/homebrew/opt/sqlite/lib/libsqlite3.dylib","/usr/local/opt/sqlite/lib/libsqlite3.dylib"];for(let J of $)try{if(zJ(J))return O1.setCustomSQLite(J),!0}catch{return!1}return!1}constructor($,J={}){this.dbPath=$,this.processRole=J.processRole??_1,this.advisoryWriteLockPath=C1($),this.db=this.open($),this.configure()}open($){let J=$.lastIndexOf("/");if(J>0){let V=$.substring(0,J);BJ(V,{recursive:!0})}return new O1($,{create:!0})}configure(){this.runConfigureStage("applyPragmas",()=>this.applyPragmas()),this.runConfigureStage("loadExtensions",()=>this.loadExtensions())}runConfigureStage($,J){try{J()}catch(V){this.throwConfigureFailure($,V)}}throwConfigureFailure($,J){let V=c(J);try{this.db.close()}catch{}throw console.error("[open-mem] Database configure failed (non-destructive fail-safe)",{stage:$,dbPath:this.dbPath,sqliteCode:V.code,sqliteMessage:V.message,action:"startup-abort",deletionAttempted:!1}),Error(`Database startup failed during ${$} (fail-safe, non-destructive): [${V.code}] ${V.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{S1.load(this.db),this._hasVectorExtension=!0}catch($){let J=c($);console.warn("[open-mem] SQLite extension load skipped",{stage:"loadExtensions",dbPath:this.dbPath,sqliteCode:J.code,sqliteMessage:J.message,action:"continue-without-extension"}),this._hasVectorExtension=!1}}get hasVectorExtension(){return this._hasVectorExtension}ensureMigrationTable(){this.db.exec(`
161
162
  CREATE TABLE IF NOT EXISTS _migrations (
162
163
  version INTEGER PRIMARY KEY,
163
164
  name TEXT NOT NULL,
164
165
  applied_at TEXT NOT NULL DEFAULT (datetime('now'))
165
166
  )
166
- `)}migrate(u){this.ensureMigrationTable();let y=this.db.query("SELECT version FROM _migrations ORDER BY version").all(),B=new Set(y.map((A)=>A.version)),$=u.filter((A)=>!B.has(A.version)).sort((A,J)=>A.version-J.version);for(let A of $)this.db.transaction(()=>{this.db.exec(A.up),this.db.query("INSERT INTO _migrations (version, name) VALUES ($version, $name)").run({$version:A.version,$name:A.name})})()}run(u,y){let B=this.db.query(u);if(y)B.run(...y);else B.run()}get(u,y){let B=this.db.query(u);return y?B.get(...y):B.get()}all(u,y){let B=this.db.query(u);return y?B.all(...y):B.all()}exec(u){this.db.exec(u)}transaction(u){return this.db.transaction(u)()}close(){this.db.close()}get isOpen(){try{return this.db.query("SELECT 1").get(),!0}catch{return!1}}get raw(){return this.db}}function au(u){return new r(u)}import{randomUUID as uy}from"crypto";class Ku{db;constructor(u){this.db=u}upsertEntity(u,y){let B=uy(),$=new Date().toISOString();this.db.run(`INSERT INTO entities (id, name, entity_type, first_seen_at, last_seen_at, mention_count)
167
+ `)}migrate($){this.withAdvisoryWriteLock(this.processRole,()=>{this.ensureMigrationTable();let J=this.withRetry("migrate.applied_versions",()=>{return this.db.query("SELECT version FROM _migrations ORDER BY version").all()}),V=new Set(J.map((X)=>X.version)),Z=$.filter((X)=>!V.has(X.version)).sort((X,H)=>X.version-H.version);for(let X of Z)this.transaction(()=>{this.exec(X.up),this.run("INSERT INTO _migrations (version, name) VALUES ($version, $name)",[{$version:X.version,$name:X.name}])})})}withRetry($,J){let V=this.transactionDepth>0?0:UJ,Z;for(let X=0;X<=V;X++)try{return J()}catch(H){if(Z=H,!LJ(H)||X===V)throw H;let K=E1*2**X+Math.random()*E1;Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,K);let z=c(H);console.warn("[open-mem] Retrying after transient SQLite error",{attempt:X+1,maxRetries:V,operation:$,role:this.processRole,dbPath:this.dbPath,sqliteCode:z.code,sqliteMessage:z.message})}throw Z}run($,J){this.withAdvisoryWriteLock(this.processRole,()=>{this.withRetry("run",()=>{let V=this.db.query($);if(J)V.run(...J);else V.run()})})}get($,J){let V=()=>{let Z=this.db.query($);return J?Z.get(...J):Z.get()};if(F$($))return this.withAdvisoryWriteLock(this.processRole,()=>this.withRetry("get",V));return this.withRetry("get",V)}all($,J){let V=()=>{let Z=this.db.query($);return J?Z.all(...J):Z.all()};if(F$($))return this.withAdvisoryWriteLock(this.processRole,()=>this.withRetry("all",V));return this.withRetry("all",V)}exec($){let J=()=>this.withRetry("exec",()=>this.db.exec($));if(F$($)){this.withAdvisoryWriteLock(this.processRole,J);return}J()}transaction($){return this.withAdvisoryWriteLock(this.processRole,()=>{if(this.transactionDepth>0)return $();let J=this.db.transaction($);if(typeof J.immediate==="function"){this.transactionDepth+=1;try{return J.immediate()}finally{this.transactionDepth-=1}}this.db.exec("BEGIN IMMEDIATE"),this.transactionDepth+=1;try{let V=$();return this.db.exec("COMMIT"),V}catch(V){let Z=V;try{this.db.exec("ROLLBACK")}catch(X){if(Z instanceof Error){let H=Z;if(H.cause===void 0)H.cause=X;else H.suppressed=[...H.suppressed??[],X]}console.warn("[open-mem] Transaction rollback failed after transaction error",{dbPath:this.dbPath,originalError:c(Z),rollbackError:c(X)})}throw Z}finally{this.transactionDepth-=1}})}get writeLockPath(){return this.advisoryWriteLockPath}withAdvisoryWriteLock($,J,V){try{return y1(this.advisoryWriteLockPath,{...V,role:$},J)}catch(Z){if(Z instanceof t)console.error("[open-mem] Advisory write lock timeout",{role:$,dbPath:this.dbPath,lockPath:Z.lockPath,waitDurationMs:Z.waitDurationMs,owner:Z.owner});throw Z}}checkpointWal($="PASSIVE"){let J=typeof $==="string"?$.toUpperCase():"";if(!DJ.has(J))throw Error(`Invalid wal_checkpoint mode: ${String($)}`);return this.withAdvisoryWriteLock(this.processRole,()=>{return this.withRetry("maintenance.wal_checkpoint",()=>{let V=this.db.query(`PRAGMA wal_checkpoint(${J})`).get();if(!V)throw Error("wal_checkpoint returned no result row");return{mode:J,busy:V.busy??0,logFrames:V.log??0,checkpointedFrames:V.checkpointed??0}})})}integrityCheck($=1){let J=Number.isFinite($)?Math.max(1,Math.floor($)):1;return this.withRetry("maintenance.integrity_check",()=>{let V=this.db.query(`PRAGMA integrity_check(${J})`).all();if(V.length===0)throw Error("integrity_check returned no result rows");let Z=V.map((X)=>Object.values(X).find((H)=>typeof H==="string")).filter((X)=>typeof X==="string").map((X)=>X.trim()).filter((X)=>X.length>0);if(Z.length===0)throw Error("integrity_check returned no diagnostic messages");return{ok:Z.length===1&&Z[0].toLowerCase()==="ok",messages:Z,maxErrors:J}})}close(){this.db.close()}get isOpen(){try{return this.db.query("SELECT 1").get(),!0}catch{return!1}}get raw(){return this.db}}function k1($,J){return new a($,J)}import{randomUUID as T1}from"crypto";class M${db;constructor($){this.db=$}upsertEntity($,J){let V=T1(),Z=new Date().toISOString();this.db.run(`INSERT INTO entities (id, name, entity_type, first_seen_at, last_seen_at, mention_count)
167
168
  VALUES (?, ?, ?, ?, ?, 1)
168
169
  ON CONFLICT(name, entity_type) DO UPDATE SET
169
170
  mention_count = mention_count + 1,
170
- last_seen_at = ?`,[B,u,y,$,$,$]);let A=this.db.get("SELECT * FROM entities WHERE name = ? AND entity_type = ?",[u,y]);if(!A)throw Error(`Failed to upsert entity: ${u} (${y})`);return this.mapEntityRow(A)}createRelation(u,y,B,$){let A=uy(),J=new Date().toISOString();try{this.db.run(`INSERT OR IGNORE INTO entity_relations
171
+ last_seen_at = ?`,[V,$,J,Z,Z,Z]);let X=this.db.get("SELECT * FROM entities WHERE name = ? AND entity_type = ?",[$,J]);if(!X)throw Error(`Failed to upsert entity: ${$} (${J})`);return this.mapEntityRow(X)}createRelation($,J,V,Z){let X=T1(),H=new Date().toISOString();try{this.db.run(`INSERT OR IGNORE INTO entity_relations
171
172
  (id, source_entity_id, target_entity_id, relationship, observation_id, created_at)
172
- VALUES (?, ?, ?, ?, ?, ?)`,[A,u,y,B,$,J])}catch{return null}let K=this.db.get(`SELECT * FROM entity_relations
173
- WHERE source_entity_id = ? AND target_entity_id = ? AND relationship = ?`,[u,y,B]);return K?this.mapRelationRow(K):null}linkObservation(u,y){this.db.run("INSERT OR IGNORE INTO entity_observations (entity_id, observation_id) VALUES (?, ?)",[u,y])}findByName(u){try{return this.db.all(`SELECT e.*
173
+ VALUES (?, ?, ?, ?, ?, ?)`,[X,$,J,V,Z,H])}catch{return null}let K=this.db.get(`SELECT * FROM entity_relations
174
+ WHERE source_entity_id = ? AND target_entity_id = ? AND relationship = ?`,[$,J,V]);return K?this.mapRelationRow(K):null}linkObservation($,J){this.db.run("INSERT OR IGNORE INTO entity_observations (entity_id, observation_id) VALUES (?, ?)",[$,J])}findByName($){try{return this.db.all(`SELECT e.*
174
175
  FROM entities e
175
176
  JOIN entities_fts fts ON e._rowid = fts.rowid
176
177
  WHERE entities_fts MATCH ?
177
- ORDER BY rank`,[u]).map((B)=>this.mapEntityRow(B))}catch{return[]}}getRelationsFor(u){return this.db.all(`SELECT * FROM entity_relations
178
- WHERE source_entity_id = ? OR target_entity_id = ?`,[u,u]).map((B)=>this.mapRelationRow(B))}traverseRelations(u,y=1){let B=Math.min(y,2),$=100,A=new Set,J=[{id:u,currentDepth:0}];A.add(u);while(J.length>0){if(A.size>=100)break;let K=J.shift();if(!K)continue;if(K.currentDepth>=B)continue;let V=this.getRelationsFor(K.id);for(let R of V){let z=R.sourceEntityId===K.id?R.targetEntityId:R.sourceEntityId;if(!A.has(z))A.add(z),J.push({id:z,currentDepth:K.currentDepth+1})}}return A}getObservationsForEntity(u){return this.db.all("SELECT observation_id FROM entity_observations WHERE entity_id = ?",[u]).map((B)=>B.observation_id)}getById(u){let y=this.db.get("SELECT * FROM entities WHERE id = ?",[u]);return y?this.mapEntityRow(y):null}mapEntityRow(u){return{id:u.id,name:u.name,entityType:u.entity_type,firstSeenAt:u.first_seen_at,lastSeenAt:u.last_seen_at,mentionCount:u.mention_count}}mapRelationRow(u){return{id:u.id,sourceEntityId:u.source_entity_id,targetEntityId:u.target_entity_id,relationship:u.relationship,observationId:u.observation_id,createdAt:u.created_at}}}import{randomUUID as H0}from"crypto";import{embed as W0}from"ai";async function zu(u,y){try{let{embedding:B}=await W0({model:u,value:y});return B}catch{return null}}function yy(u,y){if(u.length!==y.length||u.length===0)return 0;let B=0,$=0,A=0;for(let K=0;K<u.length;K++)B+=u[K]*y[K],$+=u[K]*u[K],A+=y[K]*y[K];let J=Math.sqrt($)*Math.sqrt(A);if(J===0)return 0;return B/J}function Ru(u){let y=[u.title,u.narrative];if(u.concepts.length>0)y.push(u.concepts.join(", "));return y.join(`
179
- `)}function Q0(u){return u.replace(/[%_\\]/g,"\\$&")}class Vu{db;constructor(u){this.db=u}create(u){let y=H0(),B=new Date().toISOString(),$=u.discoveryTokens??0,A=u.importance??3,J=u.scope??"project";return this.db.run(`INSERT INTO observations
178
+ ORDER BY rank`,[$]).map((V)=>this.mapEntityRow(V))}catch{return[]}}getRelationsFor($){return this.db.all(`SELECT * FROM entity_relations
179
+ WHERE source_entity_id = ? OR target_entity_id = ?`,[$,$]).map((V)=>this.mapRelationRow(V))}traverseRelations($,J=1){let V=Math.min(J,2),Z=100,X=new Set,H=[{id:$,currentDepth:0}];X.add($);while(H.length>0){if(X.size>=100)break;let K=H.shift();if(!K)continue;if(K.currentDepth>=V)continue;let z=this.getRelationsFor(K.id);for(let B of z){let Y=B.sourceEntityId===K.id?B.targetEntityId:B.sourceEntityId;if(!X.has(Y))X.add(Y),H.push({id:Y,currentDepth:K.currentDepth+1})}}return X}getObservationsForEntity($){return this.db.all("SELECT observation_id FROM entity_observations WHERE entity_id = ?",[$]).map((V)=>V.observation_id)}getById($){let J=this.db.get("SELECT * FROM entities WHERE id = ?",[$]);return J?this.mapEntityRow(J):null}mapEntityRow($){return{id:$.id,name:$.name,entityType:$.entity_type,firstSeenAt:$.first_seen_at,lastSeenAt:$.last_seen_at,mentionCount:$.mention_count}}mapRelationRow($){return{id:$.id,sourceEntityId:$.source_entity_id,targetEntityId:$.target_entity_id,relationship:$.relationship,observationId:$.observation_id,createdAt:$.created_at}}}import{randomUUID as RJ}from"crypto";import{embed as _J}from"ai";async function D$($,J){try{let{embedding:V}=await _J({model:$,value:J});return V}catch{return null}}function j1($,J){if($.length!==J.length||$.length===0)return 0;let V=0,Z=0,X=0;for(let K=0;K<$.length;K++)V+=$[K]*J[K],Z+=$[K]*$[K],X+=J[K]*J[K];let H=Math.sqrt(Z)*Math.sqrt(X);if(H===0)return 0;return V/H}function L$($){let J=[$.title,$.narrative];if($.concepts.length>0)J.push($.concepts.join(", "));return J.join(`
180
+ `)}function CJ($){return $.replace(/[%_\\]/g,"\\$&")}class _${db;constructor($){this.db=$}create($){let J=RJ(),V=new Date().toISOString(),Z=$.discoveryTokens??0,X=$.importance??3,H=$.scope??"project";return this.db.run(`INSERT INTO observations
180
181
  (id, session_id, scope, type, title, subtitle, facts, narrative,
181
182
  concepts, files_read, files_modified, raw_tool_output,
182
183
  tool_name, created_at, token_count, discovery_tokens, importance, revision_of, deleted_at)
183
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[y,u.sessionId,J,u.type,u.title,u.subtitle,JSON.stringify(u.facts),u.narrative,JSON.stringify(u.concepts),JSON.stringify(u.filesRead),JSON.stringify(u.filesModified),u.rawToolOutput,u.toolName,B,u.tokenCount,$,A,null,null]),{...u,id:y,scope:J,createdAt:B,discoveryTokens:$,importance:A,revisionOf:null,deletedAt:null,supersededBy:null,supersededAt:null}}importObservation(u){this.db.run(`INSERT INTO observations
184
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[J,$.sessionId,H,$.type,$.title,$.subtitle,JSON.stringify($.facts),$.narrative,JSON.stringify($.concepts),JSON.stringify($.filesRead),JSON.stringify($.filesModified),$.rawToolOutput,$.toolName,V,$.tokenCount,Z,X,null,null]),{...$,id:J,scope:H,createdAt:V,discoveryTokens:Z,importance:X,revisionOf:null,deletedAt:null,supersededBy:null,supersededAt:null}}importObservation($){this.db.run(`INSERT INTO observations
184
185
  (id, session_id, scope, type, title, subtitle, facts, narrative,
185
186
  concepts, files_read, files_modified, raw_tool_output,
186
187
  tool_name, created_at, token_count, discovery_tokens, importance, revision_of, deleted_at)
187
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[u.id,u.sessionId,u.scope??"project",u.type,u.title,u.subtitle,JSON.stringify(u.facts),u.narrative,JSON.stringify(u.concepts),JSON.stringify(u.filesRead),JSON.stringify(u.filesModified),u.rawToolOutput,u.toolName,u.createdAt,u.tokenCount,u.discoveryTokens??0,u.importance??3,u.revisionOf??null,u.deletedAt??null])}getById(u){let y=this.db.get("SELECT * FROM observations WHERE id = ? AND superseded_by IS NULL AND deleted_at IS NULL",[u]);return y?this.mapRow(y):null}getByIdIncludingArchived(u){let y=this.db.get("SELECT * FROM observations WHERE id = ?",[u]);return y?this.mapRow(y):null}getBySession(u){return this.db.all("SELECT * FROM observations WHERE session_id = ? AND superseded_by IS NULL AND deleted_at IS NULL ORDER BY created_at ASC",[u]).map((y)=>this.mapRow(y))}getCount(u){if(u)return this.db.get("SELECT COUNT(*) as count FROM observations WHERE session_id = ?",[u])?.count??0;return this.db.get("SELECT COUNT(*) as count FROM observations")?.count??0}getIndex(u,y=20){return this.db.all(`SELECT o.id, o.session_id, o.type, o.title, o.token_count, o.discovery_tokens, o.created_at, o.importance
188
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[$.id,$.sessionId,$.scope??"project",$.type,$.title,$.subtitle,JSON.stringify($.facts),$.narrative,JSON.stringify($.concepts),JSON.stringify($.filesRead),JSON.stringify($.filesModified),$.rawToolOutput,$.toolName,$.createdAt,$.tokenCount,$.discoveryTokens??0,$.importance??3,$.revisionOf??null,$.deletedAt??null])}getById($){let J=this.db.get("SELECT * FROM observations WHERE id = ? AND superseded_by IS NULL AND deleted_at IS NULL",[$]);return J?this.mapRow(J):null}getByIdIncludingArchived($){let J=this.db.get("SELECT * FROM observations WHERE id = ?",[$]);return J?this.mapRow(J):null}getBySession($){return this.db.all("SELECT * FROM observations WHERE session_id = ? AND superseded_by IS NULL AND deleted_at IS NULL ORDER BY created_at ASC",[$]).map((J)=>this.mapRow(J))}getCount($){if($)return this.db.get("SELECT COUNT(*) as count FROM observations WHERE session_id = ?",[$])?.count??0;return this.db.get("SELECT COUNT(*) as count FROM observations")?.count??0}getIndex($,J=20){return this.db.all(`SELECT o.id, o.session_id, o.type, o.title, o.token_count, o.discovery_tokens, o.created_at, o.importance
188
189
  FROM observations o
189
190
  JOIN sessions s ON o.session_id = s.id
190
191
  WHERE s.project_path = ? AND o.superseded_by IS NULL AND o.deleted_at IS NULL
191
192
  ORDER BY o.created_at DESC
192
- LIMIT ?`,[u,y]).map((B)=>({id:B.id,sessionId:B.session_id,type:B.type,title:B.title,tokenCount:B.token_count,discoveryTokens:B.discovery_tokens??0,createdAt:B.created_at,importance:B.importance??3}))}getAroundTimestamp(u,y,B,$){let A=y>0?this.db.all(`SELECT o.*
193
+ LIMIT ?`,[$,J]).map((V)=>({id:V.id,sessionId:V.session_id,type:V.type,title:V.title,tokenCount:V.token_count,discoveryTokens:V.discovery_tokens??0,createdAt:V.created_at,importance:V.importance??3}))}getAroundTimestamp($,J,V,Z){let X=J>0?this.db.all(`SELECT o.*
193
194
  FROM observations o
194
195
  JOIN sessions s ON o.session_id = s.id
195
196
  WHERE s.project_path = ? AND o.created_at < ?
196
197
  AND o.superseded_by IS NULL AND o.deleted_at IS NULL
197
198
  ORDER BY o.created_at DESC
198
- LIMIT ?`,[$,u,y]).reverse():[],J=B>0?this.db.all(`SELECT o.*
199
+ LIMIT ?`,[Z,$,J]).reverse():[],H=V>0?this.db.all(`SELECT o.*
199
200
  FROM observations o
200
201
  JOIN sessions s ON o.session_id = s.id
201
202
  WHERE s.project_path = ? AND o.created_at > ?
202
203
  AND o.superseded_by IS NULL AND o.deleted_at IS NULL
203
204
  ORDER BY o.created_at ASC
204
- LIMIT ?`,[$,u,B]):[];return[...A,...J].map((K)=>this.mapRow(K))}listByProject(u,y={}){let{limit:B=50,offset:$=0,type:A,state:J,sessionId:K}=y,V=`SELECT o.*
205
+ LIMIT ?`,[Z,$,V]):[];return[...X,...H].map((K)=>this.mapRow(K))}listByProject($,J={}){let{limit:V=50,offset:Z=0,type:X,state:H,sessionId:K}=J,z=`SELECT o.*
205
206
  FROM observations o
206
207
  JOIN sessions s ON o.session_id = s.id
207
- WHERE s.project_path = ?`,R=[u];if(K)V+=" AND o.session_id = ?",R.push(K);if(A)V+=" AND o.type = ?",R.push(A);if(J==="current")V+=" AND o.superseded_by IS NULL AND o.deleted_at IS NULL";else if(J==="superseded")V+=" AND o.superseded_by IS NOT NULL AND o.deleted_at IS NULL";else if(J==="tombstoned")V+=" AND o.deleted_at IS NOT NULL";else V+=" AND o.superseded_by IS NULL AND o.deleted_at IS NULL";return V+=" ORDER BY o.created_at DESC LIMIT ? OFFSET ?",R.push(B,$),this.db.all(V,R).map((z)=>this.mapRow(z))}search(u){let y=!!u.projectPath,B=`
208
+ WHERE s.project_path = ?`,B=[$];if(K)z+=" AND o.session_id = ?",B.push(K);if(X)z+=" AND o.type = ?",B.push(X);if(H==="current")z+=" AND o.superseded_by IS NULL AND o.deleted_at IS NULL";else if(H==="superseded")z+=" AND o.superseded_by IS NOT NULL AND o.deleted_at IS NULL";else if(H==="tombstoned")z+=" AND o.deleted_at IS NOT NULL";else z+=" AND o.superseded_by IS NULL AND o.deleted_at IS NULL";return z+=" ORDER BY o.created_at DESC LIMIT ? OFFSET ?",B.push(V,Z),this.db.all(z,B).map((Y)=>this.mapRow(Y))}search($){let J=!!$.projectPath,V=`
208
209
  SELECT o.*, rank
209
210
  FROM observations o
210
211
  JOIN observations_fts fts ON o._rowid = fts.rowid
211
- ${y?"JOIN sessions s ON o.session_id = s.id":""}
212
+ ${J?"JOIN sessions s ON o.session_id = s.id":""}
212
213
  WHERE observations_fts MATCH ? AND o.superseded_by IS NULL AND o.deleted_at IS NULL
213
- `,$=[u.query];if(y&&u.projectPath)B+=" AND s.project_path = ?",$.push(u.projectPath);if(u.sessionId)B+=" AND o.session_id = ?",$.push(u.sessionId);if(u.type)B+=" AND o.type = ?",$.push(u.type);if(u.importanceMin!==void 0)B+=" AND o.importance >= ?",$.push(u.importanceMin);if(u.importanceMax!==void 0)B+=" AND o.importance <= ?",$.push(u.importanceMax);if(u.createdAfter)B+=" AND o.created_at >= ?",$.push(u.createdAfter);if(u.createdBefore)B+=" AND o.created_at <= ?",$.push(u.createdBefore);if(u.concepts&&u.concepts.length>0){let A=u.concepts.map(()=>"EXISTS (SELECT 1 FROM json_each(o.concepts) WHERE LOWER(value) = LOWER(?))");B+=` AND (${A.join(" OR ")})`;for(let J of u.concepts)$.push(J)}if(u.files&&u.files.length>0){let A=u.files.map(()=>`(EXISTS (SELECT 1 FROM json_each(o.files_read) WHERE LOWER(value) LIKE LOWER(?) ESCAPE '\\')
214
- OR EXISTS (SELECT 1 FROM json_each(o.files_modified) WHERE LOWER(value) LIKE LOWER(?) ESCAPE '\\'))`);B+=` AND (${A.join(" OR ")})`;for(let J of u.files){let K=`%${Q0(J)}%`;$.push(K,K)}}return B+=" ORDER BY rank LIMIT ? OFFSET ?",$.push(u.limit??10),$.push(u.offset??0),this.db.all(B,$).map((A)=>({observation:this.mapRow(A),rank:A.rank,snippet:A.title}))}searchByConcept(u,y=10,B){let $=!!B,A=`SELECT o.*
214
+ `,Z=[$.query];if(J&&$.projectPath)V+=" AND s.project_path = ?",Z.push($.projectPath);if($.sessionId)V+=" AND o.session_id = ?",Z.push($.sessionId);if($.type)V+=" AND o.type = ?",Z.push($.type);if($.importanceMin!==void 0)V+=" AND o.importance >= ?",Z.push($.importanceMin);if($.importanceMax!==void 0)V+=" AND o.importance <= ?",Z.push($.importanceMax);if($.createdAfter)V+=" AND o.created_at >= ?",Z.push($.createdAfter);if($.createdBefore)V+=" AND o.created_at <= ?",Z.push($.createdBefore);if($.concepts&&$.concepts.length>0){let X=$.concepts.map(()=>"EXISTS (SELECT 1 FROM json_each(o.concepts) WHERE LOWER(value) = LOWER(?))");V+=` AND (${X.join(" OR ")})`;for(let H of $.concepts)Z.push(H)}if($.files&&$.files.length>0){let X=$.files.map(()=>`(EXISTS (SELECT 1 FROM json_each(o.files_read) WHERE LOWER(value) LIKE LOWER(?) ESCAPE '\\')
215
+ OR EXISTS (SELECT 1 FROM json_each(o.files_modified) WHERE LOWER(value) LIKE LOWER(?) ESCAPE '\\'))`);V+=` AND (${X.join(" OR ")})`;for(let H of $.files){let K=`%${CJ(H)}%`;Z.push(K,K)}}return V+=" ORDER BY rank LIMIT ? OFFSET ?",Z.push($.limit??10),Z.push($.offset??0),this.db.all(V,Z).map((X)=>({observation:this.mapRow(X),rank:X.rank,snippet:X.title}))}searchByConcept($,J=10,V){let Z=!!V,X=`SELECT o.*
215
216
  FROM observations o
216
217
  JOIN observations_fts fts ON o._rowid = fts.rowid
217
- ${$?"JOIN sessions s ON o.session_id = s.id":""}
218
+ ${Z?"JOIN sessions s ON o.session_id = s.id":""}
218
219
  WHERE observations_fts MATCH ?
219
220
  AND o.superseded_by IS NULL AND o.deleted_at IS NULL
220
- ${$?"AND s.project_path = ?":""}
221
+ ${Z?"AND s.project_path = ?":""}
221
222
  ORDER BY rank
222
- LIMIT ?`,K=[`concepts:"${u.replace(/"/g,'""')}"`];if($&&B)K.push(B);return K.push(y),this.db.all(A,K).map((V)=>this.mapRow(V))}searchByFile(u,y=10,B){let $=!!B,A=`SELECT o.*
223
+ LIMIT ?`,K=[`concepts:"${$.replace(/"/g,'""')}"`];if(Z&&V)K.push(V);return K.push(J),this.db.all(X,K).map((z)=>this.mapRow(z))}searchByFile($,J=10,V){let Z=!!V,X=`SELECT o.*
223
224
  FROM observations o
224
225
  JOIN observations_fts fts ON o._rowid = fts.rowid
225
- ${$?"JOIN sessions s ON o.session_id = s.id":""}
226
+ ${Z?"JOIN sessions s ON o.session_id = s.id":""}
226
227
  WHERE observations_fts MATCH ?
227
228
  AND o.superseded_by IS NULL AND o.deleted_at IS NULL
228
- ${$?"AND s.project_path = ?":""}
229
+ ${Z?"AND s.project_path = ?":""}
229
230
  ORDER BY rank
230
- LIMIT ?`,J=[`files_read:"${u.replace(/"/g,'""')}" OR files_modified:"${u.replace(/"/g,'""')}"`];if($&&B)J.push(B);return J.push(y),this.db.all(A,J).map((K)=>this.mapRow(K))}setEmbedding(u,y){this.db.run("UPDATE observations SET embedding = ? WHERE id = ?",[JSON.stringify(y),u])}getWithEmbeddings(u,y){return this.db.all(`SELECT o.id, o.embedding, o.title
231
+ LIMIT ?`,H=[`files_read:"${$.replace(/"/g,'""')}" OR files_modified:"${$.replace(/"/g,'""')}"`];if(Z&&V)H.push(V);return H.push(J),this.db.all(X,H).map((K)=>this.mapRow(K))}setEmbedding($,J){this.db.run("UPDATE observations SET embedding = ? WHERE id = ?",[JSON.stringify(J),$])}getWithEmbeddings($,J){return this.db.all(`SELECT o.id, o.embedding, o.title
231
232
  FROM observations o
232
233
  JOIN sessions s ON o.session_id = s.id
233
234
  WHERE s.project_path = ? AND o.embedding IS NOT NULL AND o.superseded_by IS NULL AND o.deleted_at IS NULL
234
235
  ORDER BY o.created_at DESC
235
- LIMIT ?`,[u,y]).map((B)=>{try{return{id:B.id,embedding:JSON.parse(B.embedding),title:B.title}}catch{return null}}).filter((B)=>B!==null)}findSimilar(u,y,B,$){let A=this.db.all(`SELECT id, embedding FROM observations
236
+ LIMIT ?`,[$,J]).map((V)=>{try{return{id:V.id,embedding:JSON.parse(V.embedding),title:V.title}}catch{return null}}).filter((V)=>V!==null)}findSimilar($,J,V,Z){let X=this.db.all(`SELECT id, embedding FROM observations
236
237
  WHERE embedding IS NOT NULL AND type = ? AND superseded_by IS NULL AND deleted_at IS NULL
237
238
  ORDER BY created_at DESC
238
- LIMIT 200`,[y]),J=[];for(let K of A)try{let V=JSON.parse(K.embedding);if(!Array.isArray(V)||V.length!==u.length)continue;let R=yy(u,V);if(R>=B)J.push({id:K.id,similarity:R})}catch{}return J.sort((K,V)=>V.similarity-K.similarity).slice(0,$)}insertVecEmbedding(u,y){let B=new Float32Array(y);this.db.run("BEGIN");try{this.db.run("DELETE FROM observation_embeddings WHERE observation_id = ?",[u]),this.db.run("INSERT INTO observation_embeddings (observation_id, embedding) VALUES (?, ?)",[u,B]),this.db.run("COMMIT")}catch($){throw this.db.run("ROLLBACK"),$}}migrateExistingEmbeddings(u){let y=this.db.all("SELECT id, embedding FROM observations WHERE embedding IS NOT NULL"),B=0,$=0;for(let A of y)try{let J=JSON.parse(A.embedding);if(!Array.isArray(J)||J.length!==u){$++;continue}this.insertVecEmbedding(A.id,J),B++}catch{$++}return{migrated:B,skipped:$}}getVecEmbeddingMatches(u,y){try{let B=new Float32Array(u);return this.db.all(`SELECT observation_id, distance
239
+ LIMIT 200`,[J]),H=[];for(let K of X)try{let z=JSON.parse(K.embedding);if(!Array.isArray(z)||z.length!==$.length)continue;let B=j1($,z);if(B>=V)H.push({id:K.id,similarity:B})}catch{}return H.sort((K,z)=>z.similarity-K.similarity).slice(0,Z)}insertVecEmbedding($,J){let V=new Float32Array(J);this.db.run("BEGIN");try{this.db.run("DELETE FROM observation_embeddings WHERE observation_id = ?",[$]),this.db.run("INSERT INTO observation_embeddings (observation_id, embedding) VALUES (?, ?)",[$,V]),this.db.run("COMMIT")}catch(Z){throw this.db.run("ROLLBACK"),Z}}migrateExistingEmbeddings($){let J=this.db.all("SELECT id, embedding FROM observations WHERE embedding IS NOT NULL"),V=0,Z=0;for(let X of J)try{let H=JSON.parse(X.embedding);if(!Array.isArray(H)||H.length!==$){Z++;continue}this.insertVecEmbedding(X.id,H),V++}catch{Z++}return{migrated:V,skipped:Z}}getVecEmbeddingMatches($,J){try{let V=new Float32Array($);return this.db.all(`SELECT observation_id, distance
239
240
  FROM observation_embeddings
240
- WHERE embedding MATCH ? AND k = ?`,[B,y]).map(($)=>({observationId:$.observation_id,distance:$.distance}))}catch{return[]}}searchVecSubset(u,y,B){if(y.length===0)return[];try{let $=new Float32Array(u),A=Math.max(B*5,y.length),J=this.db.all(`SELECT observation_id, distance
241
+ WHERE embedding MATCH ? AND k = ?`,[V,J]).map((Z)=>({observationId:Z.observation_id,distance:Z.distance}))}catch{return[]}}searchVecSubset($,J,V){if(J.length===0)return[];try{let Z=new Float32Array($),X=Math.max(V*5,J.length),H=this.db.all(`SELECT observation_id, distance
241
242
  FROM observation_embeddings
242
- WHERE embedding MATCH ? AND k = ?`,[$,A]),K=new Set(y);return J.filter((V)=>K.has(V.observation_id)).slice(0,B).map((V)=>({observationId:V.observation_id,distance:V.distance}))}catch{return[]}}update(u,y){let B=this.getById(u);if(!B)return null;if(Object.keys(y).length===0)return B;let $=this.create({sessionId:B.sessionId,scope:B.scope??"project",type:y.type??B.type,title:y.title??B.title,subtitle:y.subtitle??B.subtitle,facts:y.facts??B.facts,narrative:y.narrative??B.narrative,concepts:y.concepts??B.concepts,filesRead:y.filesRead??B.filesRead,filesModified:y.filesModified??B.filesModified,rawToolOutput:B.rawToolOutput,toolName:"mem-revise",tokenCount:B.tokenCount,discoveryTokens:B.discoveryTokens,importance:y.importance??B.importance});return this.db.run("UPDATE observations SET revision_of = ? WHERE id = ?",[u,$.id]),this.supersede(u,$.id),this.getById($.id)}supersede(u,y){let B=new Date().toISOString();this.db.run("UPDATE observations SET superseded_by = ?, superseded_at = ? WHERE id = ?",[y,B,u])}delete(u){if(this.db.all("SELECT id FROM observations WHERE id = ?",[u]).length===0)return!1;let B=new Date().toISOString();return this.db.run("UPDATE observations SET deleted_at = ? WHERE id = ?",[B,u]),this.deleteEmbeddingsForObservations([u]),!0}getLineage(u){let y=this.getByIdIncludingArchived(u);if(!y)return[];let B=new Set([y.id]),$=[y];while($[0].revisionOf){let A=this.getByIdIncludingArchived($[0].revisionOf);if(!A||B.has(A.id))break;$.unshift(A),B.add(A.id)}while($[$.length-1].supersededBy){let A=$[$.length-1].supersededBy;if(!A)break;let J=this.getByIdIncludingArchived(A);if(!J||B.has(J.id))break;$.push(J),B.add(J.id)}return $}deleteOlderThan(u){return this.db.all(`DELETE FROM observations
243
+ WHERE embedding MATCH ? AND k = ?`,[Z,X]),K=new Set(J);return H.filter((z)=>K.has(z.observation_id)).slice(0,V).map((z)=>({observationId:z.observation_id,distance:z.distance}))}catch{return[]}}update($,J){let V=this.getById($);if(!V)return null;if(Object.keys(J).length===0)return V;let Z=this.create({sessionId:V.sessionId,scope:V.scope??"project",type:J.type??V.type,title:J.title??V.title,subtitle:J.subtitle??V.subtitle,facts:J.facts??V.facts,narrative:J.narrative??V.narrative,concepts:J.concepts??V.concepts,filesRead:J.filesRead??V.filesRead,filesModified:J.filesModified??V.filesModified,rawToolOutput:V.rawToolOutput,toolName:"mem-revise",tokenCount:V.tokenCount,discoveryTokens:V.discoveryTokens,importance:J.importance??V.importance});return this.db.run("UPDATE observations SET revision_of = ? WHERE id = ?",[$,Z.id]),this.supersede($,Z.id),this.getById(Z.id)}supersede($,J){let V=new Date().toISOString();this.db.run("UPDATE observations SET superseded_by = ?, superseded_at = ? WHERE id = ?",[J,V,$])}delete($){if(this.db.all("SELECT id FROM observations WHERE id = ?",[$]).length===0)return!1;let V=new Date().toISOString();return this.db.run("UPDATE observations SET deleted_at = ? WHERE id = ?",[V,$]),this.deleteEmbeddingsForObservations([$]),!0}getLineage($){let J=this.getByIdIncludingArchived($);if(!J)return[];let V=new Set([J.id]),Z=[J];while(Z[0].revisionOf){let X=this.getByIdIncludingArchived(Z[0].revisionOf);if(!X||V.has(X.id))break;Z.unshift(X),V.add(X.id)}while(Z[Z.length-1].supersededBy){let X=Z[Z.length-1].supersededBy;if(!X)break;let H=this.getByIdIncludingArchived(X);if(!H||V.has(H.id))break;Z.push(H),V.add(H.id)}return Z}deleteOlderThan($){return this.db.all(`DELETE FROM observations
243
244
  WHERE (created_at < datetime('now', '-' || ? || ' days') OR deleted_at IS NOT NULL)
244
245
  AND session_id NOT IN (SELECT id FROM sessions WHERE status != 'completed')
245
- RETURNING id`,[u]).length}deleteEmbeddingsForObservations(u){if(u.length===0)return;let y=u.map(()=>"?").join(",");try{this.db.run(`DELETE FROM observation_embeddings WHERE observation_id IN (${y})`,u)}catch{}this.db.run(`UPDATE observations SET embedding = NULL WHERE id IN (${y})`,u)}mapRow(u){return{id:u.id,sessionId:u.session_id,scope:u.scope??"project",type:u.type,title:u.title,subtitle:u.subtitle,facts:JSON.parse(u.facts),narrative:u.narrative,concepts:JSON.parse(u.concepts),filesRead:JSON.parse(u.files_read),filesModified:JSON.parse(u.files_modified),rawToolOutput:u.raw_tool_output,toolName:u.tool_name,createdAt:u.created_at,tokenCount:u.token_count,discoveryTokens:u.discovery_tokens??0,importance:u.importance??3,revisionOf:u.revision_of??null,deletedAt:u.deleted_at??null,supersededBy:u.superseded_by??null,supersededAt:u.superseded_at??null}}}import{randomUUID as Z0}from"crypto";class Nu{db;constructor(u){this.db=u}create(u){let y=Z0(),B=new Date().toISOString();return this.db.run(`INSERT INTO pending_messages
246
+ RETURNING id`,[$]).length}deleteEmbeddingsForObservations($){if($.length===0)return;let J=$.map(()=>"?").join(",");try{this.db.run(`DELETE FROM observation_embeddings WHERE observation_id IN (${J})`,$)}catch{}this.db.run(`UPDATE observations SET embedding = NULL WHERE id IN (${J})`,$)}mapRow($){return{id:$.id,sessionId:$.session_id,scope:$.scope??"project",type:$.type,title:$.title,subtitle:$.subtitle,facts:JSON.parse($.facts),narrative:$.narrative,concepts:JSON.parse($.concepts),filesRead:JSON.parse($.files_read),filesModified:JSON.parse($.files_modified),rawToolOutput:$.raw_tool_output,toolName:$.tool_name,createdAt:$.created_at,tokenCount:$.token_count,discoveryTokens:$.discovery_tokens??0,importance:$.importance??3,revisionOf:$.revision_of??null,deletedAt:$.deleted_at??null,supersededBy:$.superseded_by??null,supersededAt:$.superseded_at??null}}}import{randomUUID as yJ}from"crypto";class R${db;constructor($){this.db=$}create($){let J=yJ(),V=new Date().toISOString();return this.db.run(`INSERT INTO pending_messages
246
247
  (id, session_id, tool_name, tool_output, call_id, created_at)
247
- VALUES (?, ?, ?, ?, ?, ?)`,[y,u.sessionId,u.toolName,u.toolOutput,u.callId,B]),{...u,id:y,createdAt:B,status:"pending",retryCount:0,error:null}}getPending(u=10){return this.db.all("SELECT * FROM pending_messages WHERE status = 'pending' ORDER BY created_at ASC LIMIT ?",[u]).map((y)=>this.mapRow(y))}getByStatus(u){return this.db.all("SELECT * FROM pending_messages WHERE status = ? ORDER BY created_at ASC",[u]).map((y)=>this.mapRow(y))}markProcessing(u){this.db.run("UPDATE pending_messages SET status = 'processing' WHERE id = ?",[u])}markCompleted(u){this.db.run("UPDATE pending_messages SET status = 'completed' WHERE id = ?",[u])}markFailed(u,y){this.db.run("UPDATE pending_messages SET status = 'failed', error = ?, retry_count = retry_count + 1 WHERE id = ?",[y,u])}resetStale(u=5){return this.db.all(`UPDATE pending_messages SET status = 'pending'
248
+ VALUES (?, ?, ?, ?, ?, ?)`,[J,$.sessionId,$.toolName,$.toolOutput,$.callId,V]),{...$,id:J,createdAt:V,status:"pending",retryCount:0,error:null}}getPending($=10){return this.db.all("SELECT * FROM pending_messages WHERE status = 'pending' ORDER BY created_at ASC LIMIT ?",[$]).map((J)=>this.mapRow(J))}getByStatus($){return this.db.all("SELECT * FROM pending_messages WHERE status = ? ORDER BY created_at ASC",[$]).map((J)=>this.mapRow(J))}markProcessing($){this.db.run("UPDATE pending_messages SET status = 'processing' WHERE id = ?",[$])}markCompleted($){this.db.run("UPDATE pending_messages SET status = 'completed' WHERE id = ?",[$])}markFailed($,J){this.db.run("UPDATE pending_messages SET status = 'failed', error = ?, retry_count = retry_count + 1 WHERE id = ?",[J,$])}resetStale($=5){return this.db.all(`UPDATE pending_messages SET status = 'pending'
248
249
  WHERE status = 'processing'
249
250
  AND created_at < datetime('now', ? || ' minutes')
250
- RETURNING id`,[`-${u}`]).length}deleteCompletedOlderThan(u){return this.db.all(`DELETE FROM pending_messages
251
+ RETURNING id`,[`-${$}`]).length}deleteCompletedOlderThan($){return this.db.all(`DELETE FROM pending_messages
251
252
  WHERE status = 'completed'
252
253
  AND created_at < datetime('now', '-' || ? || ' days')
253
- RETURNING id`,[u]).length}mapRow(u){return{id:u.id,sessionId:u.session_id,toolName:u.tool_name,toolOutput:u.tool_output,callId:u.call_id,createdAt:u.created_at,status:u.status,retryCount:u.retry_count,error:u.error??null}}}var S0=[{version:1,name:"create-schema",up:`
254
+ RETURNING id`,[$]).length}mapRow($){return{id:$.id,sessionId:$.session_id,toolName:$.tool_name,toolOutput:$.tool_output,callId:$.call_id,createdAt:$.created_at,status:$.status,retryCount:$.retry_count,error:$.error??null}}}var OJ=[{version:1,name:"create-schema",up:`
254
255
  -- Sessions table
255
256
  CREATE TABLE IF NOT EXISTS sessions (
256
257
  _rowid INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -544,22 +545,22 @@ Respond with EXACTLY this XML format:
544
545
  INSERT INTO entities_fts(rowid, name, entity_type)
545
546
  VALUES (new._rowid, new.name, new.entity_type);
546
547
  END;
547
- `}];function By(u,y){if(u.migrate(S0),y?.hasVectorExtension&&y?.embeddingDimension&&y.embeddingDimension>0)U0(u,y.embeddingDimension)}function U0(u,y){if(u.get("SELECT name FROM sqlite_master WHERE type='table' AND name='observation_embeddings'")){let $=u.get("SELECT value FROM _embedding_meta WHERE key = 'dimension'");if($&&Number($.value)!==y){console.warn(`[open-mem] vec0 table exists with dimension ${$.value}, but config specifies ${y}. Drop observation_embeddings to re-create with new dimension.`);return}}else u.exec(`CREATE VIRTUAL TABLE observation_embeddings USING vec0(
548
+ `}];function q1($,J){if($.migrate(OJ),J?.hasVectorExtension&&J?.embeddingDimension&&J.embeddingDimension>0)EJ($,J.embeddingDimension)}function EJ($,J){if($.get("SELECT name FROM sqlite_master WHERE type='table' AND name='observation_embeddings'")){let Z=$.get("SELECT value FROM _embedding_meta WHERE key = 'dimension'");if(Z&&Number(Z.value)!==J){console.warn(`[open-mem] vec0 table exists with dimension ${Z.value}, but config specifies ${J}. Drop observation_embeddings to re-create with new dimension.`);return}}else $.exec(`CREATE VIRTUAL TABLE observation_embeddings USING vec0(
548
549
  observation_id TEXT PRIMARY KEY,
549
- embedding float[${y}] distance_metric=cosine
550
- )`);u.run("INSERT OR REPLACE INTO _embedding_meta (key, value) VALUES (?, ?)",["dimension",String(y)])}class Eu{db;constructor(u){this.db=u}create(u,y){let B=new Date().toISOString();return this.db.run(`INSERT INTO sessions (id, project_path, started_at, status)
551
- VALUES (?, ?, ?, 'active')`,[u,y,B]),this.getById(u)}getOrCreate(u,y){let B=this.getById(u);if(B)return B;return this.create(u,y)}getById(u){let y=this.db.get("SELECT * FROM sessions WHERE id = ?",[u]);return y?this.mapRow(y):null}getRecent(u,y=10){return this.db.all("SELECT * FROM sessions WHERE project_path = ? ORDER BY started_at DESC LIMIT ?",[u,y]).map((B)=>this.mapRow(B))}getAll(u){return this.db.all("SELECT * FROM sessions WHERE project_path = ? ORDER BY started_at DESC",[u]).map((y)=>this.mapRow(y))}getActive(){return this.db.all("SELECT * FROM sessions WHERE status = 'active' ORDER BY started_at DESC").map((u)=>this.mapRow(u))}updateStatus(u,y){this.db.run("UPDATE sessions SET status = ? WHERE id = ?",[y,u])}markCompleted(u){this.db.run("UPDATE sessions SET status = 'completed', ended_at = datetime('now') WHERE id = ?",[u])}incrementObservationCount(u){this.db.run("UPDATE sessions SET observation_count = observation_count + 1 WHERE id = ?",[u])}setSummary(u,y){this.db.run("UPDATE sessions SET summary_id = ? WHERE id = ?",[y,u])}mapRow(u){return{id:u.id,projectPath:u.project_path,startedAt:u.started_at,endedAt:u.ended_at??null,status:u.status,observationCount:u.observation_count,summaryId:u.summary_id??null}}}import{randomUUID as k0}from"crypto";class Wu{db;constructor(u){this.db=u}create(u){let y=k0(),B=new Date().toISOString();return this.db.run(`INSERT INTO session_summaries
550
+ embedding float[${J}] distance_metric=cosine
551
+ )`);$.run("INSERT OR REPLACE INTO _embedding_meta (key, value) VALUES (?, ?)",["dimension",String(J)])}class C${db;constructor($){this.db=$}create($,J){let V=new Date().toISOString();return this.db.run(`INSERT INTO sessions (id, project_path, started_at, status)
552
+ VALUES (?, ?, ?, 'active')`,[$,J,V]),this.getById($)}getOrCreate($,J){let V=this.getById($);if(V)return V;return this.create($,J)}getById($){let J=this.db.get("SELECT * FROM sessions WHERE id = ?",[$]);return J?this.mapRow(J):null}getRecent($,J=10){return this.db.all("SELECT * FROM sessions WHERE project_path = ? ORDER BY started_at DESC LIMIT ?",[$,J]).map((V)=>this.mapRow(V))}getAll($){return this.db.all("SELECT * FROM sessions WHERE project_path = ? ORDER BY started_at DESC",[$]).map((J)=>this.mapRow(J))}getActive(){return this.db.all("SELECT * FROM sessions WHERE status = 'active' ORDER BY started_at DESC").map(($)=>this.mapRow($))}updateStatus($,J){this.db.run("UPDATE sessions SET status = ? WHERE id = ?",[J,$])}markCompleted($){this.db.run("UPDATE sessions SET status = 'completed', ended_at = datetime('now') WHERE id = ?",[$])}incrementObservationCount($){this.db.run("UPDATE sessions SET observation_count = observation_count + 1 WHERE id = ?",[$])}setSummary($,J){this.db.run("UPDATE sessions SET summary_id = ? WHERE id = ?",[J,$])}mapRow($){return{id:$.id,projectPath:$.project_path,startedAt:$.started_at,endedAt:$.ended_at??null,status:$.status,observationCount:$.observation_count,summaryId:$.summary_id??null}}}import{randomUUID as SJ}from"crypto";class y${db;constructor($){this.db=$}create($){let J=SJ(),V=new Date().toISOString();return this.db.run(`INSERT INTO session_summaries
552
553
  (id, session_id, summary, key_decisions, files_modified,
553
554
  concepts, created_at, token_count,
554
555
  request, investigated, learned, completed, next_steps)
555
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[y,u.sessionId,u.summary,JSON.stringify(u.keyDecisions),JSON.stringify(u.filesModified),JSON.stringify(u.concepts),B,u.tokenCount,u.request??"",u.investigated??"",u.learned??"",u.completed??"",u.nextSteps??""]),{...u,id:y,createdAt:B}}importSummary(u){this.db.run(`INSERT INTO session_summaries
556
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[J,$.sessionId,$.summary,JSON.stringify($.keyDecisions),JSON.stringify($.filesModified),JSON.stringify($.concepts),V,$.tokenCount,$.request??"",$.investigated??"",$.learned??"",$.completed??"",$.nextSteps??""]),{...$,id:J,createdAt:V}}importSummary($){this.db.run(`INSERT INTO session_summaries
556
557
  (id, session_id, summary, key_decisions, files_modified,
557
558
  concepts, created_at, token_count,
558
559
  request, investigated, learned, completed, next_steps)
559
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[u.id,u.sessionId,u.summary,JSON.stringify(u.keyDecisions),JSON.stringify(u.filesModified),JSON.stringify(u.concepts),u.createdAt,u.tokenCount,u.request??"",u.investigated??"",u.learned??"",u.completed??"",u.nextSteps??""])}getBySessionId(u){let y=this.db.get("SELECT * FROM session_summaries WHERE session_id = ?",[u]);return y?this.mapRow(y):null}getRecent(u=10){return this.db.all("SELECT * FROM session_summaries ORDER BY created_at DESC LIMIT ?",[u]).map((y)=>this.mapRow(y))}search(u,y=10){return this.db.all(`SELECT ss.*
560
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[$.id,$.sessionId,$.summary,JSON.stringify($.keyDecisions),JSON.stringify($.filesModified),JSON.stringify($.concepts),$.createdAt,$.tokenCount,$.request??"",$.investigated??"",$.learned??"",$.completed??"",$.nextSteps??""])}getBySessionId($){let J=this.db.get("SELECT * FROM session_summaries WHERE session_id = ?",[$]);return J?this.mapRow(J):null}getRecent($=10){return this.db.all("SELECT * FROM session_summaries ORDER BY created_at DESC LIMIT ?",[$]).map((J)=>this.mapRow(J))}search($,J=10){return this.db.all(`SELECT ss.*
560
561
  FROM session_summaries ss
561
562
  JOIN summaries_fts fts ON ss._rowid = fts.rowid
562
563
  WHERE summaries_fts MATCH ?
563
564
  ORDER BY rank
564
- LIMIT ?`,[u,y]).map((B)=>this.mapRow(B))}mapRow(u){return{id:u.id,sessionId:u.session_id,summary:u.summary,keyDecisions:JSON.parse(u.key_decisions),filesModified:JSON.parse(u.files_modified),concepts:JSON.parse(u.concepts),createdAt:u.created_at,tokenCount:u.token_count,request:u.request||void 0,investigated:u.investigated||void 0,learned:u.learned||void 0,completed:u.completed||void 0,nextSteps:u.next_steps||void 0}}}class Hu{config;compressor;summarizer;pendingRepo;observationRepo;sessionRepo;summaryRepo;embeddingModel;conflictEvaluator;entityExtractor;entityRepo;observer;processing=!1;timer=null;mode="in-process";onEnqueue=null;constructor(u,y,B,$,A,J,K,V=null,R=null,z=null,N=null,E=null){this.config=u;this.compressor=y;this.summarizer=B;this.pendingRepo=$;this.observationRepo=A;this.sessionRepo=J;this.summaryRepo=K;this.embeddingModel=V;this.conflictEvaluator=R;this.entityExtractor=z;this.entityRepo=N;this.observer=E}setMode(u){if(this.mode=u,u==="enqueue-only")this.stop()}getMode(){return this.mode}setOnEnqueue(u){this.onEnqueue=u}enqueue(u,y,B,$){if(this.pendingRepo.create({sessionId:u,toolName:y,toolOutput:B,callId:$}),this.observer?.onEnqueue?.({sessionId:u,toolName:y,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 u=0,y=0,B=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(B).toISOString()}),$.length===0)return 0;for(let A of $)try{this.pendingRepo.markProcessing(A.id);let K=await this.compressor.compress(A.toolName,A.toolOutput)??this.compressor.createFallbackObservation(A.toolName,A.toolOutput),V=!1,R=null;if(this.embeddingModel)try{let N=Ru({title:K.title,narrative:K.narrative,concepts:K.concepts}),E=await zu(this.embeddingModel,N);if(E){let H=this.config.conflictResolutionEnabled&&this.conflictEvaluator,Q=this.config.conflictSimilarityBandLow??0.7,U=this.config.conflictSimilarityBandHigh??0.92;if(H){let k=this.observationRepo.findSimilar(E,K.type,Q,5),M=k.find((f)=>f.similarity>U);if(M)console.log(`[open-mem] Dedup: skipping duplicate of ${M.id} (similarity: ${M.similarity.toFixed(3)})`),V=!0;else{let f=k.filter((Z)=>Z.similarity>=Q&&Z.similarity<=U);if(f.length>0)try{let Z=f.map((S)=>{let Y=this.observationRepo.getById(S.id);return Y?{id:Y.id,title:Y.title,narrative:Y.narrative,concepts:Y.concepts,type:Y.type}:null}).filter((S)=>S!==null);if(Z.length>0&&this.conflictEvaluator){let S=await this.conflictEvaluator.evaluate({title:K.title,narrative:K.narrative,concepts:K.concepts,type:K.type},Z);if(S&&S.outcome==="duplicate")console.log(`[open-mem] Conflict eval: duplicate (${S.reason})`),V=!0;else if(S&&S.outcome==="update"&&S.supersedesId)console.log(`[open-mem] Conflict eval: update supersedes ${S.supersedesId} (${S.reason})`),R=S.supersedesId}}catch{}}}else{let k=this.observationRepo.findSimilar(E,K.type,0.92,1);if(k.length>0)console.log(`[open-mem] Dedup: skipping duplicate of ${k[0].id} (similarity: ${k[0].similarity.toFixed(3)})`),V=!0}}}catch{}if(V){this.pendingRepo.markCompleted(A.id);continue}let z=this.observationRepo.create({sessionId:A.sessionId,type:K.type,title:K.title,subtitle:K.subtitle,facts:K.facts,narrative:K.narrative,concepts:K.concepts,filesRead:K.filesRead,filesModified:K.filesModified,rawToolOutput:A.toolOutput,toolName:A.toolName,tokenCount:P(`${K.title} ${K.narrative} ${K.facts.join(" ")}`),discoveryTokens:K.discoveryTokens??P(A.toolOutput),importance:K.importance??3});if(this.embeddingModel)try{let N=Ru({title:z.title,narrative:z.narrative,concepts:z.concepts}),E=await zu(this.embeddingModel,N);if(E)this.observationRepo.setEmbedding(z.id,E)}catch{}if(R)try{this.observationRepo.supersede(R,z.id),console.log(`[open-mem] Superseded observation ${R} with ${z.id}`)}catch(N){console.error(`[open-mem] Failed to supersede ${R}:`,N)}if(this.config.entityExtractionEnabled&&this.entityExtractor&&this.entityRepo)try{let N=await this.entityExtractor.extract({title:z.title,narrative:z.narrative,concepts:z.concepts,facts:z.facts,filesRead:z.filesRead,filesModified:z.filesModified,type:z.type});if(N){let E=new Map;for(let H of N.entities){let Q=this.entityRepo.upsertEntity(H.name,H.entityType);E.set(H.name,Q.id),this.entityRepo.linkObservation(Q.id,z.id)}for(let H of N.relations){let Q=E.get(H.sourceName),U=E.get(H.targetName);if(Q&&U)this.entityRepo.createRelation(Q,U,H.relationship,z.id)}}}catch{}this.sessionRepo.incrementObservationCount(A.sessionId),this.pendingRepo.markCompleted(A.id),u++}catch(J){this.pendingRepo.markFailed(A.id,String(J)),y++,this.observer?.onItemFailed?.({pendingId:A.id,error:String(J),failedAt:new Date().toISOString()})}return u}finally{this.observer?.onBatchEnd?.({processed:u,failed:y,durationMs:Date.now()-B,finishedAt:new Date().toISOString()}),this.processing=!1}}async summarizeSession(u){let y=this.observationRepo.getBySession(u);if(!this.summarizer.shouldSummarize(y.length))return;if(this.summaryRepo.getBySessionId(u))return;let $=await this.summarizer.summarize(u,y);if(!$)return;let A=this.summaryRepo.create({sessionId:u,summary:$.summary,keyDecisions:$.keyDecisions,filesModified:$.filesModified,concepts:$.concepts,tokenCount:P($.summary)});this.sessionRepo.setSummary(u,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}}}import{spawnSync as $y}from"child_process";import{dirname as M0,resolve as Ay}from"path";function f0(u){try{let y=$y("git",["rev-parse","--git-common-dir"],{cwd:u,encoding:"utf-8",timeout:5000});if(y.status!==0||!y.stdout)return null;let B=y.stdout.trim();if(B===".git")return null;let $=$y("git",["rev-parse","--git-dir"],{cwd:u,encoding:"utf-8",timeout:5000});if($.status!==0||!$.stdout)return null;let A=$.stdout.trim(),J=Ay(u,B),K=Ay(u,A);if(J===K)return null;let V=M0(J);if(V===J||V==="/")return null;return V}catch{return null}}function Jy(u){return f0(u)??u}function Qu(u){process.stdout.write(`${JSON.stringify(u)}
565
- `)}function Y0(){let{values:u}=X0({options:{project:{type:"string",short:"p"},"http-port":{type:"string"}},strict:!1}),y=typeof u.project==="string"?u.project:process.cwd(),B=u["http-port"],$=typeof B==="string"&&Number.parseInt(B,10)>0?Number.parseInt(B,10):void 0;return{projectDir:y,httpPort:$}}function D0(u,y){if(u==="claude-code"&&!y.platformClaudeCodeEnabled)throw Error("Claude Code adapter is disabled. Set OPEN_MEM_PLATFORM_CLAUDE_CODE=true.");if(u==="cursor"&&!y.platformCursorEnabled)throw Error("Cursor adapter is disabled. Set OPEN_MEM_PLATFORM_CURSOR=true.")}function m0(u,y){let B=Jy(y),$=su(B);D0(u,$),r.enableExtensionSupport();let A=au($.dbPath);By(A,{hasVectorExtension:A.hasVectorExtension,embeddingDimension:$.embeddingDimension});let J=new Eu(A),K=new Vu(A),V=new Wu(A),R=new Nu(A),z=new w($),N=new $u($),E=$.provider!=="bedrock",H=$.compressionEnabled&&(!E||$.apiKey)?bu({provider:$.provider,model:$.model,apiKey:$.apiKey}):null,Q=$.conflictResolutionEnabled&&(!E||$.apiKey)?new yu({provider:$.provider,apiKey:$.apiKey,model:$.model,rateLimitingEnabled:$.rateLimitingEnabled}):null,U=$.entityExtractionEnabled&&(!E||$.apiKey)?new Bu({provider:$.provider,apiKey:$.apiKey,model:$.model,rateLimitingEnabled:$.rateLimitingEnabled}):null,k=new Ku(A),M=new Hu($,z,N,R,K,J,V,H,Q,U,k),f=u==="claude-code"?Mu():Lu(),Z=new e({adapter:f,queue:M,sessions:J,observations:K,pendingMessages:R,projectPath:B,config:$});return{db:A,queue:M,runtime:Z,platform:u,projectPath:B}}function Ky(u,y){let B=u.queue.getStats();return{id:y,ok:!0,code:"OK",status:{platform:u.platform,projectPath:u.projectPath,queue:{mode:u.queue.getMode(),running:u.queue.isRunning,processing:B.processing,pending:B.pending}}}}function zy(u){if(!u||typeof u!=="object"||Array.isArray(u))return{command:"event",payload:u};let y=u,B=typeof y.command==="string"&&(y.command==="event"||y.command==="flush"||y.command==="health"||y.command==="shutdown")?y.command:void 0,$=typeof y.id==="string"||typeof y.id==="number"?y.id:void 0;if(!B)return{command:"event",payload:u,id:$};return{id:$,command:B,payload:"payload"in y?y.payload:void 0}}async function Ry(u){let y=Y0(),B=m0(u,y.projectDir);B.queue.start();let $=!1,A=async()=>{if($)return;$=!0;try{await B.queue.processBatch()}catch{}B.queue.stop(),B.db.close(),process.exit(0)},J=async(R)=>{let z=R.command??"event";if(z==="health")return Ky(B,R.id);if(z==="flush"){let E=await B.queue.processBatch();return{id:R.id,ok:!0,code:"OK",processed:E}}if(z==="shutdown")return{id:R.id,ok:!0,code:"OK",message:"shutting down"};if(!await B.runtime.ingestRaw(R.payload))return{id:R.id,ok:!1,code:"UNSUPPORTED_EVENT",message:"Payload did not match adapter event schema"};return{id:R.id,ok:!0,code:"OK",ingested:!0}};if(y.httpPort)Zu("127.0.0.1","Platform worker HTTP server"),Bun.serve({port:y.httpPort,hostname:"127.0.0.1",idleTimeout:0,fetch:async(z)=>{if(z.method==="GET"&&new URL(z.url).pathname==="/v1/health")return Response.json(Ky(B));if(z.method==="POST"&&new URL(z.url).pathname==="/v1/events"){let N;try{N=await z.json()}catch{return Response.json({ok:!1,code:"INVALID_JSON",message:"Invalid JSON payload"},{status:400})}let E=zy(N);try{let H=await J(E);if((E.command??"event")==="shutdown")setTimeout(()=>{A()},0);return Response.json(H,{status:H.ok?200:422})}catch(H){return Response.json({ok:!1,code:"INGESTION_FAILED",message:String(H)},{status:500})}}return Response.json({ok:!1,code:"NOT_FOUND"},{status:404})}});process.on("SIGINT",()=>{A()}),process.on("SIGTERM",()=>{A()});let K=Promise.resolve(),V=L0({input:process.stdin,terminal:!1});V.on("line",(R)=>{let z=R.trim();if(!z)return;K=K.then(async()=>{let N;try{N=JSON.parse(z)}catch{Qu({ok:!1,code:"INVALID_JSON",message:"Invalid JSON payload"});return}try{let E=zy(N),H=await J(E);if(Qu(H),(E.command??"event")==="shutdown")await A()}catch(E){Qu({ok:!1,code:"INGESTION_FAILED",message:String(E)})}})}),V.on("close",()=>{K.finally(()=>A())})}Ry("cursor");
565
+ LIMIT ?`,[$,J]).map((V)=>this.mapRow(V))}mapRow($){return{id:$.id,sessionId:$.session_id,summary:$.summary,keyDecisions:JSON.parse($.key_decisions),filesModified:JSON.parse($.files_modified),concepts:JSON.parse($.concepts),createdAt:$.created_at,tokenCount:$.token_count,request:$.request||void 0,investigated:$.investigated||void 0,learned:$.learned||void 0,completed:$.completed||void 0,nextSteps:$.next_steps||void 0}}}class O${config;compressor;summarizer;pendingRepo;observationRepo;sessionRepo;summaryRepo;embeddingModel;conflictEvaluator;entityExtractor;entityRepo;observer;processing=!1;timer=null;mode="in-process";onEnqueue=null;constructor($,J,V,Z,X,H,K,z=null,B=null,Y=null,Q=null,U=null){this.config=$;this.compressor=J;this.summarizer=V;this.pendingRepo=Z;this.observationRepo=X;this.sessionRepo=H;this.summaryRepo=K;this.embeddingModel=z;this.conflictEvaluator=B;this.entityExtractor=Y;this.entityRepo=Q;this.observer=U}setMode($){if(this.mode=$,$==="enqueue-only")this.stop()}getMode(){return this.mode}setOnEnqueue($){this.onEnqueue=$}enqueue($,J,V,Z){if(this.pendingRepo.create({sessionId:$,toolName:J,toolOutput:V,callId:Z}),this.observer?.onEnqueue?.({sessionId:$,toolName:J,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 $=0,J=0,V=Date.now();try{this.pendingRepo.resetStale(5);let Z=this.pendingRepo.getPending(this.config.batchSize);if(this.observer?.onBatchStart?.({pending:Z.length,mode:this.mode,startedAt:new Date(V).toISOString()}),Z.length===0)return 0;for(let X of Z)try{this.pendingRepo.markProcessing(X.id);let K=await this.compressor.compress(X.toolName,X.toolOutput)??this.compressor.createFallbackObservation(X.toolName,X.toolOutput),z=!1,B=null;if(this.embeddingModel)try{let Q=L$({title:K.title,narrative:K.narrative,concepts:K.concepts}),U=await D$(this.embeddingModel,Q);if(U){let A=this.config.conflictResolutionEnabled&&this.conflictEvaluator,W=this.config.conflictSimilarityBandLow??0.7,M=this.config.conflictSimilarityBandHigh??0.92;if(A){let D=this.observationRepo.findSimilar(U,K.type,W,5),L=D.find((_)=>_.similarity>M);if(L)console.log(`[open-mem] Dedup: skipping duplicate of ${L.id} (similarity: ${L.similarity.toFixed(3)})`),z=!0;else{let _=D.filter((G)=>G.similarity>=W&&G.similarity<=M);if(_.length>0)try{let G=_.map((F)=>{let R=this.observationRepo.getById(F.id);return R?{id:R.id,title:R.title,narrative:R.narrative,concepts:R.concepts,type:R.type}:null}).filter((F)=>F!==null);if(G.length>0&&this.conflictEvaluator){let F=await this.conflictEvaluator.evaluate({title:K.title,narrative:K.narrative,concepts:K.concepts,type:K.type},G);if(F&&F.outcome==="duplicate")console.log(`[open-mem] Conflict eval: duplicate (${F.reason})`),z=!0;else if(F&&F.outcome==="update"&&F.supersedesId)console.log(`[open-mem] Conflict eval: update supersedes ${F.supersedesId} (${F.reason})`),B=F.supersedesId}}catch{}}}else{let D=this.observationRepo.findSimilar(U,K.type,0.92,1);if(D.length>0)console.log(`[open-mem] Dedup: skipping duplicate of ${D[0].id} (similarity: ${D[0].similarity.toFixed(3)})`),z=!0}}}catch{}if(z){this.pendingRepo.markCompleted(X.id);continue}let Y=this.observationRepo.create({sessionId:X.sessionId,type:K.type,title:K.title,subtitle:K.subtitle,facts:K.facts,narrative:K.narrative,concepts:K.concepts,filesRead:K.filesRead,filesModified:K.filesModified,rawToolOutput:X.toolOutput,toolName:X.toolName,tokenCount:f(`${K.title} ${K.narrative} ${K.facts.join(" ")}`),discoveryTokens:K.discoveryTokens??f(X.toolOutput),importance:K.importance??3});if(this.embeddingModel)try{let Q=L$({title:Y.title,narrative:Y.narrative,concepts:Y.concepts}),U=await D$(this.embeddingModel,Q);if(U)this.observationRepo.setEmbedding(Y.id,U)}catch{}if(B)try{this.observationRepo.supersede(B,Y.id),console.log(`[open-mem] Superseded observation ${B} with ${Y.id}`)}catch(Q){console.error(`[open-mem] Failed to supersede ${B}:`,Q)}if(this.config.entityExtractionEnabled&&this.entityExtractor&&this.entityRepo)try{let Q=await this.entityExtractor.extract({title:Y.title,narrative:Y.narrative,concepts:Y.concepts,facts:Y.facts,filesRead:Y.filesRead,filesModified:Y.filesModified,type:Y.type});if(Q){let U=new Map;for(let A of Q.entities){let W=this.entityRepo.upsertEntity(A.name,A.entityType);U.set(A.name,W.id),this.entityRepo.linkObservation(W.id,Y.id)}for(let A of Q.relations){let W=U.get(A.sourceName),M=U.get(A.targetName);if(W&&M)this.entityRepo.createRelation(W,M,A.relationship,Y.id)}}}catch{}this.sessionRepo.incrementObservationCount(X.sessionId),this.pendingRepo.markCompleted(X.id),$++}catch(H){this.pendingRepo.markFailed(X.id,String(H)),J++,this.observer?.onItemFailed?.({pendingId:X.id,error:String(H),failedAt:new Date().toISOString()})}return $}finally{this.observer?.onBatchEnd?.({processed:$,failed:J,durationMs:Date.now()-V,finishedAt:new Date().toISOString()}),this.processing=!1}}async summarizeSession($){let J=this.observationRepo.getBySession($);if(!this.summarizer.shouldSummarize(J.length))return;if(this.summaryRepo.getBySessionId($))return;let Z=await this.summarizer.summarize($,J);if(!Z)return;let X=this.summaryRepo.create({sessionId:$,summary:Z.summary,keyDecisions:Z.keyDecisions,filesModified:Z.filesModified,concepts:Z.concepts,tokenCount:f(Z.summary)});this.sessionRepo.setSummary($,X.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}}}function x1($){return{start:()=>$.start(),stop:()=>{$.setOnEnqueue(null),$.stop()},setInProcess:()=>{$.setOnEnqueue(null),$.setMode("in-process"),$.start()},setEnqueueOnly:(J)=>{$.setMode("enqueue-only"),$.setOnEnqueue(J)}}}import{spawnSync as f1}from"child_process";import{dirname as kJ,resolve as I1}from"path";function TJ($){try{let J=f1("git",["rev-parse","--git-common-dir"],{cwd:$,encoding:"utf-8",timeout:5000});if(J.status!==0||!J.stdout)return null;let V=J.stdout.trim();if(V===".git")return null;let Z=f1("git",["rev-parse","--git-dir"],{cwd:$,encoding:"utf-8",timeout:5000});if(Z.status!==0||!Z.stdout)return null;let X=Z.stdout.trim(),H=I1($,V),K=I1($,X);if(H===K)return null;let z=kJ(H);if(z===H||z==="/")return null;return z}catch{return null}}function u1($){return TJ($)??$}function S$($,J){if(J)console.warn(`[open-mem] ${J}`);if($.queueRuntime.setInProcess(),$.daemonLivenessTimer)clearInterval($.daemonLivenessTimer),$.daemonLivenessTimer=null}function E$($){process.stdout.write(`${JSON.stringify($)}
566
+ `)}function xJ(){let{values:$}=qJ({options:{project:{type:"string",short:"p"},"http-port":{type:"string"}},strict:!1}),J=typeof $.project==="string"?$.project:process.cwd(),V=$["http-port"],Z=typeof V==="string"&&Number.parseInt(V,10)>0?Number.parseInt(V,10):void 0;return{projectDir:J,httpPort:Z}}function fJ($,J){if($==="claude-code"&&!J.platformClaudeCodeEnabled)throw Error("Claude Code adapter is disabled. Set OPEN_MEM_PLATFORM_CLAUDE_CODE=true.");if($==="cursor"&&!J.platformCursorEnabled)throw Error("Cursor adapter is disabled. Set OPEN_MEM_PLATFORM_CURSOR=true.")}function IJ($,J){let V=u1(J),Z=z1(V);fJ($,Z);let X=$==="claude-code"?"platform-worker-claude":"platform-worker-cursor",H=F1(Z.dbPath,$==="claude-code"?"claude":"cursor");a.enableExtensionSupport();let K=k1(Z.dbPath,{processRole:X});q1(K,{hasVectorExtension:K.hasVectorExtension,embeddingDimension:Z.embeddingDimension});let z=new C$(K),B=new _$(K),Y=new y$(K),Q=new R$(K),U=new m(Z),A=new Q$(Z),W=Z.provider!=="bedrock",M=Z.compressionEnabled&&(!W||Z.apiKey)?X1({provider:Z.provider,model:Z.model,apiKey:Z.apiKey}):null,D=Z.conflictResolutionEnabled&&(!W||Z.apiKey)?new z$({provider:Z.provider,apiKey:Z.apiKey,model:Z.model,rateLimitingEnabled:Z.rateLimitingEnabled}):null,L=Z.entityExtractionEnabled&&(!W||Z.apiKey)?new B$({provider:Z.provider,apiKey:Z.apiKey,model:Z.model,rateLimitingEnabled:Z.rateLimitingEnabled}):null,_=new M$(K),G=new O$(Z,U,A,Q,B,z,Y,M,D,L,_),F=x1(G),R=$==="claude-code"?f$():u$(),e=new H$({adapter:R,queue:G,sessions:z,observations:B,pendingMessages:Q,projectPath:V,config:Z}),y={db:K,queue:G,queueRuntime:F,runtime:e,platform:$,projectPath:V,daemonManager:null,daemonLivenessTimer:null,daemonConfigured:Z.daemonEnabled,workerPidPath:H};if(Z.daemonEnabled)if(y.daemonManager=new N$({dbPath:Z.dbPath,projectPath:V,daemonScript:""}),y.daemonManager.getStatus().running)F.setEnqueueOnly(()=>{let k$=y.daemonManager?.signal("PROCESS_NOW");if(!k$?.ok)console.warn(`[open-mem] Daemon signal failed (${k$?.state??"no-daemon"}), falling back to in-process processing`),S$(y)}),y.daemonLivenessTimer=setInterval(()=>{if(!y.daemonManager||!y.daemonManager.getStatus().running)console.warn("[open-mem] Daemon died, falling back to in-process processing"),S$(y)},30000);else F.setInProcess();else F.setInProcess();return y}function w1($,J){let V=$.queue.getStats(),Z=$.daemonManager?.getStatus()??null;return{id:J,ok:!0,code:"OK",status:{platform:$.platform,projectPath:$.projectPath,queue:{mode:$.queue.getMode(),running:$.queue.isRunning,processing:V.processing,pending:V.pending},daemon:{enabled:$.daemonConfigured,running:Z?.running??!1,pid:Z?.pid??null}}}}function P1($){if(!$||typeof $!=="object"||Array.isArray($))return{command:"event",payload:$};let J=$,V=typeof J.command==="string"&&(J.command==="event"||J.command==="flush"||J.command==="health"||J.command==="shutdown")?J.command:void 0,Z=typeof J.id==="string"||typeof J.id==="number"?J.id:void 0;if(!V)return{command:"event",payload:$,id:Z};return{id:Z,command:V,payload:"payload"in J?J.payload:void 0}}async function v1($){let J=xJ(),V=IJ($,J.projectDir);W1(V.workerPidPath);let Z=!1,X=()=>{A$(V.workerPidPath,process.pid)},H=async()=>{if(Z)return;Z=!0;try{await V.queue.processBatch()}catch{}try{if(V.daemonLivenessTimer)clearInterval(V.daemonLivenessTimer),V.daemonLivenessTimer=null;V.queueRuntime.stop(),V.db.close()}finally{X(),process.exit(0)}},K=async(Y)=>{let Q=Y.command??"event";if(Q==="health")return w1(V,Y.id);if(Q==="flush"){if(V.queue.getMode()==="enqueue-only"&&V.daemonManager){let M=V.daemonManager.signal("PROCESS_NOW");if(!M.ok)S$(V,`Daemon signal failed (${M.state}), falling back to in-process processing`);else return{id:Y.id,ok:!0,code:"ENQUEUED",message:"Daemon signaled; flush is asynchronous in enqueue-only mode"}}let W=await V.queue.processBatch();return{id:Y.id,ok:!0,code:"OK",processed:W}}if(Q==="shutdown")return{id:Y.id,ok:!0,code:"OK",message:"shutting down"};if(!await V.runtime.ingestRaw(Y.payload))return{id:Y.id,ok:!1,code:"UNSUPPORTED_EVENT",message:"Payload did not match adapter event schema"};return{id:Y.id,ok:!0,code:"OK",ingested:!0}};if(J.httpPort)T$("127.0.0.1","Platform worker HTTP server"),Bun.serve({port:J.httpPort,hostname:"127.0.0.1",idleTimeout:0,fetch:async(Q)=>{if(Q.method==="GET"&&new URL(Q.url).pathname==="/v1/health")return Response.json(w1(V));if(Q.method==="POST"&&new URL(Q.url).pathname==="/v1/events"){let U;try{U=await Q.json()}catch{return Response.json({ok:!1,code:"INVALID_JSON",message:"Invalid JSON payload"},{status:400})}let A=P1(U);try{let W=await K(A);if((A.command??"event")==="shutdown")setTimeout(()=>{H()},0);return Response.json(W,{status:W.ok?200:422})}catch(W){return Response.json({ok:!1,code:"INGESTION_FAILED",message:String(W)},{status:500})}}return Response.json({ok:!1,code:"NOT_FOUND"},{status:404})}});process.on("SIGINT",()=>{H()}),process.on("SIGTERM",()=>{H()});let z=Promise.resolve(),B=jJ({input:process.stdin,terminal:!1});B.on("line",(Y)=>{let Q=Y.trim();if(!Q)return;z=z.then(async()=>{let U;try{U=JSON.parse(Q)}catch{E$({ok:!1,code:"INVALID_JSON",message:"Invalid JSON payload"});return}try{let A=P1(U),W=await K(A);if(E$(W),(A.command??"event")==="shutdown")await H()}catch(A){E$({ok:!1,code:"INGESTION_FAILED",message:String(A)})}})}),B.on("close",()=>{z.finally(()=>H())})}v1("cursor");