open-mem 0.7.0 → 0.7.1

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.
Files changed (111) hide show
  1. package/CHANGELOG.md +23 -3
  2. package/README.md +77 -27
  3. package/dist/adapters/http/server.d.ts +15 -1
  4. package/dist/adapters/http/server.d.ts.map +1 -1
  5. package/dist/adapters/http/sse.d.ts +16 -1
  6. package/dist/adapters/http/sse.d.ts.map +1 -1
  7. package/dist/adapters/mcp/server.d.ts +25 -1
  8. package/dist/adapters/mcp/server.d.ts.map +1 -1
  9. package/dist/adapters/opencode/tools.d.ts.map +1 -1
  10. package/dist/adapters/platform/bridge-client.d.ts +32 -0
  11. package/dist/adapters/platform/bridge-client.d.ts.map +1 -0
  12. package/dist/adapters/platform/builtin.d.ts +6 -0
  13. package/dist/adapters/platform/builtin.d.ts.map +1 -0
  14. package/dist/adapters/platform/claude-code.d.ts +7 -0
  15. package/dist/adapters/platform/claude-code.d.ts.map +1 -0
  16. package/dist/adapters/platform/cursor.d.ts +7 -0
  17. package/dist/adapters/platform/cursor.d.ts.map +1 -0
  18. package/dist/adapters/platform/index.d.ts +9 -0
  19. package/dist/adapters/platform/index.d.ts.map +1 -0
  20. package/dist/adapters/platform/normalize.d.ts +14 -0
  21. package/dist/adapters/platform/normalize.d.ts.map +1 -0
  22. package/dist/adapters/platform/opencode.d.ts +7 -0
  23. package/dist/adapters/platform/opencode.d.ts.map +1 -0
  24. package/dist/adapters/platform/runtime.d.ts +27 -0
  25. package/dist/adapters/platform/runtime.d.ts.map +1 -0
  26. package/dist/adapters/platform/types.d.ts +53 -0
  27. package/dist/adapters/platform/types.d.ts.map +1 -0
  28. package/dist/ai/compressor.d.ts.map +1 -1
  29. package/dist/ai/conflict-evaluator.d.ts.map +1 -1
  30. package/dist/ai/entity-extractor.d.ts +2 -2
  31. package/dist/ai/entity-extractor.d.ts.map +1 -1
  32. package/dist/ai/parser.d.ts.map +1 -1
  33. package/dist/ai/prompts.d.ts.map +1 -1
  34. package/dist/ai/summarizer.d.ts.map +1 -1
  35. package/dist/claude-code.d.ts +3 -0
  36. package/dist/claude-code.d.ts.map +1 -0
  37. package/dist/claude-code.js +551 -0
  38. package/dist/config/store.d.ts.map +1 -1
  39. package/dist/config.d.ts.map +1 -1
  40. package/dist/context/builder.d.ts.map +1 -1
  41. package/dist/contracts/api.d.ts +129 -0
  42. package/dist/contracts/api.d.ts.map +1 -0
  43. package/dist/core/contracts.d.ts +67 -1
  44. package/dist/core/contracts.d.ts.map +1 -1
  45. package/dist/core/memory-engine.d.ts +33 -2
  46. package/dist/core/memory-engine.d.ts.map +1 -1
  47. package/dist/cursor.d.ts +3 -0
  48. package/dist/cursor.d.ts.map +1 -0
  49. package/dist/cursor.js +551 -0
  50. package/dist/daemon.js +146 -122
  51. package/dist/dashboard/assets/index-BTEnO15N.js +63 -0
  52. package/dist/dashboard/assets/index-o3hCx7_v.css +1 -0
  53. package/dist/dashboard/index.html +2 -2
  54. package/dist/db/config-audit.d.ts +10 -0
  55. package/dist/db/config-audit.d.ts.map +1 -0
  56. package/dist/db/entities.d.ts.map +1 -1
  57. package/dist/db/maintenance-history.d.ts +9 -0
  58. package/dist/db/maintenance-history.d.ts.map +1 -0
  59. package/dist/db/observations.d.ts +12 -0
  60. package/dist/db/observations.d.ts.map +1 -1
  61. package/dist/db/schema.d.ts +3 -1
  62. package/dist/db/schema.d.ts.map +1 -1
  63. package/dist/db/user-memory.d.ts.map +1 -1
  64. package/dist/hooks/chat-capture.d.ts +11 -0
  65. package/dist/hooks/chat-capture.d.ts.map +1 -1
  66. package/dist/hooks/context-inject.d.ts.map +1 -1
  67. package/dist/hooks/session-events.d.ts +10 -0
  68. package/dist/hooks/session-events.d.ts.map +1 -1
  69. package/dist/hooks/tool-capture.d.ts +12 -0
  70. package/dist/hooks/tool-capture.d.ts.map +1 -1
  71. package/dist/index.d.ts +5 -3
  72. package/dist/index.d.ts.map +1 -1
  73. package/dist/index.js +223 -225
  74. package/dist/maintenance.js +130 -106
  75. package/dist/mcp.js +184 -187
  76. package/dist/platform-worker.d.ts +3 -0
  77. package/dist/platform-worker.d.ts.map +1 -0
  78. package/dist/queue/processor.d.ts +26 -1
  79. package/dist/queue/processor.d.ts.map +1 -1
  80. package/dist/runtime/metrics.d.ts +43 -0
  81. package/dist/runtime/metrics.d.ts.map +1 -0
  82. package/dist/search/graph.d.ts.map +1 -1
  83. package/dist/search/orchestrator.d.ts +1 -0
  84. package/dist/search/orchestrator.d.ts.map +1 -1
  85. package/dist/search/reranker.d.ts +1 -1
  86. package/dist/search/reranker.d.ts.map +1 -1
  87. package/dist/store/ports.d.ts +9 -0
  88. package/dist/store/ports.d.ts.map +1 -1
  89. package/dist/store/sqlite/adapters.d.ts.map +1 -1
  90. package/dist/tools/recall.d.ts.map +1 -1
  91. package/dist/tools/save.d.ts +1 -1
  92. package/dist/tools/save.d.ts.map +1 -1
  93. package/dist/types.d.ts +64 -0
  94. package/dist/types.d.ts.map +1 -1
  95. package/dist/utils/agents-md.d.ts.map +1 -1
  96. package/dist/utils/folder-context-maintenance.d.ts.map +1 -1
  97. package/package.json +27 -6
  98. package/dist/dashboard/assets/index-9JxqY10c.css +0 -1
  99. package/dist/dashboard/assets/index-DWbZtwHB.js +0 -60
  100. package/dist/dashboard/dist/assets/index-9JxqY10c.css +0 -1
  101. package/dist/dashboard/dist/assets/index-CGCNZcwT.js +0 -60
  102. package/dist/dashboard/dist/assets/index-CI60x_dC.css +0 -1
  103. package/dist/dashboard/dist/assets/index-CTwrdVhA.js +0 -60
  104. package/dist/dashboard/dist/assets/index-DWbZtwHB.js +0 -60
  105. package/dist/dashboard/dist/index.html +0 -19
  106. package/dist/servers/http-server.d.ts +0 -22
  107. package/dist/servers/http-server.d.ts.map +0 -1
  108. package/dist/servers/mcp-server.d.ts +0 -27
  109. package/dist/servers/mcp-server.d.ts.map +0 -1
  110. package/dist/servers/sse-broadcaster.d.ts +0 -27
  111. package/dist/servers/sse-broadcaster.d.ts.map +0 -1
package/dist/index.js CHANGED
@@ -1,45 +1,24 @@
1
1
  // @bun
2
- var _2=Object.create;var{getPrototypeOf:F2,defineProperty:D$,getOwnPropertyNames:E2}=Object;var L2=Object.prototype.hasOwnProperty;var H2=($,f,J)=>{J=$!=null?_2(F2($)):{};let Q=f||!$||!$.__esModule?D$(J,"default",{value:$,enumerable:!0}):J;for(let M of E2($))if(!L2.call(Q,M))D$(Q,M,{get:()=>$[M],enumerable:!0});return Q};var I=import.meta.require;import{existsSync as c5}from"fs";import{dirname as p5,join as g}from"path";import{fileURLToPath as n5}from"url";import{z}from"zod";var N0=z.enum(["decision","bugfix","feature","refactor","discovery","change"]),C$=z.object({query:z.string().describe("Search query (supports keywords, phrases, file paths)"),type:N0.optional().describe("Filter by observation type"),limit:z.number().min(1).max(50).default(10).describe("Maximum number of results"),importance_min:z.number().min(1).max(5).optional().describe("Minimum importance (1-5)"),importance_max:z.number().min(1).max(5).optional().describe("Maximum importance (1-5)"),after:z.string().optional().describe("Only observations after this date (ISO 8601)"),before:z.string().optional().describe("Only observations before this date (ISO 8601)"),concepts:z.array(z.string()).optional().describe("Filter by concepts"),files:z.array(z.string()).optional().describe("Filter by file paths")}),j$=z.object({limit:z.number().min(1).max(20).default(5).describe("Number of recent sessions to show"),sessionId:z.string().optional().describe("Show details for a specific session ID")}),R$=z.object({ids:z.array(z.string()).describe("Observation IDs to fetch"),limit:z.number().min(1).max(50).default(10).describe("Maximum number of results")}),k$=z.object({title:z.string().describe("Brief title for the observation (max 80 chars)"),type:N0.describe("Type of observation"),narrative:z.string().describe("Detailed description of what to remember"),concepts:z.array(z.string()).optional().describe("Related concepts/tags"),files:z.array(z.string()).optional().describe("Related file paths"),importance:z.number().int().min(1).max(5).optional().describe("Importance score (1-5, default 3)"),scope:z.enum(["project","user"]).optional().default("project").describe("Memory scope")}),T$=z.object({id:z.string().describe("Observation ID to update"),title:z.string().optional().describe("Updated title"),narrative:z.string().optional().describe("Updated narrative"),type:N0.optional().describe("Updated observation type"),concepts:z.array(z.string()).optional().describe("Updated concepts"),importance:z.number().int().min(1).max(5).optional().describe("Updated importance")}),I$=z.object({id:z.string().describe("Observation ID to delete")}),x$=z.object({format:z.enum(["json"]).default("json"),type:N0.optional(),limit:z.number().min(1).optional()}),P$=z.object({data:z.string().describe("JSON string from a mem-export output"),mode:z.enum(["skip-duplicates","overwrite"]).optional().default("skip-duplicates")});function O2($,f){let J=[],Q=f==="user"?" [USER]":"";if(J.push(`## [${$.type.toUpperCase()}]${Q} ${$.title}`),$.subtitle)J.push(`*${$.subtitle}*`);if(J.push(`
3
- ${$.narrative}`),$.facts.length>0){J.push(`
4
- **Facts:**`);for(let M of $.facts)J.push(`- ${M}`)}if($.concepts.length>0)J.push(`
5
- **Concepts:** ${$.concepts.join(", ")}`);if($.filesRead.length>0)J.push(`**Files read:** ${$.filesRead.join(", ")}`);if($.filesModified.length>0)J.push(`**Files modified:** ${$.filesModified.join(", ")}`);return J.push(`
6
- *ID: ${$.id} | Created: ${$.createdAt} | Tokens: ${$.tokenCount}*`),J.join(`
7
- `)}function D2($){let f=[`Found ${$.length} observation(s):
8
- `];for(let J of $){let Q=J.observation,M=J.source==="user"?" [USER]":"";if(f.push(`## [${Q.type.toUpperCase()}]${M} ${Q.title}`),f.push(`**ID:** \`${Q.id}\``),Q.subtitle)f.push(`*${Q.subtitle}*`);if(f.push(`
9
- ${Q.narrative}`),Q.facts.length>0){f.push(`
10
- **Facts:**`);for(let X of Q.facts)f.push(`- ${X}`)}if(Q.concepts.length>0)f.push(`
11
- **Concepts:** ${Q.concepts.join(", ")}`);if(Q.filesModified.length>0)f.push(`**Files modified:** ${Q.filesModified.join(", ")}`);if(Q.filesRead.length>0)f.push(`**Files read:** ${Q.filesRead.join(", ")}`);f.push(`
12
- *Session: ${Q.sessionId} | ${Q.createdAt}*`),f.push("---")}return f.push("\n\uD83D\uDCA1 Use `mem-recall` with observation IDs above to get full details."),f.join(`
13
- `)}function w$($){return{"mem-search":{description:"Layer 1: quick search over memory using hybrid retrieval.",args:C$.shape,execute:async(f)=>{try{let J=C$.parse(f),Q=await $.search(J.query,{type:J.type,limit:J.limit,importanceMin:J.importance_min,importanceMax:J.importance_max,after:J.after,before:J.before,concepts:J.concepts,files:J.files});if(Q.length===0)return"No matching observations found.";return D2(Q)}catch(J){return`Search error: ${J}`}}},"mem-timeline":{description:"Layer 2: browse session-level history and summaries.",args:j$.shape,execute:async(f)=>{try{let J=j$.parse(f),Q=await $.timeline({limit:J.limit,sessionId:J.sessionId});if(Q.length===0)return J.sessionId?`Session ${J.sessionId} not found.`:"No past sessions found for this project.";if(J.sessionId){let X=Q[0],W=[`# Session Detail: ${X.session.id}
14
- `];if(W.push(`- **Started**: ${X.session.startedAt}`),W.push(`- **Ended**: ${X.session.endedAt??"Active"}`),W.push(`- **Status**: ${X.session.status}`),W.push(`- **Observations**: ${X.session.observationCount}`),X.summary)W.push(`
15
- ## Summary
16
- ${X.summary.summary}`);if(X.observations.length>0){W.push(`
17
- ## Observations`);for(let Z of X.observations)W.push(`
18
- ### [${Z.type.toUpperCase()}] ${Z.title}
19
- ${Z.narrative}`)}return W.join(`
20
- `)}let M=[`# Session Timeline (${Q.length} sessions)
21
- `];for(let X of Q){if(M.push(`## Session: ${X.session.id}`),M.push(`- **Started**: ${X.session.startedAt}`),M.push(`- **Status**: ${X.session.status}`),M.push(`- **Observations**: ${X.session.observationCount}`),X.summary)M.push(`- **Summary**: ${X.summary.summary}`);M.push("")}return M.join(`
22
- `)}catch(J){return`Timeline error: ${J}`}}},"mem-recall":{description:"Layer 3: fetch full observation details by ID.",args:R$.shape,execute:async(f)=>{try{let J=R$.parse(f),Q=await $.recall(J.ids,J.limit);if(Q.length===0)return"No matching observations found.";return`Recalled ${Q.length} observation(s):
23
-
24
- ${Q.map((M)=>O2(M)).join(`
25
- ---
26
- `)}`}catch(J){return`Recall error: ${J}`}}},"mem-save":{description:"Save an observation to project or user memory.",args:k$.shape,execute:async(f,J)=>{try{let Q=k$.parse(f),M=await $.save({...Q,sessionId:J.sessionID});if(!M&&Q.scope==="user")return"Save error: User-level memory is not enabled. Set OPEN_MEM_USER_MEMORY=true to enable.";if(!M)return"Save error: unable to save observation.";return`Saved observation: [${M.type}] "${M.title}" (ID: ${M.id}${Q.scope==="user"?", scope: user":""})`}catch(Q){return`Save error: ${Q}`}}},"mem-update":{description:"Update an existing project observation.",args:T$.shape,execute:async(f)=>{try{let J=T$.parse(f),Q=await $.update(J);if(!Q)return`Update error: observation "${J.id}" not found in this project.`;return`Updated observation "${Q.title}" (new revision ID: ${Q.id}, previous ID: ${J.id}).`}catch(J){return`Update error: ${J}`}}},"mem-delete":{description:"Delete an observation from project memory.",args:I$.shape,execute:async(f)=>{try{let J=I$.parse(f);if(await $.delete([J.id])===0)return`Delete error: observation "${J.id}" not found in this project.`;return`Tombstoned observation (ID: ${J.id})`}catch(J){return`Delete error: ${J}`}}},"mem-export":{description:"Export project memories as portable JSON.",args:x$.shape,execute:async(f)=>{try{let J=x$.parse(f);if(J.format!=="json")return"Export error: only JSON format is supported.";let Q=await $.export("project",{type:J.type,limit:J.limit}),M=Q,X=M.observations?.length??0,W=M.summaries?.length??0;return`Exported ${X} observation(s) and ${W} summary(ies).
27
-
28
- ${JSON.stringify(Q,null,2)}`}catch(J){return`Export error: ${J}`}}},"mem-import":{description:"Import observations and summaries from JSON export.",args:P$.shape,execute:async(f)=>{try{let J=P$.parse(f),Q=await $.import(J.data,{mode:J.mode});return`Imported ${Q.imported} observation(s). Skipped ${Q.skipped} duplicate observation(s).`}catch(J){return`Import error: ${J}`}}},"mem-guide":{description:"Show the recommended open-mem retrieval and write workflow.",args:{},execute:async()=>$.guide()}}}import{generateText as P2}from"ai";var C2=new Set(["decision","bugfix","feature","refactor","discovery","change"]);function F($,f){let J=new RegExp(`<${f}[^>]*>([\\s\\S]*?)</${f}>`,"i"),Q=$.match(J);return Q?Q[1].trim():""}function R($,f){let J=new RegExp(`<${f}[^>]*>([\\s\\S]*?)</${f}>`,"gi"),Q=[];for(let M of $.matchAll(J)){let X=M[1].trim();if(X)Q.push(X)}return Q}function q$($){let f=F($,"observation");if(!f)return null;let J=F(f,"type").toLowerCase(),Q=C2.has(J)?J:"discovery",M=F(f,"title")||"Untitled observation",X=F(f,"subtitle"),W=F(f,"narrative"),Z=R(F(f,"facts"),"fact"),N=R(F(f,"concepts"),"concept"),S=R(F(f,"files_read"),"file"),K=R(F(f,"files_modified"),"file"),V=F(f,"importance"),Y=Number.parseInt(V,10),U=Number.isNaN(Y)?3:Math.max(1,Math.min(5,Y));return{type:Q,title:M,subtitle:X,facts:Z,narrative:W,concepts:N,filesRead:S,filesModified:K,importance:U}}function y$($){let f=F($,"session_summary");if(!f)return null;let J=F(f,"summary")||"No summary available",Q=R(F(f,"key_decisions"),"decision"),M=R(F(f,"files_modified"),"file"),X=R(F(f,"concepts"),"concept"),W=F(f,"request")||void 0,Z=F(f,"investigated")||void 0,N=F(f,"learned")||void 0,S=F(f,"completed")||void 0,K=F(f,"next_steps")||void 0;return{summary:J,keyDecisions:Q,filesModified:M,concepts:X,request:W,investigated:Z,learned:N,completed:S,nextSteps:K}}function v$($){let f=F($,"reranked");if(!f)return null;let J=R(f,"index");if(J.length===0)return null;let Q=[];for(let M of J){let X=Number.parseInt(M,10);if(Number.isNaN(X)||X<0)return null;Q.push(X)}return Q}var j2=new Set(["new_fact","update","duplicate"]);function g$($){let f=F($,"evaluation");if(!f)return null;let J=F(f,"outcome").toLowerCase().trim();if(!j2.has(J))return null;let Q=J,M=F(f,"reason");if(!M)return null;let X=F(f,"supersedes"),W={outcome:Q,reason:M};if(Q==="update"&&X)W.supersedesId=X;if(Q==="update"&&!W.supersedesId)return null;return W}var R2=new Set(["technology","library","pattern","concept","file","person","project","other"]),k2=new Set(["uses","depends_on","implements","extends","related_to","replaces","configures"]);function h$($){let f=F($,"extraction");if(!f)return null;let J=F(f,"entities"),Q=F(f,"relations"),M=R(J,"entity"),X=[];for(let N of M){let S=F(N,"name");if(!S)continue;let K=F(N,"type").toLowerCase(),V=R2.has(K)?K:"other";X.push({name:S,entityType:V})}let W=R(Q,"relation"),Z=[];for(let N of W){let S=F(N,"source"),K=F(N,"target"),V=F(N,"relationship").toLowerCase();if(!S||!K||!V)continue;if(!k2.has(V))continue;Z.push({sourceName:S,targetName:K,relationship:V})}return{entities:X,relations:Z}}function L($){return Math.ceil($.length/4)}function b$($,f,J){let Q=J?`<session_context>
29
- ${J}
2
+ var iA=Object.create;var{getPrototypeOf:tA,defineProperty:f0,getOwnPropertyNames:aA}=Object;var sA=Object.prototype.hasOwnProperty;var oA=(f,n,A)=>{A=f!=null?iA(tA(f)):{};let E=n||!f||!f.__esModule?f0(A,"default",{value:f,enumerable:!0}):A;for(let N of aA(f))if(!sA.call(E,N))f0(E,N,{get:()=>f[N],enumerable:!0});return E};var dA=(f,n)=>{for(var A in n)f0(f,A,{get:n[A],enumerable:!0,configurable:!0,set:(E)=>n[A]=()=>E})};var a0=(f,n)=>()=>(f&&(n=f(f=0)),n);var v=import.meta.require;import{existsSync as y1,readFileSync as C1}from"fs";function V1(){let f={};if(process.env.OPEN_MEM_DB_PATH)f.dbPath=process.env.OPEN_MEM_DB_PATH;if(process.env.OPEN_MEM_PROVIDER)f.provider=process.env.OPEN_MEM_PROVIDER;if(process.env.OPEN_MEM_MODEL)f.model=process.env.OPEN_MEM_MODEL;if(process.env.OPEN_MEM_MAX_CONTEXT_TOKENS)f.maxContextTokens=Number.parseInt(process.env.OPEN_MEM_MAX_CONTEXT_TOKENS,10);if(process.env.OPEN_MEM_COMPRESSION==="false")f.compressionEnabled=!1;if(process.env.OPEN_MEM_CONTEXT_INJECTION==="false")f.contextInjectionEnabled=!1;if(process.env.OPEN_MEM_IGNORED_TOOLS)f.ignoredTools=process.env.OPEN_MEM_IGNORED_TOOLS.split(",").map((n)=>n.trim());if(process.env.OPEN_MEM_BATCH_SIZE)f.batchSize=Number.parseInt(process.env.OPEN_MEM_BATCH_SIZE,10);if(process.env.OPEN_MEM_RETENTION_DAYS)f.retentionDays=Number.parseInt(process.env.OPEN_MEM_RETENTION_DAYS,10);if(process.env.OPEN_MEM_LOG_LEVEL)f.logLevel=process.env.OPEN_MEM_LOG_LEVEL;if(process.env.OPEN_MEM_CONTEXT_SHOW_TOKEN_COSTS==="false")f.contextShowTokenCosts=!1;if(process.env.OPEN_MEM_CONTEXT_TYPES)f.contextObservationTypes=process.env.OPEN_MEM_CONTEXT_TYPES==="all"?"all":process.env.OPEN_MEM_CONTEXT_TYPES.split(",").map((n)=>n.trim());if(process.env.OPEN_MEM_CONTEXT_FULL_COUNT)f.contextFullObservationCount=Number.parseInt(process.env.OPEN_MEM_CONTEXT_FULL_COUNT,10);if(process.env.OPEN_MEM_MAX_OBSERVATIONS)f.maxObservations=Number.parseInt(process.env.OPEN_MEM_MAX_OBSERVATIONS,10);if(process.env.OPEN_MEM_CONTEXT_SHOW_LAST_SUMMARY==="false")f.contextShowLastSummary=!1;if(process.env.OPEN_MEM_RATE_LIMITING==="false")f.rateLimitingEnabled=!1;if(process.env.OPEN_MEM_FOLDER_CONTEXT==="false")f.folderContextEnabled=!1;if(process.env.OPEN_MEM_FOLDER_CONTEXT_MAX_DEPTH)f.folderContextMaxDepth=Number.parseInt(process.env.OPEN_MEM_FOLDER_CONTEXT_MAX_DEPTH,10);if(process.env.OPEN_MEM_DAEMON==="true")f.daemonEnabled=!0;if(process.env.OPEN_MEM_DASHBOARD==="true")f.dashboardEnabled=!0;if(process.env.OPEN_MEM_DASHBOARD_PORT)f.dashboardPort=Number.parseInt(process.env.OPEN_MEM_DASHBOARD_PORT,10);if(process.env.OPEN_MEM_PLATFORM_OPENCODE==="false")f.platformOpenCodeEnabled=!1;if(process.env.OPEN_MEM_PLATFORM_CLAUDE_CODE==="true")f.platformClaudeCodeEnabled=!0;if(process.env.OPEN_MEM_PLATFORM_CURSOR==="true")f.platformCursorEnabled=!0;if(process.env.OPEN_MEM_MCP_COMPAT_MODE)f.mcpCompatibilityMode=process.env.OPEN_MEM_MCP_COMPAT_MODE;if(process.env.OPEN_MEM_MCP_PROTOCOL_VERSION)f.mcpProtocolVersion=process.env.OPEN_MEM_MCP_PROTOCOL_VERSION;if(process.env.OPEN_MEM_MCP_SUPPORTED_PROTOCOLS)f.mcpSupportedProtocolVersions=process.env.OPEN_MEM_MCP_SUPPORTED_PROTOCOLS.split(",").map((n)=>n.trim()).filter(Boolean);if(process.env.OPEN_MEM_EMBEDDING_DIMENSION)f.embeddingDimension=Number.parseInt(process.env.OPEN_MEM_EMBEDDING_DIMENSION,10);if(process.env.OPEN_MEM_CONFLICT_RESOLUTION==="true")f.conflictResolutionEnabled=!0;if(process.env.OPEN_MEM_CONFLICT_BAND_LOW){let n=Number.parseFloat(process.env.OPEN_MEM_CONFLICT_BAND_LOW);if(!Number.isNaN(n))f.conflictSimilarityBandLow=n}if(process.env.OPEN_MEM_CONFLICT_BAND_HIGH){let n=Number.parseFloat(process.env.OPEN_MEM_CONFLICT_BAND_HIGH);if(!Number.isNaN(n))f.conflictSimilarityBandHigh=n}if(process.env.OPEN_MEM_USER_MEMORY==="true")f.userMemoryEnabled=!0;if(process.env.OPEN_MEM_USER_MEMORY_DB_PATH)f.userMemoryDbPath=process.env.OPEN_MEM_USER_MEMORY_DB_PATH;if(process.env.OPEN_MEM_USER_MEMORY_MAX_TOKENS)f.userMemoryMaxContextTokens=Number.parseInt(process.env.OPEN_MEM_USER_MEMORY_MAX_TOKENS,10);if(process.env.OPEN_MEM_RERANKING==="true")f.rerankingEnabled=!0;if(process.env.OPEN_MEM_RERANKING_MAX_CANDIDATES)f.rerankingMaxCandidates=Number.parseInt(process.env.OPEN_MEM_RERANKING_MAX_CANDIDATES,10);if(process.env.OPEN_MEM_ENTITY_EXTRACTION==="true")f.entityExtractionEnabled=!0;return f}function B1(f){let n=`${f}/.open-mem/config.json`;if(!y1(n))return{};try{let A=C1(n,"utf-8"),E=JSON.parse(A);if(!E||typeof E!=="object"||Array.isArray(E))return{};return E}catch{return{}}}function J1(f){switch(f){case"google":return 768;case"openai":return 1536;case"bedrock":return 1024;case"anthropic":return 0;default:return 768}}function d(f,n){let A=B1(f),E=V1(),N={...Bn,...A,...E,...n};if(!N.dbPath.startsWith("/"))N.dbPath=`${f}/${N.dbPath}`;if(!process.env.OPEN_MEM_PROVIDER&&!n?.provider){if(process.env.GOOGLE_GENERATIVE_AI_API_KEY||process.env.GEMINI_API_KEY)N.provider="google";else if(process.env.ANTHROPIC_API_KEY)N.provider="anthropic";else if(process.env.AWS_BEARER_TOKEN_BEDROCK||process.env.AWS_ACCESS_KEY_ID||process.env.AWS_PROFILE)N.provider="bedrock"}if(!N.apiKey)switch(N.provider){case"google":N.apiKey=process.env.GOOGLE_GENERATIVE_AI_API_KEY||process.env.GEMINI_API_KEY;break;case"anthropic":N.apiKey=process.env.ANTHROPIC_API_KEY;break;case"openai":N.apiKey=process.env.OPENAI_API_KEY;break;case"bedrock":break}if(N.embeddingDimension===void 0)N.embeddingDimension=J1(N.provider);return N}function Jn(f){let n=[],A=f.provider!=="bedrock";if(f.compressionEnabled&&A&&!f.apiKey)n.push("AI compression enabled but no API key found. Get a free Gemini API key at https://aistudio.google.com/apikey and set GOOGLE_GENERATIVE_AI_API_KEY, or set OPEN_MEM_PROVIDER and the appropriate API key for your provider.");if(f.maxContextTokens<500)n.push("maxContextTokens must be at least 500");if(f.batchSize<1)n.push("batchSize must be at least 1");if(f.minOutputLength<0)n.push("minOutputLength must be non-negative");return n}function Ff(){return{...Bn}}async function Qn(f){let n=f.dbPath.substring(0,f.dbPath.lastIndexOf("/")),{mkdir:A}=await import("fs/promises");await A(n,{recursive:!0})}var Bn;var cf=a0(()=>{Bn={dbPath:".open-mem/memory.db",provider:"google",apiKey:void 0,model:"gemini-2.5-flash-lite",maxTokensPerCompression:1024,compressionEnabled:!0,contextInjectionEnabled:!0,maxContextTokens:4000,batchSize:5,batchIntervalMs:30000,ignoredTools:[],minOutputLength:50,maxIndexEntries:20,sensitivePatterns:[],retentionDays:90,maxDatabaseSizeMb:500,logLevel:"warn",contextShowTokenCosts:!0,contextObservationTypes:"all",contextFullObservationCount:3,maxObservations:50,contextShowLastSummary:!0,rateLimitingEnabled:!0,folderContextEnabled:!0,folderContextMaxDepth:5,daemonEnabled:!1,dashboardEnabled:!1,dashboardPort:3737,platformOpenCodeEnabled:!0,platformClaudeCodeEnabled:!1,platformCursorEnabled:!1,mcpCompatibilityMode:"strict",mcpProtocolVersion:"2024-11-05",mcpSupportedProtocolVersions:["2024-11-05"],embeddingDimension:void 0,conflictResolutionEnabled:!1,conflictSimilarityBandLow:0.7,conflictSimilarityBandHigh:0.92,userMemoryEnabled:!1,userMemoryDbPath:"~/.config/open-mem/user-memory.db",userMemoryMaxContextTokens:1000,rerankingEnabled:!1,rerankingMaxCandidates:20,entityExtractionEnabled:!1}});var Kn={};dA(Kn,{writeProjectConfig:()=>Xn,validatePatch:()=>D0,readProjectConfig:()=>b,previewConfig:()=>l0,patchConfig:()=>Gf,getEffectiveConfig:()=>p,getConfigSchema:()=>R0});import{existsSync as Q1}from"fs";import{mkdir as L1,readFile as z1,writeFile as W1}from"fs/promises";import{dirname as X1,join as K1}from"path";function zn(f){return K1(f,".open-mem","config.json")}function Wn(f){return Ln.find((n)=>n.key===f)}function U1(f,n){let A=Wn(f);if(!A)return null;if(A.type==="string"&&typeof n!=="string")return`${String(f)} must be a string`;if(A.type==="number"&&typeof n!=="number")return`${String(f)} must be a number`;if(A.type==="boolean"&&typeof n!=="boolean")return`${String(f)} must be a boolean`;if(A.type==="array"&&!Array.isArray(n))return`${String(f)} must be an array`;if(A.enum&&typeof n==="string"&&!A.enum.includes(n))return`${String(f)} must be one of: ${A.enum.join(", ")}`;if(typeof n==="number"){if(A.min!==void 0&&n<A.min)return`${String(f)} must be >= ${A.min}`;if(A.max!==void 0&&n>A.max)return`${String(f)} must be <= ${A.max}`}return null}function R0(){return Ln}async function b(f){let n=zn(f);if(!Q1(n))return{};try{let A=await z1(n,"utf-8"),E=JSON.parse(A);if(!E||typeof E!=="object"||Array.isArray(E))return{};return E}catch{return{}}}async function Xn(f,n){let A=zn(f),N={...await b(f),...n};await L1(X1(A),{recursive:!0}),await W1(A,JSON.stringify(N,null,2),"utf-8")}function D0(f){let n=[];for(let[A,E]of Object.entries(f)){let O=U1(A,E);if(O)n.push(O)}return n}async function p(f){let n=Ff(),A=await b(f),E=d(f),N=[],O={};for(let[S,M]of Object.entries(n)){let _=S,$=Wn(_),D=(Z1[_]??[]).some((Q)=>typeof process.env[Q]==="string"),l=Object.hasOwn(A,_),u="default";if(l)u="file";if(D)u="env";if(O[_]={source:u,locked:D,restartRequired:$?.restartRequired??!1,liveApply:$?.liveApply??!1},u==="env"&&l)N.push(`${String(_)} is overridden by environment variable.`);if(E[_]===void 0&&M!==void 0)N.push(`${String(_)} resolved to undefined unexpectedly.`)}return{config:E,meta:O,warnings:N}}async function l0(f,n){let A=D0(n);if(A.length>0)return{...await p(f),warnings:A};let E=Ff(),N=await b(f),O={...E,...N,...n},M={...d(f,n),...O},_=(await p(f)).meta;return{config:M,meta:_,warnings:[]}}async function Gf(f,n){let A=D0(n);if(A.length>0)return{...await p(f),warnings:A};return await Xn(f,n),p(f)}var Ln,Z1;var u0=a0(()=>{cf();Ln=[{key:"dbPath",label:"Database Path",type:"string",group:"Storage",liveApply:!1,restartRequired:!0},{key:"provider",label:"Provider",type:"string",group:"AI",liveApply:!1,restartRequired:!0,enum:["google","anthropic","openai","bedrock"]},{key:"model",label:"Model",type:"string",group:"AI",liveApply:!1,restartRequired:!0},{key:"maxTokensPerCompression",label:"Max Tokens Per Compression",type:"number",group:"AI",liveApply:!0,restartRequired:!1,min:128,max:8192},{key:"compressionEnabled",label:"Compression Enabled",type:"boolean",group:"Behavior",liveApply:!0,restartRequired:!1},{key:"contextInjectionEnabled",label:"Context Injection Enabled",type:"boolean",group:"Behavior",liveApply:!0,restartRequired:!1},{key:"maxContextTokens",label:"Max Context Tokens",type:"number",group:"Behavior",liveApply:!0,restartRequired:!1,min:500,max:64000},{key:"batchSize",label:"Batch Size",type:"number",group:"Behavior",liveApply:!0,restartRequired:!1,min:1,max:100},{key:"batchIntervalMs",label:"Batch Interval (ms)",type:"number",group:"Behavior",liveApply:!0,restartRequired:!1,min:1000,max:300000},{key:"ignoredTools",label:"Ignored Tools",type:"array",group:"Filtering",liveApply:!0,restartRequired:!1},{key:"minOutputLength",label:"Min Output Length",type:"number",group:"Filtering",liveApply:!0,restartRequired:!1,min:0,max:1e4},{key:"maxObservations",label:"Max Observations",type:"number",group:"Progressive Disclosure",liveApply:!0,restartRequired:!1,min:1,max:200},{key:"contextFullObservationCount",label:"Full Observation Count",type:"number",group:"Progressive Disclosure",liveApply:!0,restartRequired:!1,min:0,max:20},{key:"contextShowTokenCosts",label:"Show Token Costs",type:"boolean",group:"Progressive Disclosure",liveApply:!0,restartRequired:!1},{key:"sensitivePatterns",label:"Sensitive Patterns",type:"array",group:"Privacy",liveApply:!0,restartRequired:!1},{key:"retentionDays",label:"Retention Days",type:"number",group:"Data Retention",liveApply:!1,restartRequired:!0,min:0,max:3650},{key:"maxDatabaseSizeMb",label:"Max Database Size (MB)",type:"number",group:"Data Retention",liveApply:!1,restartRequired:!0,min:0,max:1e5},{key:"dashboardEnabled",label:"Dashboard Enabled",type:"boolean",group:"Dashboard",liveApply:!1,restartRequired:!0},{key:"dashboardPort",label:"Dashboard Port",type:"number",group:"Dashboard",liveApply:!1,restartRequired:!0,min:1,max:65535},{key:"platformOpenCodeEnabled",label:"OpenCode Adapter",type:"boolean",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"platformClaudeCodeEnabled",label:"Claude Code Adapter",type:"boolean",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"platformCursorEnabled",label:"Cursor Adapter",type:"boolean",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"mcpCompatibilityMode",label:"MCP Compatibility Mode",type:"string",group:"Advanced",liveApply:!1,restartRequired:!0,enum:["strict","legacy"]},{key:"mcpProtocolVersion",label:"MCP Protocol Version",type:"string",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"mcpSupportedProtocolVersions",label:"MCP Supported Protocols",type:"array",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"rerankingEnabled",label:"Reranking Enabled",type:"boolean",group:"Advanced",liveApply:!0,restartRequired:!1},{key:"entityExtractionEnabled",label:"Entity Extraction Enabled",type:"boolean",group:"Advanced",liveApply:!0,restartRequired:!1},{key:"userMemoryEnabled",label:"User Memory Enabled",type:"boolean",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"userMemoryMaxContextTokens",label:"User Memory Max Context Tokens",type:"number",group:"Advanced",liveApply:!0,restartRequired:!1,min:0,max:8000}],Z1={dbPath:["OPEN_MEM_DB_PATH"],provider:["OPEN_MEM_PROVIDER"],model:["OPEN_MEM_MODEL"],compressionEnabled:["OPEN_MEM_COMPRESSION"],contextInjectionEnabled:["OPEN_MEM_CONTEXT_INJECTION"],maxContextTokens:["OPEN_MEM_MAX_CONTEXT_TOKENS"],ignoredTools:["OPEN_MEM_IGNORED_TOOLS"],batchSize:["OPEN_MEM_BATCH_SIZE"],retentionDays:["OPEN_MEM_RETENTION_DAYS"],contextShowTokenCosts:["OPEN_MEM_CONTEXT_SHOW_TOKEN_COSTS"],contextFullObservationCount:["OPEN_MEM_CONTEXT_FULL_COUNT"],maxObservations:["OPEN_MEM_MAX_OBSERVATIONS"],dashboardEnabled:["OPEN_MEM_DASHBOARD"],dashboardPort:["OPEN_MEM_DASHBOARD_PORT"],platformOpenCodeEnabled:["OPEN_MEM_PLATFORM_OPENCODE"],platformClaudeCodeEnabled:["OPEN_MEM_PLATFORM_CLAUDE_CODE"],platformCursorEnabled:["OPEN_MEM_PLATFORM_CURSOR"],mcpCompatibilityMode:["OPEN_MEM_MCP_COMPAT_MODE"],mcpProtocolVersion:["OPEN_MEM_MCP_PROTOCOL_VERSION"],mcpSupportedProtocolVersions:["OPEN_MEM_MCP_SUPPORTED_PROTOCOLS"],rerankingEnabled:["OPEN_MEM_RERANKING"],userMemoryEnabled:["OPEN_MEM_USER_MEMORY"]}});import{existsSync as mN}from"fs";import{dirname as YN,join as a}from"path";import{fileURLToPath as FN}from"url";import{randomUUID as Rf}from"crypto";import{normalize as m1,resolve as y0,sep as Zn}from"path";import{fileURLToPath as Y1}from"url";var n0=(f,n,A)=>{return(E,N)=>{let O=-1;return S(0);async function S(M){if(M<=O)throw Error("next() called multiple times");O=M;let _,$=!1,R;if(f[M])R=f[M][0][0],E.req.routeIndex=M;else R=M===f.length&&N||void 0;if(R)try{_=await R(E,()=>S(M+1))}catch(D){if(D instanceof Error&&n)E.error=D,_=await n(D,E),$=!0;else throw D}else if(E.finalized===!1&&A)_=await A(E);if(_&&(E.finalized===!1||$))E.res=_;return E}}};var s0=Symbol();var o0=async(f,n=Object.create(null))=>{let{all:A=!1,dot:E=!1}=n,O=(f instanceof Qf?f.raw.headers:f.headers).get("Content-Type");if(O?.startsWith("multipart/form-data")||O?.startsWith("application/x-www-form-urlencoded"))return eA(f,{all:A,dot:E});return{}};async function eA(f,n){let A=await f.formData();if(A)return f1(A,n);return{}}function f1(f,n){let A=Object.create(null);if(f.forEach((E,N)=>{if(!(n.all||N.endsWith("[]")))A[N]=E;else n1(A,N,E)}),n.dot)Object.entries(A).forEach(([E,N])=>{if(E.includes("."))A1(A,E,N),delete A[E]});return A}var n1=(f,n,A)=>{if(f[n]!==void 0)if(Array.isArray(f[n]))f[n].push(A);else f[n]=[f[n],A];else if(!n.endsWith("[]"))f[n]=A;else f[n]=[A]},A1=(f,n,A)=>{let E=f,N=n.split(".");N.forEach((O,S)=>{if(S===N.length-1)E[O]=A;else{if(!E[O]||typeof E[O]!=="object"||Array.isArray(E[O])||E[O]instanceof File)E[O]=Object.create(null);E=E[O]}})};var E0=(f)=>{let n=f.split("/");if(n[0]==="")n.shift();return n},d0=(f)=>{let{groups:n,path:A}=E1(f),E=E0(A);return N1(E,n)},E1=(f)=>{let n=[];return f=f.replace(/\{[^}]+\}/g,(A,E)=>{let N=`@${E}`;return n.push([N,A]),N}),{groups:n,path:f}},N1=(f,n)=>{for(let A=n.length-1;A>=0;A--){let[E]=n[A];for(let N=f.length-1;N>=0;N--)if(f[N].includes(E)){f[N]=f[N].replace(E,n[A][1]);break}}return f},Lf={},e0=(f,n)=>{if(f==="*")return"*";let A=f.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);if(A){let E=`${f}#${n}`;if(!Lf[E])if(A[2])Lf[E]=n&&n[0]!==":"&&n[0]!=="*"?[E,A[1],new RegExp(`^${A[2]}(?=/${n})`)]:[f,A[1],new RegExp(`^${A[2]}$`)];else Lf[E]=[f,A[1],!0];return Lf[E]}return null},zf=(f,n)=>{try{return n(f)}catch{return f.replace(/(?:%[0-9A-Fa-f]{2})+/g,(A)=>{try{return n(A)}catch{return A}})}},O1=(f)=>zf(f,decodeURI),N0=(f)=>{let n=f.url,A=n.indexOf("/",n.indexOf(":")+4),E=A;for(;E<n.length;E++){let N=n.charCodeAt(E);if(N===37){let O=n.indexOf("?",E),S=n.slice(A,O===-1?void 0:O);return O1(S.includes("%25")?S.replace(/%25/g,"%2525"):S)}else if(N===63)break}return n.slice(A,E)};var fn=(f)=>{let n=N0(f);return n.length>1&&n.at(-1)==="/"?n.slice(0,-1):n},r=(f,n,...A)=>{if(A.length)n=r(n,...A);return`${f?.[0]==="/"?"":"/"}${f}${n==="/"?"":`${f?.at(-1)==="/"?"":"/"}${n?.[0]==="/"?n.slice(1):n}`}`},Wf=(f)=>{if(f.charCodeAt(f.length-1)!==63||!f.includes(":"))return null;let n=f.split("/"),A=[],E="";return n.forEach((N)=>{if(N!==""&&!/\:/.test(N))E+="/"+N;else if(/\:/.test(N))if(/\?/.test(N)){if(A.length===0&&E==="")A.push("/");else A.push(E);let O=N.replace("?","");E+="/"+O,A.push(E)}else E+="/"+N}),A.filter((N,O,S)=>S.indexOf(N)===O)},A0=(f)=>{if(!/[%+]/.test(f))return f;if(f.indexOf("+")!==-1)f=f.replace(/\+/g," ");return f.indexOf("%")!==-1?zf(f,O0):f},nn=(f,n,A)=>{let E;if(!A&&n&&!/[%+]/.test(n)){let S=f.indexOf("?",8);if(S===-1)return;if(!f.startsWith(n,S+1))S=f.indexOf(`&${n}`,S+1);while(S!==-1){let M=f.charCodeAt(S+n.length+1);if(M===61){let _=S+n.length+2,$=f.indexOf("&",_);return A0(f.slice(_,$===-1?void 0:$))}else if(M==38||isNaN(M))return"";S=f.indexOf(`&${n}`,S+1)}if(E=/[%+]/.test(f),!E)return}let N={};E??=/[%+]/.test(f);let O=f.indexOf("?",8);while(O!==-1){let S=f.indexOf("&",O+1),M=f.indexOf("=",O);if(M>S&&S!==-1)M=-1;let _=f.slice(O+1,M===-1?S===-1?void 0:S:M);if(E)_=A0(_);if(O=S,_==="")continue;let $;if(M===-1)$="";else if($=f.slice(M+1,S===-1?void 0:S),E)$=A0($);if(A){if(!(N[_]&&Array.isArray(N[_])))N[_]=[];N[_].push($)}else N[_]??=$}return n?N[n]:N},An=nn,En=(f,n)=>{return nn(f,n,!0)},O0=decodeURIComponent;var Nn=(f)=>zf(f,O0),Qf=class{raw;#f;#n;routeIndex=0;path;bodyCache={};constructor(f,n="/",A=[[]]){this.raw=f,this.path=n,this.#n=A,this.#f={}}param(f){return f?this.#A(f):this.#O()}#A(f){let n=this.#n[0][this.routeIndex][1][f],A=this.#N(n);return A&&/\%/.test(A)?Nn(A):A}#O(){let f={},n=Object.keys(this.#n[0][this.routeIndex][1]);for(let A of n){let E=this.#N(this.#n[0][this.routeIndex][1][A]);if(E!==void 0)f[A]=/\%/.test(E)?Nn(E):E}return f}#N(f){return this.#n[1]?this.#n[1][f]:f}query(f){return An(this.url,f)}queries(f){return En(this.url,f)}header(f){if(f)return this.raw.headers.get(f)??void 0;let n={};return this.raw.headers.forEach((A,E)=>{n[E]=A}),n}async parseBody(f){return this.bodyCache.parsedBody??=await o0(this,f)}#E=(f)=>{let{bodyCache:n,raw:A}=this,E=n[f];if(E)return E;let N=Object.keys(n)[0];if(N)return n[N].then((O)=>{if(N==="json")O=JSON.stringify(O);return new Response(O)[f]()});return n[f]=A[f]()};json(){return this.#E("text").then((f)=>JSON.parse(f))}text(){return this.#E("text")}arrayBuffer(){return this.#E("arrayBuffer")}blob(){return this.#E("blob")}formData(){return this.#E("formData")}addValidatedData(f,n){this.#f[f]=n}valid(f){return this.#f[f]}get url(){return this.raw.url}get method(){return this.raw.method}get[s0](){return this.#n}get matchedRoutes(){return this.#n[0].map(([[,f]])=>f)}get routePath(){return this.#n[0].map(([[,f]])=>f)[this.routeIndex].path}};var Xf={Stringify:1,BeforeStream:2,Stream:3},M1=(f,n)=>{let A=new String(f);return A.isEscaped=!0,A.callbacks=n,A};var Of=async(f,n,A,E,N)=>{if(typeof f==="object"&&!(f instanceof String)){if(!(f instanceof Promise))f=f.toString();if(f instanceof Promise)f=await f}let O=f.callbacks;if(!O?.length)return Promise.resolve(f);if(N)N[0]+=f;else N=[f];let S=Promise.all(O.map((M)=>M({phase:n,buffer:N,context:E}))).then((M)=>Promise.all(M.filter(Boolean).map((_)=>Of(_,n,!1,E,N))).then(()=>N[0]));if(A)return M1(await S,O);else return S};var On="text/plain; charset=UTF-8",M0=(f,n)=>{return{"Content-Type":f,...n}},Mn=class{#f;#n;env={};#A;finalized=!1;error;#O;#N;#E;#R;#_;#$;#S;#D;#l;constructor(f,n){if(this.#f=f,n)this.#N=n.executionCtx,this.env=n.env,this.#$=n.notFoundHandler,this.#l=n.path,this.#D=n.matchResult}get req(){return this.#n??=new Qf(this.#f,this.#l,this.#D),this.#n}get event(){if(this.#N&&"respondWith"in this.#N)return this.#N;else throw Error("This context has no FetchEvent")}get executionCtx(){if(this.#N)return this.#N;else throw Error("This context has no ExecutionContext")}get res(){return this.#E||=new Response(null,{headers:this.#S??=new Headers})}set res(f){if(this.#E&&f){f=new Response(f.body,f);for(let[n,A]of this.#E.headers.entries()){if(n==="content-type")continue;if(n==="set-cookie"){let E=this.#E.headers.getSetCookie();f.headers.delete("set-cookie");for(let N of E)f.headers.append("set-cookie",N)}else f.headers.set(n,A)}}this.#E=f,this.finalized=!0}render=(...f)=>{return this.#_??=(n)=>this.html(n),this.#_(...f)};setLayout=(f)=>this.#R=f;getLayout=()=>this.#R;setRenderer=(f)=>{this.#_=f};header=(f,n,A)=>{if(this.finalized)this.#E=new Response(this.#E.body,this.#E);let E=this.#E?this.#E.headers:this.#S??=new Headers;if(n===void 0)E.delete(f);else if(A?.append)E.append(f,n);else E.set(f,n)};status=(f)=>{this.#O=f};set=(f,n)=>{this.#A??=new Map,this.#A.set(f,n)};get=(f)=>{return this.#A?this.#A.get(f):void 0};get var(){if(!this.#A)return{};return Object.fromEntries(this.#A)}#M(f,n,A){let E=this.#E?new Headers(this.#E.headers):this.#S??new Headers;if(typeof n==="object"&&"headers"in n){let O=n.headers instanceof Headers?n.headers:new Headers(n.headers);for(let[S,M]of O)if(S.toLowerCase()==="set-cookie")E.append(S,M);else E.set(S,M)}if(A)for(let[O,S]of Object.entries(A))if(typeof S==="string")E.set(O,S);else{E.delete(O);for(let M of S)E.append(O,M)}let N=typeof n==="number"?n:n?.status??this.#O;return new Response(f,{status:N,headers:E})}newResponse=(...f)=>this.#M(...f);body=(f,n,A)=>this.#M(f,n,A);text=(f,n,A)=>{return!this.#S&&!this.#O&&!n&&!A&&!this.finalized?new Response(f):this.#M(f,n,M0(On,A))};json=(f,n,A)=>{return this.#M(JSON.stringify(f),n,M0("application/json",A))};html=(f,n,A)=>{let E=(N)=>this.#M(N,n,M0("text/html; charset=UTF-8",A));return typeof f==="object"?Of(f,Xf.Stringify,!1,{}).then(E):E(f)};redirect=(f,n)=>{let A=String(f);return this.header("Location",!/[^\x00-\xFF]/.test(A)?A:encodeURI(A)),this.newResponse(null,n??302)};notFound=()=>{return this.#$??=()=>new Response,this.#$(this)}};var z="ALL",Sn="all",_n=["get","post","put","delete","options","patch"],Kf="Can not add a route since the matcher is already built.",Zf=class extends Error{};var $n="__COMPOSED_HANDLER";var S1=(f)=>{return f.text("404 Not Found",404)},Rn=(f,n)=>{if("getResponse"in f){let A=f.getResponse();return n.newResponse(A.body,A)}return console.error(f),n.text("Internal Server Error",500)},Dn=class f{get;post;put;delete;options;patch;all;on;use;router;getPath;_basePath="/";#f="/";routes=[];constructor(n={}){[..._n,Sn].forEach((O)=>{this[O]=(S,...M)=>{if(typeof S==="string")this.#f=S;else this.#O(O,this.#f,S);return M.forEach((_)=>{this.#O(O,this.#f,_)}),this}}),this.on=(O,S,...M)=>{for(let _ of[S].flat()){this.#f=_;for(let $ of[O].flat())M.map((R)=>{this.#O($.toUpperCase(),this.#f,R)})}return this},this.use=(O,...S)=>{if(typeof O==="string")this.#f=O;else this.#f="*",S.unshift(O);return S.forEach((M)=>{this.#O(z,this.#f,M)}),this};let{strict:E,...N}=n;Object.assign(this,N),this.getPath=E??!0?n.getPath??N0:fn}#n(){let n=new f({router:this.router,getPath:this.getPath});return n.errorHandler=this.errorHandler,n.#A=this.#A,n.routes=this.routes,n}#A=S1;errorHandler=Rn;route(n,A){let E=this.basePath(n);return A.routes.map((N)=>{let O;if(A.errorHandler===Rn)O=N.handler;else O=async(S,M)=>(await n0([],A.errorHandler)(S,()=>N.handler(S,M))).res,O[$n]=N.handler;E.#O(N.method,N.path,O)}),this}basePath(n){let A=this.#n();return A._basePath=r(this._basePath,n),A}onError=(n)=>{return this.errorHandler=n,this};notFound=(n)=>{return this.#A=n,this};mount(n,A,E){let N,O;if(E)if(typeof E==="function")O=E;else if(O=E.optionHandler,E.replaceRequest===!1)N=(_)=>_;else N=E.replaceRequest;let S=O?(_)=>{let $=O(_);return Array.isArray($)?$:[$]}:(_)=>{let $=void 0;try{$=_.executionCtx}catch{}return[_.env,$]};N||=(()=>{let _=r(this._basePath,n),$=_==="/"?0:_.length;return(R)=>{let D=new URL(R.url);return D.pathname=D.pathname.slice($)||"/",new Request(D,R)}})();let M=async(_,$)=>{let R=await A(N(_.req.raw),...S(_));if(R)return R;await $()};return this.#O(z,r(n,"*"),M),this}#O(n,A,E){n=n.toUpperCase(),A=r(this._basePath,A);let N={basePath:this._basePath,path:A,method:n,handler:E};this.router.add(n,A,[E,N]),this.routes.push(N)}#N(n,A){if(n instanceof Error)return this.errorHandler(n,A);throw n}#E(n,A,E,N){if(N==="HEAD")return(async()=>new Response(null,await this.#E(n,A,E,"GET")))();let O=this.getPath(n,{env:E}),S=this.router.match(N,O),M=new Mn(n,{path:O,matchResult:S,env:E,executionCtx:A,notFoundHandler:this.#A});if(S[0].length===1){let $;try{$=S[0][0][0][0](M,async()=>{M.res=await this.#A(M)})}catch(R){return this.#N(R,M)}return $ instanceof Promise?$.then((R)=>R||(M.finalized?M.res:this.#A(M))).catch((R)=>this.#N(R,M)):$??this.#A(M)}let _=n0(S[0],this.errorHandler,this.#A);return(async()=>{try{let $=await _(M);if(!$.finalized)throw Error("Context is not finalized. Did you forget to return a Response object or `await next()`?");return $.res}catch($){return this.#N($,M)}})()}fetch=(n,...A)=>{return this.#E(n,A[1],A[0],n.method)};request=(n,A,E,N)=>{if(n instanceof Request)return this.fetch(A?new Request(n,A):n,E,N);return n=n.toString(),this.fetch(new Request(/^https?:\/\//.test(n)?n:`http://localhost${r("/",n)}`,A),E,N)};fire=()=>{addEventListener("fetch",(n)=>{n.respondWith(this.#E(n.request,n,void 0,n.request.method))})}};var Mf=[];function Uf(f,n){let A=this.buildAllMatchers(),E=(N,O)=>{let S=A[N]||A[z],M=S[2][O];if(M)return M;let _=O.match(S[0]);if(!_)return[[],Mf];let $=_.indexOf("",1);return[S[1][$],_]};return this.match=E,E(f,n)}var mf="[^/]+",Sf=".*",_f="(?:|/.*)",h=Symbol(),_1=new Set(".\\+*[^]$()");function $1(f,n){if(f.length===1)return n.length===1?f<n?-1:1:-1;if(n.length===1)return 1;if(f===Sf||f===_f)return 1;else if(n===Sf||n===_f)return-1;if(f===mf)return 1;else if(n===mf)return-1;return f.length===n.length?f<n?-1:1:n.length-f.length}var ln=class f{#f;#n;#A=Object.create(null);insert(n,A,E,N,O){if(n.length===0){if(this.#f!==void 0)throw h;if(O)return;this.#f=A;return}let[S,...M]=n,_=S==="*"?M.length===0?["","",Sf]:["","",mf]:S==="/*"?["","",_f]:S.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/),$;if(_){let R=_[1],D=_[2]||mf;if(R&&_[2]){if(D===".*")throw h;if(D=D.replace(/^\((?!\?:)(?=[^)]+\)$)/,"(?:"),/\((?!\?:)/.test(D))throw h}if($=this.#A[D],!$){if(Object.keys(this.#A).some((l)=>l!==Sf&&l!==_f))throw h;if(O)return;if($=this.#A[D]=new f,R!=="")$.#n=N.varIndex++}if(!O&&R!=="")E.push([R,$.#n])}else if($=this.#A[S],!$){if(Object.keys(this.#A).some((R)=>R.length>1&&R!==Sf&&R!==_f))throw h;if(O)return;$=this.#A[S]=new f}$.insert(M,A,E,N,O)}buildRegExpStr(){let A=Object.keys(this.#A).sort($1).map((E)=>{let N=this.#A[E];return(typeof N.#n==="number"?`(${E})@${N.#n}`:_1.has(E)?`\\${E}`:E)+N.buildRegExpStr()});if(typeof this.#f==="number")A.unshift(`#${this.#f}`);if(A.length===0)return"";if(A.length===1)return A[0];return"(?:"+A.join("|")+")"}};var un=class{#f={varIndex:0};#n=new ln;insert(f,n,A){let E=[],N=[];for(let S=0;;){let M=!1;if(f=f.replace(/\{[^}]+\}/g,(_)=>{let $=`@\\${S}`;return N[S]=[$,_],S++,M=!0,$}),!M)break}let O=f.match(/(?::[^\/]+)|(?:\/\*$)|./g)||[];for(let S=N.length-1;S>=0;S--){let[M]=N[S];for(let _=O.length-1;_>=0;_--)if(O[_].indexOf(M)!==-1){O[_]=O[_].replace(M,N[S][1]);break}}return this.#n.insert(O,n,E,this.#f,A),E}buildRegExp(){let f=this.#n.buildRegExpStr();if(f==="")return[/^$/,[],[]];let n=0,A=[],E=[];return f=f.replace(/#(\d+)|@(\d+)|\.\*\$/g,(N,O,S)=>{if(O!==void 0)return A[++n]=Number(O),"$()";if(S!==void 0)return E[Number(S)]=++n,"";return""}),[new RegExp(`^${f}`),A,E]}};var R1=[/^$/,[],Object.create(null)],yn=Object.create(null);function Cn(f){return yn[f]??=new RegExp(f==="*"?"":`^${f.replace(/\/\*$|([.\\+*[^\]$()])/g,(n,A)=>A?`\\${A}`:"(?:|/.*)")}$`)}function D1(){yn=Object.create(null)}function l1(f){let n=new un,A=[];if(f.length===0)return R1;let E=f.map(($)=>[!/\*|\/:/.test($[0]),...$]).sort(([$,R],[D,l])=>$?1:D?-1:R.length-l.length),N=Object.create(null);for(let $=0,R=-1,D=E.length;$<D;$++){let[l,u,Q]=E[$];if(l)N[u]=[Q.map(([J])=>[J,Object.create(null)]),Mf];else R++;let V;try{V=n.insert(u,R,l)}catch(J){throw J===h?new Zf(u):J}if(l)continue;A[R]=Q.map(([J,W])=>{let F=Object.create(null);W-=1;for(;W>=0;W--){let[K,U]=V[W];F[K]=U}return[J,F]})}let[O,S,M]=n.buildRegExp();for(let $=0,R=A.length;$<R;$++)for(let D=0,l=A[$].length;D<l;D++){let u=A[$][D]?.[1];if(!u)continue;let Q=Object.keys(u);for(let V=0,J=Q.length;V<J;V++)u[Q[V]]=M[u[Q[V]]]}let _=[];for(let $ in S)_[$]=A[S[$]];return[O,_,N]}function o(f,n){if(!f)return;for(let A of Object.keys(f).sort((E,N)=>N.length-E.length))if(Cn(A).test(n))return[...f[A]];return}var Yf=class{name="RegExpRouter";#f;#n;constructor(){this.#f={[z]:Object.create(null)},this.#n={[z]:Object.create(null)}}add(f,n,A){let E=this.#f,N=this.#n;if(!E||!N)throw Error(Kf);if(!E[f])[E,N].forEach((M)=>{M[f]=Object.create(null),Object.keys(M[z]).forEach((_)=>{M[f][_]=[...M[z][_]]})});if(n==="/*")n="*";let O=(n.match(/\/:/g)||[]).length;if(/\*$/.test(n)){let M=Cn(n);if(f===z)Object.keys(E).forEach((_)=>{E[_][n]||=o(E[_],n)||o(E[z],n)||[]});else E[f][n]||=o(E[f],n)||o(E[z],n)||[];Object.keys(E).forEach((_)=>{if(f===z||f===_)Object.keys(E[_]).forEach(($)=>{M.test($)&&E[_][$].push([A,O])})}),Object.keys(N).forEach((_)=>{if(f===z||f===_)Object.keys(N[_]).forEach(($)=>M.test($)&&N[_][$].push([A,O]))});return}let S=Wf(n)||[n];for(let M=0,_=S.length;M<_;M++){let $=S[M];Object.keys(N).forEach((R)=>{if(f===z||f===R)N[R][$]||=[...o(E[R],$)||o(E[z],$)||[]],N[R][$].push([A,O-_+M+1])})}}match=Uf;buildAllMatchers(){let f=Object.create(null);return Object.keys(this.#n).concat(Object.keys(this.#f)).forEach((n)=>{f[n]||=this.#A(n)}),this.#f=this.#n=void 0,D1(),f}#A(f){let n=[],A=f===z;if([this.#f,this.#n].forEach((E)=>{let N=E[f]?Object.keys(E[f]).map((O)=>[O,E[f][O]]):[];if(N.length!==0)A||=!0,n.push(...N);else if(f!==z)n.push(...Object.keys(E[z]).map((O)=>[O,E[z][O]]))}),!A)return null;else return l1(n)}};var u1=class{name="PreparedRegExpRouter";#f;#n;constructor(f,n){this.#f=f,this.#n=n}#A(f,n){let A=this.#f[f];A[1].forEach((E)=>E&&E.push(n)),Object.values(A[2]).forEach((E)=>E[0].push(n))}#O(f,n,A,E,N){let O=this.#f[f];if(!N)O[2][n][0].push([A,{}]);else E.forEach((S)=>{if(typeof S==="number")O[1][S].push([A,N]);else O[2][S||n][0].push([A,N])})}add(f,n,A){if(!this.#f[f]){let N=this.#f[z],O={};for(let S in N[2])O[S]=[N[2][S][0].slice(),Mf];this.#f[f]=[N[0],N[1].map((S)=>Array.isArray(S)?S.slice():0),O]}if(n==="/*"||n==="*"){let N=[A,{}];if(f===z)for(let O in this.#f)this.#A(O,N);else this.#A(f,N);return}let E=this.#n[n];if(!E)throw Error(`Path ${n} is not registered`);for(let[N,O]of E)if(f===z)for(let S in this.#f)this.#O(S,n,A,N,O);else this.#O(f,n,A,N,O)}buildAllMatchers(){return this.#f}match=Uf};var S0=class{name="SmartRouter";#f=[];#n=[];constructor(f){this.#f=f.routers}add(f,n,A){if(!this.#n)throw Error(Kf);this.#n.push([f,n,A])}match(f,n){if(!this.#n)throw Error("Fatal error");let A=this.#f,E=this.#n,N=A.length,O=0,S;for(;O<N;O++){let M=A[O];try{for(let _=0,$=E.length;_<$;_++)M.add(...E[_]);S=M.match(f,n)}catch(_){if(_ instanceof Zf)continue;throw _}this.match=M.match.bind(M),this.#f=[M],this.#n=void 0;break}if(O===N)throw Error("Fatal error");return this.name=`SmartRouter + ${this.activeRouter.name}`,S}get activeRouter(){if(this.#n||this.#f.length!==1)throw Error("No active router has been determined yet.");return this.#f[0]}};var $f=Object.create(null),Vn=class f{#f;#n;#A;#O=0;#N=$f;constructor(n,A,E){if(this.#n=E||Object.create(null),this.#f=[],n&&A){let N=Object.create(null);N[n]={handler:A,possibleKeys:[],score:0},this.#f=[N]}this.#A=[]}insert(n,A,E){this.#O=++this.#O;let N=this,O=d0(A),S=[];for(let M=0,_=O.length;M<_;M++){let $=O[M],R=O[M+1],D=e0($,R),l=Array.isArray(D)?D[0]:$;if(l in N.#n){if(N=N.#n[l],D)S.push(D[1]);continue}if(N.#n[l]=new f,D)N.#A.push(D),S.push(D[1]);N=N.#n[l]}return N.#f.push({[n]:{handler:E,possibleKeys:S.filter((M,_,$)=>$.indexOf(M)===_),score:this.#O}}),N}#E(n,A,E,N){let O=[];for(let S=0,M=n.#f.length;S<M;S++){let _=n.#f[S],$=_[A]||_[z],R={};if($!==void 0){if($.params=Object.create(null),O.push($),E!==$f||N&&N!==$f)for(let D=0,l=$.possibleKeys.length;D<l;D++){let u=$.possibleKeys[D],Q=R[$.score];$.params[u]=N?.[u]&&!Q?N[u]:E[u]??N?.[u],R[$.score]=!0}}}return O}search(n,A){let E=[];this.#N=$f;let O=[this],S=E0(A),M=[];for(let _=0,$=S.length;_<$;_++){let R=S[_],D=_===$-1,l=[];for(let u=0,Q=O.length;u<Q;u++){let V=O[u],J=V.#n[R];if(J)if(J.#N=V.#N,D){if(J.#n["*"])E.push(...this.#E(J.#n["*"],n,V.#N));E.push(...this.#E(J,n,V.#N))}else l.push(J);for(let W=0,F=V.#A.length;W<F;W++){let K=V.#A[W],U=V.#N===$f?{}:{...V.#N};if(K==="*"){let H=V.#n["*"];if(H)E.push(...this.#E(H,n,V.#N)),H.#N=U,l.push(H);continue}let[Vf,w,j]=K;if(!R&&!(j instanceof RegExp))continue;let c=V.#n[Vf],sf=S.slice(_).join("/");if(j instanceof RegExp){let H=j.exec(sf);if(H){if(U[w]=H[0],E.push(...this.#E(c,n,V.#N,U)),Object.keys(c.#n).length){c.#N=U;let Bf=H[0].match(/\//)?.length??0;(M[Bf]||=[]).push(c)}continue}}if(j===!0||j.test(R))if(U[w]=R,D){if(E.push(...this.#E(c,n,U,V.#N)),c.#n["*"])E.push(...this.#E(c.#n["*"],n,U,V.#N))}else c.#N=U,l.push(c)}}O=l.concat(M.shift()??[])}if(E.length>1)E.sort((_,$)=>{return _.score-$.score});return[E.map(({handler:_,params:$})=>[_,$])]}};var _0=class{name="TrieRouter";#f;constructor(){this.#f=new Vn}add(f,n,A){let E=Wf(n);if(E){for(let N=0,O=E.length;N<O;N++)this.#f.insert(f,E[N],A);return}this.#f.insert(f,n,A)}match(f,n){return this.#f.search(f,n)}};var $0=class extends Dn{constructor(f={}){super(f);this.router=f.router??new S0({routers:[new Yf,new _0]})}};u0();import{z as y}from"zod";var e=y.enum(["decision","bugfix","feature","refactor","discovery","change"]);function C(f,n={}){return{data:f,error:null,meta:n}}function B(f,n,A){return{data:null,error:{code:f,message:n,details:A},meta:{}}}var Z={find:y.object({query:y.string().min(1),scope:y.enum(["project","user","all"]).optional().default("project"),types:y.array(e).optional(),limit:y.number().int().min(1).max(50).optional().default(10),cursor:y.string().optional(),include:y.object({snippets:y.boolean().optional(),scores:y.boolean().optional(),relations:y.boolean().optional()}).optional()}),history:y.object({limit:y.number().int().min(1).max(20).optional().default(5),cursor:y.string().optional(),sessionId:y.string().optional()}),get:y.object({ids:y.array(y.string()).min(1),includeHistory:y.boolean().optional().default(!1),limit:y.number().int().min(1).max(50).optional().default(10)}),create:y.object({title:y.string(),type:e,narrative:y.string(),concepts:y.array(y.string()).optional(),files:y.array(y.string()).optional(),importance:y.number().int().min(1).max(5).optional(),scope:y.enum(["project","user"]).optional().default("project")}),revise:y.object({id:y.string(),title:y.string().optional(),narrative:y.string().optional(),type:e.optional(),concepts:y.array(y.string()).optional(),importance:y.number().int().min(1).max(5).optional(),reason:y.string().optional()}),remove:y.object({id:y.string(),reason:y.string().optional()}),transferExport:y.object({scope:y.enum(["project"]).optional().default("project"),type:e.optional(),limit:y.number().int().min(1).optional(),format:y.enum(["json"]).optional().default("json")}),transferImport:y.object({payload:y.string(),mode:y.enum(["skip","merge","replace"]).optional().default("skip")}),maintenance:y.object({action:y.enum(["folderContextDryRun","folderContextClean","folderContextRebuild"])}),help:y.object({})};var F1=new Set(e.options);function C0(f,n,A=100){if(!f)return n;let E=Number.parseInt(f,10);if(Number.isNaN(E))return n;return Math.max(1,Math.min(E,A))}function c1(f){if(!f)return 0;let n=Number.parseInt(f,10);if(Number.isNaN(n))return 0;return Math.max(0,n)}function Un(f){if(!f)return;if(F1.has(f))return f;return}function jf(f){let n={};for(let[A,E]of Object.entries(f)){let N=A.toLowerCase();n[A]=typeof E==="string"&&(N.includes("key")||N.includes("api"))?"***REDACTED***":E}return n}function mn(f){let{projectPath:n,memoryEngine:A,runtimeStatusProvider:E,dashboardDir:N}=f,O=new $0;O.get("/v1/memory/observations",(M)=>{let _=C0(M.req.query("limit"),50),$=c1(M.req.query("offset")),R=Un(M.req.query("type")),D=M.req.query("sessionId"),l=M.req.query("state"),u=l==="current"||l==="superseded"||l==="tombstoned"?l:void 0,Q=A.listObservations({limit:_,offset:$,type:R,sessionId:D,state:u});return M.json(C(Q,{limit:_,offset:$}))}),O.post("/v1/memory/observations",async(M)=>{try{let _=await M.req.json(),$=await A.save({..._,sessionId:_.sessionId??`http-${Date.now()}`});if(!$)return M.json(B("CONFLICT","Unable to create observation"),409);return M.json(C($),201)}catch{return M.json(B("VALIDATION_ERROR","Invalid JSON body"),400)}}),O.get("/v1/memory/observations/:id",(M)=>{let _=M.req.param("id"),$=A.getObservation(_);if(!$)return M.json(B("NOT_FOUND","Observation not found"),404);return M.json(C($))}),O.get("/v1/memory/observations/:id/lineage",(M)=>{let _=M.req.param("id"),$=A.getLineage(_);if(!$)return M.json(B("NOT_FOUND","Observation not found"),404);return M.json(C({observationId:_,lineage:$}))}),O.get("/v1/memory/observations/:id/revision-diff",(M)=>{let _=M.req.param("id"),$=M.req.query("against");if(!$)return M.json(B("VALIDATION_ERROR","Query parameter 'against' is required"),400);let R=A.getRevisionDiff(_,$);if(!R)return M.json(B("NOT_FOUND","One or both observations not found"),404);if(M.req.query("version")==="1")return M.json(C({baseId:R.toId,againstId:R.fromId,changes:R.changedFields}));return M.json(C(R))}),O.post("/v1/memory/observations/:id/revisions",async(M)=>{let _=M.req.param("id");try{let $=await M.req.json(),R=await A.update({id:_,...$});if(!R)return M.json(B("NOT_FOUND","Observation not found"),404);return M.json(C({previousId:_,newId:R.id,observation:R}))}catch{return M.json(B("VALIDATION_ERROR","Invalid JSON body"),400)}}),O.post("/v1/memory/observations/:id/tombstone",async(M)=>{let _=M.req.param("id");if(await A.delete([_])===0)return M.json(B("NOT_FOUND","Observation not found"),404);return M.json(C({id:_,tombstoned:!0}))}),O.get("/v1/memory/sessions",(M)=>{let _=C0(M.req.query("limit"),20),$=M.req.query("projectPath")||n;return M.json(C(A.listSessions({limit:_,projectPath:$}),{limit:_}))}),O.get("/v1/memory/sessions/:id",(M)=>{let _=M.req.param("id"),$=A.getSession(_);if(!$)return M.json(B("NOT_FOUND","Session not found"),404);return M.json(C({...$.session,observations:$.observations,summary:$.summary}))}),O.get("/v1/memory/search",async(M)=>{let _=M.req.query("q");if(!_)return M.json(B("VALIDATION_ERROR","Query parameter 'q' is required"),400);let $=Un(M.req.query("type")),R=C0(M.req.query("limit"),20);try{let D=await A.search(_,{type:$,limit:R});return M.json(C(D,{limit:R}))}catch{return M.json(C([],{limit:R}))}}),O.post("/v1/memory/recall",async(M)=>{try{let _=await M.req.json(),$=await A.recall(_.ids??[],_.limit??10);return M.json(C($))}catch{return M.json(B("VALIDATION_ERROR","Invalid JSON body"),400)}}),O.post("/v1/memory/export",async(M)=>{try{let _=await M.req.json().catch(()=>({})),$=await A.export("project",{type:_.type,limit:_.limit});return M.json(C($))}catch(_){return M.json(B("INTERNAL_ERROR",String(_)),500)}}),O.post("/v1/memory/import",async(M)=>{try{let _=await M.req.json(),$=_.mode==="replace"?"overwrite":"skip-duplicates",R=await A.import(_.payload,{mode:$});return M.json(C(R))}catch{return M.json(B("VALIDATION_ERROR","Invalid import payload"),400)}}),O.get("/v1/memory/stats",(M)=>{return M.json(C(A.stats()))}),O.get("/v1/health",(M)=>{let _=A.getHealth(),$=A.getMetrics(),R=E?.(),D={status:_.status,timestamp:_.timestamp,uptimeMs:process.uptime()*1000,queue:{mode:"in-process",running:!1,processing:!1,pending:0,lastBatchDurationMs:0,lastProcessedAt:null,lastFailedAt:null,lastError:null},batches:{total:0,processedItems:0,failedItems:0,avgDurationMs:0},enqueueCount:0},l=R??D;return M.json(C({status:l.status,timestamp:l.timestamp,uptimeMs:l.uptimeMs,queue:l.queue,memory:{totalObservations:$.memory.totalObservations,totalSessions:$.memory.totalSessions}}))}),O.get("/v1/metrics",(M)=>{let _=A.getHealth(),R=E?.()??{status:_.status,timestamp:_.timestamp,uptimeMs:process.uptime()*1000,queue:{mode:"in-process",running:!1,processing:!1,pending:0,lastBatchDurationMs:0,lastProcessedAt:null,lastFailedAt:null,lastError:null},batches:{total:0,processedItems:0,failedItems:0,avgDurationMs:0},enqueueCount:0};return M.json(C(R))}),O.get("/v1/platforms",(M)=>{let _=A.getAdapterStatuses();return M.json(C({platforms:_.map(($)=>({name:$.name,version:$.version,enabled:$.enabled,capabilities:$.capabilities}))}))}),O.get("/v1/adapters/status",(M)=>{return M.json(C(A.getAdapterStatuses()))}),O.get("/v1/config/schema",(M)=>M.json(C(R0()))),O.get("/v1/config/effective",async(M)=>{let _=await p(n);return M.json(C({config:jf(_.config),meta:_.meta,warnings:_.warnings}))}),O.post("/v1/config/preview",async(M)=>{try{let _=await M.req.json(),$=await l0(n,_);return M.json(C({config:jf($.config),meta:$.meta,warnings:$.warnings}))}catch{return M.json(B("VALIDATION_ERROR","Invalid JSON body"),400)}}),O.patch("/v1/config",async(M)=>{let _;try{_=await M.req.json()}catch{return M.json(B("VALIDATION_ERROR","Invalid JSON body"),400)}try{let $=await b(n),R=await Gf(n,_),D={};for(let l of Object.keys(_))if(Object.hasOwn($,l))D[l]=$[l];return A.trackConfigAudit({id:Rf(),timestamp:new Date().toISOString(),patch:_,previousValues:D,source:"api"}),M.json(C({config:jf(R.config),meta:R.meta,warnings:R.warnings}))}catch($){return M.json(B("INTERNAL_ERROR",String($)),500)}}),O.get("/v1/config/audit",(M)=>{return M.json(C(A.getConfigAuditTimeline()))}),O.post("/v1/config/rollback",async(M)=>{let _;try{_=await M.req.json()}catch{return M.json(B("VALIDATION_ERROR","Invalid JSON body"),400)}if(!_.eventId)return M.json(B("VALIDATION_ERROR","eventId is required"),400);try{let $=await A.rollbackConfig(_.eventId);if(!$)return M.json(B("NOT_FOUND","Audit event not found"),404);return M.json(C($))}catch($){return M.json(B("INTERNAL_ERROR",String($)),500)}});let S={balanced:{minOutputLength:50,contextFullObservationCount:3,maxObservations:50,batchSize:5},focus:{minOutputLength:120,contextFullObservationCount:2,maxObservations:30,batchSize:3},chill:{minOutputLength:200,contextFullObservationCount:1,maxObservations:15,batchSize:2,compressionEnabled:!1}};if(O.get("/v1/modes",(M)=>M.json(C({modes:Object.entries(S).map(([_,$])=>({id:_,patch:$}))}))),O.post("/v1/modes/:id/apply",async(M)=>{let _=M.req.param("id"),$=S[_];if(!$)return M.json(B("NOT_FOUND","Unknown mode"),404);try{let R=await b(n),D=await Gf(n,$),l={};for(let u of Object.keys($))if(Object.hasOwn(R,u))l[u]=R[u];return A.trackConfigAudit({id:Rf(),timestamp:new Date().toISOString(),patch:$,previousValues:l,source:"mode"}),M.json(C({applied:_,config:jf(D.config),meta:D.meta,warnings:D.warnings}))}catch(R){return M.json(B("INTERNAL_ERROR",String(R)),500)}}),O.post("/v1/maintenance/folder-context/dry-run",async(M)=>{try{let $=(await M.req.json().catch(()=>({}))).action??"clean",R=await A.maintainFolderContext($,!0);return A.trackMaintenanceResult({id:Rf(),timestamp:new Date().toISOString(),action:`folder-context-${$}-dry-run`,dryRun:!0,result:R}),M.json(C(R))}catch(_){return M.json(B("INTERNAL_ERROR",String(_)),500)}}),O.post("/v1/maintenance/folder-context/clean",async(M)=>{try{let _=await A.maintainFolderContext("clean",!1);return A.trackMaintenanceResult({id:Rf(),timestamp:new Date().toISOString(),action:"folder-context-clean",dryRun:!1,result:_}),M.json(C(_))}catch(_){return M.json(B("INTERNAL_ERROR",String(_)),500)}}),O.post("/v1/maintenance/folder-context/rebuild",async(M)=>{try{let _=await A.maintainFolderContext("rebuild",!1);return A.trackMaintenanceResult({id:Rf(),timestamp:new Date().toISOString(),action:"folder-context-rebuild",dryRun:!1,result:_}),M.json(C(_))}catch(_){return M.json(B("INTERNAL_ERROR",String(_)),500)}}),O.get("/v1/maintenance/history",(M)=>{return M.json(C(A.getMaintenanceHistory()))}),f.sseHandler)O.get("/v1/events",f.sseHandler);return O.get("*",async(M)=>{let _=M.req.path;if(_.startsWith("/v1/"))return M.json(B("NOT_FOUND","Not found"),404);let $=N??y0(Y1(import.meta.url),"../../dist/dashboard"),R=m1($),D=R.endsWith(Zn)?R:`${R}${Zn}`,l=_==="/"?"index.html":_.replace(/^\//,""),u=y0($,l);if(!u.startsWith(D))return M.json(B("NOT_FOUND","Not found"),404);try{let V=Bun.file(u);if(await V.exists())return new Response(V)}catch{}let Q=y0($,"index.html");if(!Q.startsWith(D))return M.json(B("NOT_FOUND","Not found"),404);try{let V=Bun.file(Q);if(await V.exists())return new Response(V,{headers:{"Content-Type":"text/html; charset=utf-8"}})}catch{}return M.json(B("NOT_FOUND","Dashboard not found. Run the dashboard build first."),404)}),O}var V0=class{writer;encoder;writable;abortSubscribers=[];responseReadable;aborted=!1;closed=!1;constructor(f,n){this.writable=f,this.writer=f.getWriter(),this.encoder=new TextEncoder;let A=n.getReader();this.abortSubscribers.push(async()=>{await A.cancel()}),this.responseReadable=new ReadableStream({async pull(E){let{done:N,value:O}=await A.read();N?E.close():E.enqueue(O)},cancel:()=>{this.abort()}})}async write(f){try{if(typeof f==="string")f=this.encoder.encode(f);await this.writer.write(f)}catch{}return this}async writeln(f){return await this.write(f+`
3
+ `),this}sleep(f){return new Promise((n)=>setTimeout(n,f))}async close(){try{await this.writer.close()}catch{}this.closed=!0}async pipe(f){this.writer.releaseLock(),await f.pipeTo(this.writable,{preventClose:!0}),this.writer=this.writable.getWriter()}onAbort(f){this.abortSubscribers.push(f)}abort(){if(!this.aborted)this.aborted=!0,this.abortSubscribers.forEach((f)=>f())}};var Hf=()=>{let f=typeof Bun<"u"?Bun.version:void 0;if(f===void 0)return!1;let n=f.startsWith("1.1")||f.startsWith("1.0")||f.startsWith("0.");return Hf=()=>n,n};var Yn=class extends V0{constructor(f,n){super(f,n)}async writeSSE(f){let A=(await Of(f.data,Xf.Stringify,!1,{})).split(/\r\n|\r|\n/).map((N)=>{return`data: ${N}`}).join(`
4
+ `),E=[f.event&&`event: ${f.event}`,A,f.id&&`id: ${f.id}`,f.retry&&`retry: ${f.retry}`].filter(Boolean).join(`
5
+ `)+`
6
+
7
+ `;await this.write(E)}},G1=async(f,n,A)=>{try{await n(f)}catch(E){if(E instanceof Error&&A)await A(E,f),await f.writeSSE({event:"error",data:E.message});else console.error(E)}finally{f.close()}},j1=new WeakMap,B0=(f,n,A)=>{let{readable:E,writable:N}=new TransformStream,O=new Yn(N,E);if(Hf())f.req.raw.signal.addEventListener("abort",()=>{if(!O.closed)O.abort()});return j1.set(O.responseReadable,f),f.header("Transfer-Encoding","chunked"),f.header("Content-Type","text/event-stream"),f.header("Cache-Control","no-cache"),f.header("Connection","keep-alive"),G1(O,n,A),f.newResponse(O.responseReadable)};class J0{eventBus;clients=new Set;cleanups=[];constructor(f){this.eventBus=f;this.subscribeToAll()}addClient(f){this.clients.add(f)}removeClient(f){this.clients.delete(f)}get clientCount(){return this.clients.size}destroy(){for(let f of this.cleanups)f();this.cleanups=[],this.clients.clear()}subscribeToAll(){let f=["observation:created","observation:updated","session:started","session:ended","summary:created","pending:enqueued","pending:processed"];for(let n of f){let A=(E)=>this.broadcast(n,E);this.eventBus.on(n,A),this.cleanups.push(()=>this.eventBus.off(n,A))}}broadcast(f,n){let A=JSON.stringify(n);for(let E of this.clients)try{let N=E(f,A);if(N&&typeof N.catch==="function")N.catch(()=>this.clients.delete(E))}catch{this.clients.delete(E)}}}var g1=30000;function Fn(f){return(n)=>{return B0(n,async(A)=>{let E=(O,S)=>{A.writeSSE({event:O,data:S,id:Date.now().toString()})};f.addClient(E);let N=setInterval(()=>{A.writeSSE({event:"heartbeat",data:"",id:Date.now().toString()})},g1);A.onAbort(()=>{f.removeClient(E),clearInterval(N)});while(!A.aborted)await A.sleep(1000)})}}function X(f){return JSON.stringify(f,null,2)}function T1(f,n){return f.filter((A)=>n==="all"?!0:n==="user"?A.source==="user":A.source!=="user").map((A)=>({id:A.observation.id,title:A.observation.title,type:A.observation.type,summary:A.observation.narrative,snippet:A.snippet,score:A.rank,source:A.source??"project",createdAt:A.observation.createdAt}))}function cn(f){return{"memory.find":{description:"Find relevant memories by query with optional filtering.",args:Z.find.shape,execute:async(n)=>{try{let A=Z.find.parse(n),E=await f.search(A.query,{limit:A.limit,type:A.types?.[0]}),N=C({results:T1(E,A.scope),nextCursor:null});return X(N)}catch(A){return X(B("VALIDATION_ERROR","Invalid find arguments",String(A)))}}},"memory.history":{description:"Browse session history and summaries.",args:Z.history.shape,execute:async(n)=>{try{let A=Z.history.parse(n),E=await f.timeline({limit:A.limit,sessionId:A.sessionId});return X(C({items:E,nextCursor:null}))}catch(A){return X(B("VALIDATION_ERROR","Invalid history arguments",String(A)))}}},"memory.get":{description:"Get full memory records by ID.",args:Z.get.shape,execute:async(n)=>{try{let A=Z.get.parse(n),E=await f.recall(A.ids,A.limit);return X(C({observations:E}))}catch(A){return X(B("VALIDATION_ERROR","Invalid get arguments",String(A)))}}},"memory.create":{description:"Create a memory record.",args:Z.create.shape,execute:async(n,A)=>{try{let E=Z.create.parse(n),N=await f.save({...E,sessionId:A.sessionID});if(!N)return X(B("CONFLICT","Unable to create memory"));return X(C({observation:N}))}catch(E){return X(B("VALIDATION_ERROR","Invalid create arguments",String(E)))}}},"memory.revise":{description:"Create a new revision for an existing memory.",args:Z.revise.shape,execute:async(n)=>{try{let A=Z.revise.parse(n),E=await f.update(A);if(!E)return X(B("NOT_FOUND",`Observation ${A.id} not found`));return X(C({previousId:A.id,newId:E.id,observation:E}))}catch(A){return X(B("VALIDATION_ERROR","Invalid revise arguments",String(A)))}}},"memory.remove":{description:"Tombstone a memory record.",args:Z.remove.shape,execute:async(n)=>{try{let A=Z.remove.parse(n);if(await f.delete([A.id])===0)return X(B("NOT_FOUND",`Observation ${A.id} not found`));return X(C({id:A.id,tombstoned:!0}))}catch(A){return X(B("VALIDATION_ERROR","Invalid remove arguments",String(A)))}}},"memory.transfer.export":{description:"Export project memory as JSON payload.",args:Z.transferExport.shape,execute:async(n)=>{try{let A=Z.transferExport.parse(n),E=await f.export("project",{type:A.type,limit:A.limit});return X(C({payload:E,format:A.format}))}catch(A){return X(B("VALIDATION_ERROR","Invalid export arguments",String(A)))}}},"memory.transfer.import":{description:"Import memory payload.",args:Z.transferImport.shape,execute:async(n)=>{try{let A=Z.transferImport.parse(n),E=A.mode==="replace"?"overwrite":"skip-duplicates",N=await f.import(A.payload,{mode:E});return X(C({imported:N.imported,skipped:N.skipped,mode:A.mode}))}catch(A){return X(B("VALIDATION_ERROR","Invalid import arguments",String(A)))}}},"memory.maintenance":{description:"Run memory maintenance actions.",args:Z.maintenance.shape,execute:async(n)=>{try{let A=Z.maintenance.parse(n);if(A.action==="folderContextDryRun")return X(C(await f.maintainFolderContext("clean",!0)));if(A.action==="folderContextClean")return X(C(await f.maintainFolderContext("clean",!1)));return X(C(await f.maintainFolderContext("rebuild",!1)))}catch(A){return X(B("VALIDATION_ERROR","Invalid maintenance arguments",String(A)))}}},"memory.help":{description:"Show memory workflow guidance.",args:Z.help.shape,execute:async()=>X(C({guide:f.guide()}))}}}import{generateText as r1}from"ai";var P1=new Set(["decision","bugfix","feature","refactor","discovery","change"]);function L(f,n){let A=new RegExp(`<${n}[^>]*>([\\s\\S]*?)</${n}>`,"i"),E=f.match(A);return E?E[1].trim():""}function T(f,n){let A=new RegExp(`<${n}[^>]*>([\\s\\S]*?)</${n}>`,"gi"),E=[];for(let N of f.matchAll(A)){let O=N[1].trim();if(O)E.push(O)}return E}function Gn(f){let n=L(f,"observation");if(!n)return null;let A=L(n,"type").toLowerCase(),E=P1.has(A)?A:"discovery",N=L(n,"title")||"Untitled observation",O=L(n,"subtitle"),S=L(n,"narrative"),M=T(L(n,"facts"),"fact"),_=T(L(n,"concepts"),"concept"),$=T(L(n,"files_read"),"file"),R=T(L(n,"files_modified"),"file"),D=L(n,"importance"),l=Number.parseInt(D,10),u=Number.isNaN(l)?3:Math.max(1,Math.min(5,l));return{type:E,title:N,subtitle:O,facts:M,narrative:S,concepts:_,filesRead:$,filesModified:R,importance:u}}function jn(f){let n=L(f,"session_summary");if(!n)return null;let A=L(n,"summary")||"No summary available",E=T(L(n,"key_decisions"),"decision"),N=T(L(n,"files_modified"),"file"),O=T(L(n,"concepts"),"concept"),S=L(n,"request")||void 0,M=L(n,"investigated")||void 0,_=L(n,"learned")||void 0,$=L(n,"completed")||void 0,R=L(n,"next_steps")||void 0;return{summary:A,keyDecisions:E,filesModified:N,concepts:O,request:S,investigated:M,learned:_,completed:$,nextSteps:R}}function Hn(f){let n=L(f,"reranked");if(!n)return null;let A=T(n,"index");if(A.length===0)return null;let E=[];for(let N of A){let O=Number.parseInt(N,10);if(Number.isNaN(O)||O<0)return null;E.push(O)}return E}var k1=new Set(["new_fact","update","duplicate"]);function gn(f){let n=L(f,"evaluation");if(!n)return null;let A=L(n,"outcome").toLowerCase().trim();if(!k1.has(A))return null;let E=A,N=L(n,"reason");if(!N)return null;let O=L(n,"supersedes"),S={outcome:E,reason:N};if(E==="update"&&O)S.supersedesId=O;if(E==="update"&&!S.supersedesId)return null;return S}var I1=new Set(["technology","library","pattern","concept","file","person","project","other"]),w1=new Set(["uses","depends_on","implements","extends","related_to","replaces","configures"]);function Tn(f){let n=L(f,"extraction");if(!n)return null;let A=L(n,"entities"),E=L(n,"relations"),N=T(A,"entity"),O=[];for(let _ of N){let $=L(_,"name");if(!$)continue;let R=L(_,"type").toLowerCase(),D=I1.has(R)?R:"other";O.push({name:$,entityType:D})}let S=T(E,"relation"),M=[];for(let _ of S){let $=L(_,"source"),R=L(_,"target"),D=L(_,"relationship").toLowerCase();if(!$||!R||!D)continue;if(!w1.has(D))continue;M.push({sourceName:$,targetName:R,relationship:D})}return{entities:O,relations:M}}function Y(f){return Math.ceil(f.length/4)}function Pn(f,n,A){let E=A?`<session_context>
8
+ ${A}
30
9
  </session_context>
31
10
 
32
11
  `:"";return`<task>
33
12
  Analyze the following tool output and extract a structured observation.
34
13
  </task>
35
14
 
36
- <tool_name>${$}</tool_name>
15
+ <tool_name>${f}</tool_name>
37
16
 
38
17
  <tool_output>
39
- ${f}
18
+ ${n}
40
19
  </tool_output>
41
20
 
42
- ${Q}<instructions>
21
+ ${E}<instructions>
43
22
  Extract a structured observation from the tool output. Determine the most appropriate type and provide a concise but informative summary.
44
23
 
45
24
  When extracting concepts, prefer established vocabulary where appropriate:
@@ -74,18 +53,18 @@ Respond with EXACTLY this XML format:
74
53
  <file>path/to/file/modified</file>
75
54
  </files_modified>
76
55
  </observation>
77
- </instructions>`}function u$($,f){let J=$.map((Q,M)=>` <obs index="${M+1}" type="${Q.type}">
78
- <title>${Q.title}</title>
79
- <narrative>${Q.narrative}</narrative>
56
+ </instructions>`}function kn(f,n){let A=f.map((E,N)=>` <obs index="${N+1}" type="${E.type}">
57
+ <title>${E.title}</title>
58
+ <narrative>${E.narrative}</narrative>
80
59
  </obs>`).join(`
81
60
  `);return`<task>
82
61
  Summarize the following coding session based on its observations.
83
62
  </task>
84
63
 
85
- <session_id>${f}</session_id>
64
+ <session_id>${n}</session_id>
86
65
 
87
66
  <observations>
88
- ${J}
67
+ ${A}
89
68
  </observations>
90
69
 
91
70
  <instructions>
@@ -109,21 +88,21 @@ Respond with EXACTLY this XML format:
109
88
  <concept>key-concept</concept>
110
89
  </concepts>
111
90
  </session_summary>
112
- </instructions>`}function m$($,f){let J=f.map((Q)=>` <candidate id="${Q.id}">
113
- <title>${Q.title}</title>
114
- <narrative>${Q.narrative}</narrative>
115
- <concepts>${Q.concepts.join(", ")}</concepts>
116
- <type>${Q.type}</type>
91
+ </instructions>`}function In(f,n){let A=n.map((E)=>` <candidate id="${E.id}">
92
+ <title>${E.title}</title>
93
+ <narrative>${E.narrative}</narrative>
94
+ <concepts>${E.concepts.join(", ")}</concepts>
95
+ <type>${E.type}</type>
117
96
  </candidate>`).join(`
118
97
  `);return`<conflict_evaluation>
119
98
  <new_observation>
120
- <title>${$.title}</title>
121
- <narrative>${$.narrative}</narrative>
122
- <concepts>${$.concepts.join(", ")}</concepts>
123
- <type>${$.type}</type>
99
+ <title>${f.title}</title>
100
+ <narrative>${f.narrative}</narrative>
101
+ <concepts>${f.concepts.join(", ")}</concepts>
102
+ <type>${f.type}</type>
124
103
  </new_observation>
125
104
  <existing_candidates>
126
- ${J}
105
+ ${A}
127
106
  </existing_candidates>
128
107
  <instructions>
129
108
  Evaluate whether the new observation represents:
@@ -138,16 +117,16 @@ Respond with EXACTLY this XML format:
138
117
  <reason>Brief explanation</reason>
139
118
  </evaluation>
140
119
  </instructions>
141
- </conflict_evaluation>`}function l$($){let f=[...$.filesRead,...$.filesModified];return`<entity_extraction>
120
+ </conflict_evaluation>`}function wn(f){let n=[...f.filesRead,...f.filesModified];return`<entity_extraction>
142
121
  <observation>
143
- <title>${$.title}</title>
144
- <type>${$.type}</type>
145
- <narrative>${$.narrative}</narrative>
146
- <facts>${$.facts.join(`
122
+ <title>${f.title}</title>
123
+ <type>${f.type}</type>
124
+ <narrative>${f.narrative}</narrative>
125
+ <facts>${f.facts.join(`
147
126
  `)}</facts>
148
- <files>${f.join(`
127
+ <files>${n.join(`
149
128
  `)}</files>
150
- <concepts>${$.concepts.join(", ")}</concepts>
129
+ <concepts>${f.concepts.join(", ")}</concepts>
151
130
  </observation>
152
131
  <instructions>
153
132
  Extract entities and relationships from this observation.
@@ -167,11 +146,11 @@ Respond with EXACTLY this XML format:
167
146
  </relations>
168
147
  </extraction>
169
148
  </instructions>
170
- </entity_extraction>`}function c$($,f){let J=f.map((Q,M)=>` <candidate index="${M}"><title>${Q.title}</title><narrative>${Q.narrative}</narrative></candidate>`).join(`
149
+ </entity_extraction>`}function xn(f,n){let A=n.map((E,N)=>` <candidate index="${N}"><title>${E.title}</title><narrative>${E.narrative}</narrative></candidate>`).join(`
171
150
  `);return`<rerank_request>
172
- <query>${$}</query>
151
+ <query>${f}</query>
173
152
  <candidates>
174
- ${J}
153
+ ${A}
175
154
  </candidates>
176
155
  <instructions>Reorder the candidates by relevance to the query. Return indices from most to least relevant.
177
156
 
@@ -182,114 +161,117 @@ Respond with EXACTLY this XML format:
182
161
  <index>0</index>
183
162
  </reranked>
184
163
  </instructions>
185
- </rerank_request>`}var T2={"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 I2($){if($.includes("."))return $;return T2[$]||`us.anthropic.${$}-v1:0`}function k($){switch($.provider){case"anthropic":{let{createAnthropic:f}=I("@ai-sdk/anthropic");return f({apiKey:$.apiKey})($.model)}case"bedrock":{let{createAmazonBedrock:f}=I("@ai-sdk/amazon-bedrock");return f()(I2($.model))}case"openai":{let{createOpenAI:f}=I("@ai-sdk/openai");return f({apiKey:$.apiKey})($.model)}case"google":{let{createGoogleGenerativeAI:f}=I("@ai-sdk/google");return f({apiKey:$.apiKey})($.model)}default:throw Error(`Unknown provider: ${$.provider}. Supported: anthropic, bedrock, openai, google`)}}function p$($){try{switch($.provider){case"google":{let{createGoogleGenerativeAI:f}=I("@ai-sdk/google");return f({apiKey:$.apiKey}).embedding("text-embedding-004")}case"openai":{let{createOpenAI:f}=I("@ai-sdk/openai");return f({apiKey:$.apiKey}).embedding("text-embedding-3-small")}case"bedrock":{let{createAmazonBedrock:f}=I("@ai-sdk/amazon-bedrock");return f().embedding("amazon.titan-embed-text-v2:0")}case"anthropic":return null;default:return null}}catch{return null}}var x2={"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},n$=0;async function T($,f){if(!f)return;let J=x2[$]||5,Q=Math.ceil(60000/J)+100,X=Date.now()-n$;if(X<Q){let W=Q-X;await new Promise((Z)=>setTimeout(Z,W))}n$=Date.now()}class r{model;config;_generate=P2;constructor($){this.config=$,this.model=null;let f=$.provider!=="bedrock";if($.compressionEnabled&&(!f||$.apiKey))try{this.model=k({provider:$.provider,model:$.model,apiKey:$.apiKey})}catch{}}static MAX_INPUT_LENGTH=50000;async compress($,f,J){if(!this.config.compressionEnabled||!this.model)return null;if(f.length<this.config.minOutputLength)return null;let Q=L(f),M=f.length>r.MAX_INPUT_LENGTH?`${f.substring(0,r.MAX_INPUT_LENGTH)}
186
-
187
- [... truncated ...]`:f,X=b$($,M,J),W=2;for(let Z=0;Z<=W;Z++)try{if(this.config.provider==="google")await T(this.config.model,this.config.rateLimitingEnabled);let{text:N}=await this._generate({model:this.model,maxOutputTokens:this.config.maxTokensPerCompression,prompt:X}),S=q$(N);if(S)S.discoveryTokens=Q;return S}catch(N){if(v2(N)&&Z<W){let S=2**Z*1000;await d$(S);continue}return null}return null}async compressBatch($){let f=new Map;for(let J=0;J<$.length;J++){let Q=$[J],M=await this.compress(Q.toolName,Q.toolOutput,Q.sessionContext);if(f.set(Q.callId,M),J<$.length-1)await d$(200)}return f}createFallbackObservation($,f){let J=y2(f),Q=w2[$]??"discovery";return{type:Q,title:`${$} execution`,subtitle:f.substring(0,100).replace(/\n/g," "),facts:[],narrative:`Tool ${$} was executed. Output length: ${f.length} chars.`,concepts:[],filesRead:Q==="discovery"?J:[],filesModified:Q==="change"?J:[],discoveryTokens:L(f),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 w2={Read:"discovery",Write:"change",Edit:"change",Bash:"change",Glob:"discovery",Grep:"discovery"},q2=/(?:^|\s)((?:\.\/|\/|src\/|tests\/|lib\/)\S+\.\w+)/gm;function y2($){let f=[];for(let J of $.matchAll(q2))f.push(J[1]);return[...new Set(f)]}function v2($){if(typeof $!=="object"||$===null)return!1;let f=$,J=f.status;if(J===429||J===500||J===503)return!0;let Q=f.error;if(typeof Q==="object"&&Q!==null&&Q.type==="overloaded_error")return!0;return!1}function d$($){return new Promise((f)=>setTimeout(f,$))}import{generateText as g2}from"ai";class g0{model;config;_generate=g2;constructor($){if(this.config=$,this.model=null,$.provider==="bedrock"||$.apiKey)try{this.model=k({provider:$.provider,model:$.model,apiKey:$.apiKey})}catch{}}async evaluate($,f){if(!this.model||f.length===0)return null;let J=m$($,f),Q=2;for(let M=0;M<=Q;M++)try{if(this.config.provider==="google")await T(this.config.model,this.config.rateLimitingEnabled);let{text:X}=await this._generate({model:this.model,maxOutputTokens:512,prompt:J});return g$(X)}catch(X){if(h2(X)&&M<Q){let W=2**M*1000;await b2(W);continue}return null}return null}}function h2($){if(typeof $!=="object"||$===null)return!1;let f=$,J=f.status;if(J===429||J===500||J===503)return!0;let Q=f.error;if(typeof Q==="object"&&Q!==null&&Q.type==="overloaded_error")return!0;return!1}function b2($){return new Promise((f)=>setTimeout(f,$))}import{generateText as u2}from"ai";class h0{model;config;_generate=u2;constructor($){if(this.config=$,this.model=null,$.provider==="bedrock"||$.apiKey)try{this.model=k({provider:$.provider,model:$.model,apiKey:$.apiKey})}catch{}}async extract($){if(!this.model)return null;let f=l$($),J=2;for(let Q=0;Q<=J;Q++)try{if(this.config.provider==="google")await T(this.config.model,this.config.rateLimitingEnabled);let{text:M}=await this._generate({model:this.model,maxOutputTokens:1024,prompt:f});return h$(M)}catch(M){if(m2(M)&&Q<J){let X=2**Q*1000;await l2(X);continue}return null}return null}}function m2($){if(typeof $!=="object"||$===null)return!1;let f=$,J=f.status;if(J===429||J===500||J===503)return!0;let Q=f.error;if(typeof Q==="object"&&Q!==null&&Q.type==="overloaded_error")return!0;return!1}function l2($){return new Promise((f)=>setTimeout(f,$))}import{generateText as c2}from"ai";class b0{model;config;_generate=c2;constructor($){this.config=$,this.model=null;let f=$.provider!=="bedrock";if($.compressionEnabled&&(!f||$.apiKey))try{this.model=k({provider:$.provider,model:$.model,apiKey:$.apiKey})}catch{}}async summarize($,f){if(f.length===0)return null;if(!this.config.compressionEnabled||!this.model)return this.createFallbackSummary(f);let J=u$(f.map((Q)=>({type:Q.type,title:Q.title,narrative:Q.narrative})),$);try{if(this.config.provider==="google")await T(this.config.model,this.config.rateLimitingEnabled);let{text:Q}=await this._generate({model:this.model,maxOutputTokens:this.config.maxTokensPerCompression,prompt:J}),M=y$(Q);if(!M)return this.createFallbackSummary(f);return M}catch{return this.createFallbackSummary(f)}}createFallbackSummary($){let f=new Set,J=new Set,Q=[];for(let Z of $){for(let N of Z.filesModified)f.add(N);for(let N of Z.concepts)J.add(N);if(Z.type==="decision")Q.push(Z.title)}let M=new Map;for(let Z of $)M.set(Z.type,(M.get(Z.type)??0)+1);let X=Array.from(M.entries()).map(([Z,N])=>`${N} ${Z}${N>1?"s":""}`).join(", "),W=Array.from(J).slice(0,5).join(", ");return{summary:`Session with ${$.length} observations: ${X}. Files modified: ${f.size}. Key concepts: ${W}.`,keyDecisions:Q.slice(0,5),filesModified:Array.from(f),concepts:Array.from(J)}}shouldSummarize($){return $>=2}}import{existsSync as p2,readFileSync as n2}from"fs";var i$={dbPath:".open-mem/memory.db",provider:"google",apiKey:void 0,model:"gemini-2.5-flash-lite",maxTokensPerCompression:1024,compressionEnabled:!0,contextInjectionEnabled:!0,maxContextTokens:4000,batchSize:5,batchIntervalMs:30000,ignoredTools:[],minOutputLength:50,maxIndexEntries:20,sensitivePatterns:[],retentionDays:90,maxDatabaseSizeMb:500,logLevel:"warn",contextShowTokenCosts:!0,contextObservationTypes:"all",contextFullObservationCount:3,maxObservations:50,contextShowLastSummary:!0,rateLimitingEnabled:!0,folderContextEnabled:!0,folderContextMaxDepth:5,daemonEnabled:!1,dashboardEnabled:!1,dashboardPort:3737,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};function d2(){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((f)=>f.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((f)=>f.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_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_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 f=Number.parseFloat(process.env.OPEN_MEM_CONFLICT_BAND_LOW);if(!Number.isNaN(f))$.conflictSimilarityBandLow=f}if(process.env.OPEN_MEM_CONFLICT_BAND_HIGH){let f=Number.parseFloat(process.env.OPEN_MEM_CONFLICT_BAND_HIGH);if(!Number.isNaN(f))$.conflictSimilarityBandHigh=f}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;return $}function i2($){let f=`${$}/.open-mem/config.json`;if(!p2(f))return{};try{let J=n2(f,"utf-8"),Q=JSON.parse(J);if(!Q||typeof Q!=="object"||Array.isArray(Q))return{};return Q}catch{return{}}}function r2($){switch($){case"google":return 768;case"openai":return 1536;case"bedrock":return 1024;case"anthropic":return 0;default:return 768}}function b($,f){let J=i2($),Q=d2(),M={...i$,...J,...Q,...f};if(!M.dbPath.startsWith("/"))M.dbPath=`${$}/${M.dbPath}`;if(!process.env.OPEN_MEM_PROVIDER&&!f?.provider){if(process.env.GOOGLE_GENERATIVE_AI_API_KEY||process.env.GEMINI_API_KEY)M.provider="google";else if(process.env.ANTHROPIC_API_KEY)M.provider="anthropic";else if(process.env.AWS_BEARER_TOKEN_BEDROCK||process.env.AWS_ACCESS_KEY_ID||process.env.AWS_PROFILE)M.provider="bedrock"}if(!M.apiKey)switch(M.provider){case"google":M.apiKey=process.env.GOOGLE_GENERATIVE_AI_API_KEY||process.env.GEMINI_API_KEY;break;case"anthropic":M.apiKey=process.env.ANTHROPIC_API_KEY;break;case"openai":M.apiKey=process.env.OPENAI_API_KEY;break;case"bedrock":break}if(M.embeddingDimension===void 0)M.embeddingDimension=r2(M.provider);return M}function r$($){let f=[],J=$.provider!=="bedrock";if($.compressionEnabled&&J&&!$.apiKey)f.push("AI compression enabled but no API key found. Get a free Gemini API key at https://aistudio.google.com/apikey and set GOOGLE_GENERATIVE_AI_API_KEY, or set OPEN_MEM_PROVIDER and the appropriate API key for your provider.");if($.maxContextTokens<500)f.push("maxContextTokens must be at least 500");if($.batchSize<1)f.push("batchSize must be at least 1");if($.minOutputLength<0)f.push("minOutputLength must be non-negative");return f}function S0(){return{...i$}}async function s$($){let f=$.dbPath.substring(0,$.dbPath.lastIndexOf("/")),{mkdir:J}=await import("fs/promises");await J(f,{recursive:!0})}var s2={showTokenCosts:!0,observationTypes:"all",fullObservationCount:3,showLastSummary:!0},s={bugfix:"\uD83D\uDD34",feature:"\uD83D\uDFE3",refactor:"\uD83D\uDD04",change:"\u2705",discovery:"\uD83D\uDD35",decision:"\u2696\uFE0F"};function K0($,f=s2){let J=[];if(J.push("## open-mem: Past Session Memory"),J.push(""),J.push("**\uD83D\uDCA1 Progressive Disclosure:** This is a compact index showing WHAT was observed and retrieval COST."),J.push("Use `mem-search` to find observations by query, then `mem-recall` with IDs to fetch full details."),J.push(""),J.push("**3-Layer Memory Access:**"),J.push("- **Layer 1** `mem-search` \u2014 Find observations by query (returns IDs + summaries)"),J.push("- **Layer 2** `mem-timeline` \u2014 Browse session history and drill into sessions"),J.push("- **Layer 3** `mem-recall` \u2014 Get full details by ID (use IDs from search results or the index below)"),f.showLastSummary&&$.recentSummaries.length>0){J.push(""),J.push("### Recent Sessions"),J.push("| Session | Summary | Decisions |"),J.push("|---------|---------|-----------|");for(let W of $.recentSummaries){let Z=W.keyDecisions.length>0?W.keyDecisions.join("; "):"\u2014";J.push(`| ${W.sessionId} | ${W.summary} | ${Z} |`)}}let Q=f.observationTypes==="all"?$.observationIndex:$.observationIndex.filter((W)=>f.observationTypes.includes(W.type));if(Q.length>0){J.push(""),J.push(`### Recent Observations (${Q.length} entries)`);let W=o2(Q,$.fullObservations);for(let[Z,N]of W){if(J.push(""),J.push(`**${Z}**`),f.showTokenCosts)J.push("| ID | Type | Title | ~Tokens |"),J.push("|----|------|-------|---------|");else J.push("| ID | Type | Title |"),J.push("|----|------|-------|");for(let S of N){let K=s[S.type]||"\uD83D\uDCDD";if(f.showTokenCosts)J.push(`| ${S.id} | ${K} | ${S.title} | ~${S.tokenCount} |`);else J.push(`| ${S.id} | ${K} | ${S.title} |`)}}}let M=$.fullObservations.slice(0,f.fullObservationCount);if(M.length>0){J.push(""),J.push("### Full Details (most recent)");for(let W of M){let Z=s[W.type]||"\uD83D\uDCDD";if(J.push(""),J.push(`#### ${Z} ${W.title} (${W.id})`),J.push(W.narrative),W.facts.length>0)J.push(`**Facts:** ${W.facts.map((S)=>`- ${S}`).join(" ")}`);if(W.concepts.length>0)J.push(`**Concepts:** ${W.concepts.join(", ")}`);let N=[...W.filesRead,...W.filesModified];if(N.length>0)J.push(`**Files:** ${N.join(", ")}`)}}let X=a2($);if(X)J.push(""),J.push(X);return J.join(`
188
- `)}function a2($){let f=0,J=0,Q=new Set($.observationIndex.map((W)=>W.id));for(let W of $.observationIndex)f+=W.tokenCount,J+=W.discoveryTokens;for(let W of $.fullObservations)if(!Q.has(W.id))f+=W.tokenCount,J+=W.discoveryTokens;if(J===0)return null;let M=J-f,X=Math.max(0,Math.round(M/J*100));return`### \uD83D\uDCB0 Memory Economics
189
- **Read cost:** ~${f}t | **Discovery cost:** ~${J}t | **Savings:** ${X}% (${M}t saved)`}function o2($,f){let J=new Map;for(let M of f){let X=M.filesModified[0]||M.filesRead[0];if(X)J.set(M.id,X)}let Q=new Map;for(let M of $){let X=J.get(M.id)??"General",W=Q.get(X)??[];W.push(M),Q.set(X,W)}return Q}function V0($){let f=[];if(f.push("[open-mem] Memory context:"),$.recentSummaries.length>0){f.push(`
190
- Recent sessions:`);for(let J of $.recentSummaries)f.push(`- ${J.summary}`)}if($.observationIndex.length>0){f.push(`
191
- Recent observations (${$.observationIndex.length} entries):`);for(let J of $.observationIndex)f.push(`- ${s[J.type]||"\uD83D\uDCDD"} ${J.title}`)}return f.join(`
192
- `)}function Y0($,f){if($.length===0)return"";let J=f,Q=[];for(let X of $){let W=X.tokenCount||L(X.title);if(J-W<0)break;Q.push(X),J-=W}if(Q.length===0)return"";let M=[];M.push("### Cross-Project Memory"),M.push(""),M.push("| ID | Type | Title | ~Tokens |"),M.push("|----|------|-------|---------|");for(let X of Q){let W=s[X.type]||"\uD83D\uDCDD";M.push(`| ${X.id} | ${W} | ${X.title} | ~${X.tokenCount} |`)}return M.join(`
193
- `)}function U0($,f){if($.length===0)return"";let J=f,Q=[];for(let X of $){let W=X.tokenCount||L(X.title);if(J-W<0)break;Q.push(X),J-=W}if(Q.length===0)return"";let M=[];M.push(`
194
- Cross-project observations (${Q.length} entries):`);for(let X of Q)M.push(`- ${s[X.type]||"\uD83D\uDCDD"} ${X.title}`);return M.join(`
195
- `)}var A0={recency:0.4,typeImportance:0.3,sessionAffinity:0.2,tokenEfficiency:0.1},t2={decision:1,bugfix:0.9,feature:0.8,refactor:0.6,discovery:0.5,change:0.4};function e2($,f){let J=new Date($),M=(f.getTime()-J.getTime())/3600000;if(M<0)return 1;if(M<24)return 1;if(M<48)return 0.8;if(M<168)return 0.5;return 0.2}function $f($){return t2[$]??0.3}function ff($,f){if(!f)return 0.5;return $===f?1:0.3}function Jf($){if($<=10)return 1;if($>=200)return 0.2;return 1-($-10)/190*0.8}function Qf($,f){let J=e2($.createdAt,f.now),Q=$f($.type),M=ff($.sessionId,f.currentSessionId),X=Jf($.tokenCount);return J*A0.recency+Q*A0.typeImportance+M*A0.sessionAffinity+X*A0.tokenEfficiency}function a$($,f){let J=new Map;for(let Q of $)J.set(Q.id,Qf(Q,f));return[...$].sort((Q,M)=>{let X=J.get(Q.id)??0,W=J.get(M.id)??0;if(W!==X)return W-X;return new Date(M.createdAt).getTime()-new Date(Q.createdAt).getTime()})}function u($,f,J,Q,M=[],X){let W=Q,Z=[],N=[];for(let K of f){let V=K.tokenCount||L(K.summary);if(W-V<0)break;Z.push(K),W-=V}let S=X?a$(J,X):J;for(let K of S){let V=K.tokenCount||L(K.title);if(W-V<0)break;N.push(K),W-=V}return{recentSummaries:Z,observationIndex:N,fullObservations:[...M],totalTokens:Q-W}}import{existsSync as Gf}from"fs";import{readdir as _f,readFile as Ff,writeFile as Ef}from"fs/promises";import{join as Lf,resolve as Hf}from"path";import{existsSync as t$}from"fs";import{mkdir as Mf,readFile as Xf,rename as Zf,unlink as Wf,writeFile as Nf}from"fs/promises";import{dirname as l0,isAbsolute as e$,join as B0,normalize as Sf,relative as $1,resolve as m0,sep as u0}from"path";var z0="<!-- open-mem-context -->",a="<!-- /open-mem-context -->",Kf={bugfix:"\uD83D\uDD34",feature:"\uD83D\uDFE3",refactor:"\uD83D\uDD04",change:"\u2705",discovery:"\uD83D\uDD35",decision:"\u2696\uFE0F"},o$=new Map,Vf=new Set(["node_modules",".git","dist","coverage",".open-mem","build","__pycache__",".next",".nuxt"]);async function G0($,f,J=5){if(f.length===0)return;let Q=[];for(let W of f){for(let Z of W.filesModified)Q.push(Z);for(let Z of W.filesRead)Q.push(Z)}let M=zf(Q,$,J);if(M.size===0)return;let X=Bf(f,M,$);for(let[W,Z]of X)try{let N=Yf(W,Z,$);await Uf(W,N)}catch(N){console.error(`[open-mem] Failed to update AGENTS.md in ${W}:`,N)}}function Yf($,f,J){let Q=[...f].sort((N,S)=>S.createdAt.localeCompare(N.createdAt)).slice(0,10),M=$1(J,$)||".",X=[];X.push(`## Recent Activity in \`${M}/\` (auto-generated by open-mem)`),X.push(""),X.push("| Type | Title | Date |"),X.push("|------|-------|------|");for(let N of Q){let S=Kf[N.type]||"\uD83D\uDCDD",K=N.createdAt.split("T")[0],V=N.title.replace(/\|/g,"\\|");X.push(`| ${S} ${N.type} | ${V} | ${K} |`)}let W=new Set;for(let N of Q)for(let S of N.concepts)W.add(S);if(W.size>0){let N=[...W].slice(0,10).join(", ");X.push(""),X.push(`**Key concepts:** ${N}`)}let Z=Q.filter((N)=>N.type==="decision").map((N)=>N.title);if(Z.length>0)X.push(""),X.push(`**Recent decisions:** ${Z.slice(0,5).join("; ")}`);return X.join(`
196
- `)}async function Uf($,f){if(!t$($))return;let Q=(o$.get($)??Promise.resolve()).then(async()=>{let M=B0($,"AGENTS.md"),X=B0($,".AGENTS.md.tmp"),W="";try{W=await Xf(M,"utf-8")}catch{}let Z=Af(W,f);try{await Mf(l0(X),{recursive:!0}),await Nf(X,Z,"utf-8"),await Zf(X,M)}catch(N){try{await Wf(X)}catch{}throw N}});return o$.set($,Q.catch(()=>{})),Q}function Af($,f){if(!$)return`${z0}
197
- ${f}
198
- ${a}
199
- `;let J=$.indexOf(z0),Q=$.indexOf(a);if(J!==-1&&Q!==-1&&Q>J){let M=$.substring(0,J),X=$.substring(Q+a.length);return`${M}${z0}
200
- ${f}
201
- ${a}${X}`}return`${$}
202
-
203
- ${z0}
204
- ${f}
205
- ${a}
206
- `}function zf($,f,J){let Q=new Set,M=m0(f);for(let X of $){if(!X||!X.trim())continue;if(X.startsWith("~")||X.startsWith("http"))continue;let W=e$(X)?X:B0(f,X),Z=l0(W),N=m0(Z);if(!N.startsWith(M+u0)&&N!==M)continue;if(N===M)continue;let S=$1(M,N);if(S.split(u0).length>J)continue;if(Sf(S).split(u0).some((Y)=>Vf.has(Y)))continue;if(!t$(N))continue;Q.add(N)}return Q}function Bf($,f,J){let Q=new Map;for(let M of $){let X=[...M.filesModified,...M.filesRead],W=new Set;for(let Z of X){if(!Z)continue;let N=e$(Z)?Z:B0(J,Z),S=m0(l0(N));if(f.has(S))W.add(S)}for(let Z of W){let N=Q.get(Z)??[];N.push(M),Q.set(Z,N)}}return Q}var Of="<!-- open-mem-context -->",f1="<!-- /open-mem-context -->";async function J1($,f){let J;try{J=await _f($,{withFileTypes:!0,encoding:"utf8"})}catch{return}for(let Q of J){let M=String(Q.name);if(M===".git"||M==="node_modules"||M===".open-mem"||M==="dist")continue;let X=Lf($,M);if(Q.isDirectory())await J1(X,f);else if(Q.isFile()&&M==="AGENTS.md")f.push(X)}}async function Q1($){let f=Hf($),J=[];return await J1(f,J),J}function Df($){let f=$.indexOf(Of),J=$.indexOf(f1);if(f===-1||J===-1||J<=f)return $;let Q=$.slice(0,f).trimEnd(),M=$.slice(J+f1.length).trimStart();if(!Q&&!M)return"";if(!Q)return`${M}
207
- `;if(!M)return`${Q}
208
- `;return`${Q}
209
-
210
- ${M}
211
- `}async function M1($,f=!1){let J=await Q1($),Q=0;for(let M of J){let X=await Ff(M,"utf-8"),W=Df(X);if(W!==X){if(Q+=1,!f)await Ef(M,W,"utf-8")}}return{files:J,changed:Q}}async function X1($,f,J,Q,M=!1){let W=f.getAll($).flatMap((N)=>J.getBySession(N.id));if(M){let N=new Set;for(let S of W)for(let K of[...S.filesRead,...S.filesModified])N.add(K);return{observations:W.length,filesTouched:N.size}}if(!Gf($))return{observations:0,filesTouched:0};await G0($,W,Q);let Z=await Q1($);return{observations:W.length,filesTouched:Z.length}}class c0{observations;sessions;summaries;searchOrchestrator;projectPath;config;userObservationRepo;constructor($){this.observations=$.observations,this.sessions=$.sessions,this.summaries=$.summaries,this.searchOrchestrator=$.searchOrchestrator,this.projectPath=$.projectPath,this.config=$.config,this.userObservationRepo=$.userObservationRepo??null}async ingest($){}async processPending($){return 0}async search($,f={}){return this.searchOrchestrator.search($,{type:f.type,limit:f.limit??10,projectPath:this.projectPath,importanceMin:f.importanceMin,importanceMax:f.importanceMax,createdAfter:f.after,createdBefore:f.before,concepts:f.concepts,files:f.files})}async timeline($={}){if($.sessionId){let J=this.sessions.getById($.sessionId);if(!J)return[];return[{session:J,summary:this.summaries.getBySessionId(J.id),observations:this.observations.getBySession(J.id)}]}return this.sessions.getRecent(this.projectPath,$.limit??5).map((J)=>({session:J,summary:this.summaries.getBySessionId(J.id),observations:[]}))}async recall($,f=10){let J=[];for(let Q of $.slice(0,f)){let M=this.observations.getById(Q);if(M){J.push(M);continue}if(!this.userObservationRepo)continue;let X=this.userObservationRepo.getById(Q);if(!X)continue;J.push({...X,sessionId:"",rawToolOutput:"",discoveryTokens:0})}return J}async save($){if($.scope==="user"){if(!this.userObservationRepo)return null;return{...this.userObservationRepo.create({type:$.type,title:$.title,subtitle:"",facts:[],narrative:$.narrative,concepts:$.concepts??[],filesRead:[],filesModified:$.files??[],toolName:"mem-save",tokenCount:L(`${$.title} ${$.narrative}`),importance:$.importance??3,sourceProject:this.projectPath}),sessionId:"",rawToolOutput:"",discoveryTokens:0}}this.sessions.getOrCreate($.sessionId,this.projectPath);let f=this.observations.create({sessionId:$.sessionId,type:$.type,title:$.title,subtitle:"",facts:[],narrative:$.narrative,concepts:$.concepts??[],filesRead:[],filesModified:$.files??[],rawToolOutput:`[Manual save] ${$.narrative}`,toolName:"mem-save",tokenCount:L(`${$.title} ${$.narrative}`),discoveryTokens:0,importance:$.importance??3});return this.sessions.incrementObservationCount($.sessionId),f}async update($){let f=this.observations.getById($.id);if(!f)return null;let J=this.sessions.getById(f.sessionId);if(!J||J.projectPath!==this.projectPath)return null;let{id:Q,...M}=$;return this.observations.update($.id,M)??null}async delete($){let f=0;for(let J of $){let Q=this.observations.getById(J);if(!Q)continue;let M=this.sessions.getById(Q.sessionId);if(!M||M.projectPath!==this.projectPath)continue;if(this.observations.delete(J))f+=1}return f}async export($,f={}){if($!=="project")throw Error("Only project scope export is supported.");let J=this.sessions.getAll(this.projectPath),Q=[];for(let Z of J)Q.push(...this.observations.getBySession(Z.id));if(f.type)Q=Q.filter((Z)=>Z.type===f.type);if(Q.sort((Z,N)=>new Date(Z.createdAt).getTime()-new Date(N.createdAt).getTime()),f.limit&&f.limit<Q.length)Q=Q.slice(0,f.limit);let M=Q.map(({rawToolOutput:Z,...N})=>N),X=J.map((Z)=>this.summaries.getBySessionId(Z.id)).filter((Z)=>Z!==null);return{version:1,exportedAt:new Date().toISOString(),project:this.projectPath,observations:M,summaries:X}}async import($,f={}){let J;try{J=JSON.parse($)}catch{throw Error("Invalid JSON payload.")}if(typeof J!=="object"||J===null)throw Error("Invalid import payload.");let Q=J;if(Q.version!==1||!Array.isArray(Q.observations))throw Error("Unsupported export format.");let M=f.mode??"skip-duplicates",X=0,W=0;for(let Z of Q.observations){let N=this.observations.getById(Z.id);if(N&&M==="skip-duplicates"){W+=1;continue}if(N&&M==="overwrite")this.observations.delete(Z.id);this.sessions.getOrCreate(Z.sessionId,this.projectPath),this.observations.importObservation({id:Z.id,sessionId:Z.sessionId,type:Z.type,title:Z.title,subtitle:Z.subtitle??"",facts:Z.facts??[],narrative:Z.narrative??"",concepts:Z.concepts??[],filesRead:Z.filesRead??[],filesModified:Z.filesModified??[],rawToolOutput:Z.rawToolOutput??"",toolName:Z.toolName??"unknown",createdAt:Z.createdAt,tokenCount:Z.tokenCount??0,discoveryTokens:Z.discoveryTokens??0,importance:Z.importance??3,supersededBy:Z.supersededBy??null,supersededAt:Z.supersededAt??null}),this.sessions.incrementObservationCount(Z.sessionId),X+=1}for(let Z of Q.summaries??[]){let N=this.summaries.getBySessionId(Z.sessionId);if(N&&M==="skip-duplicates")continue;if(N&&M==="overwrite")continue;this.sessions.getOrCreate(Z.sessionId,this.projectPath),this.summaries.importSummary(Z),this.sessions.setSummary(Z.sessionId,Z.id)}return{imported:X,skipped:W}}async buildContext($,f="normal"){let J=this.sessions.getRecent(this.projectPath,5),Q=J.map((K)=>K.summaryId?this.summaries.getBySessionId(K.id):null).filter((K)=>K!==null),M=this.observations.getIndex(this.projectPath,this.config.maxObservations),W=M.slice(0,this.config.contextFullObservationCount).map((K)=>K.id).map((K)=>this.observations.getById(K)).filter((K)=>K!==null),Z=u(J,Q,M,this.config.maxContextTokens,W);if(f==="compaction"){let K=V0(Z);if(this.config.userMemoryEnabled&&this.userObservationRepo)K+=U0(this.userObservationRepo.getIndex(this.config.maxObservations),this.config.userMemoryMaxContextTokens);return K}let N={showTokenCosts:this.config.contextShowTokenCosts,observationTypes:this.config.contextObservationTypes,fullObservationCount:this.config.contextFullObservationCount,showLastSummary:this.config.contextShowLastSummary},S=K0(Z,N);if(this.config.userMemoryEnabled&&this.userObservationRepo){let K=Y0(this.userObservationRepo.getIndex(this.config.maxObservations),this.config.userMemoryMaxContextTokens);if(K)S+=`
212
-
213
- ${K}`}return S}guide(){return["open-mem workflow:","1) Use mem-search to find candidate observations by query.","2) Use mem-timeline to inspect session-level history and summaries.","3) Use mem-recall with IDs from search/timeline to fetch full details.","Write/edit flow: mem-save (new), mem-update (refine), mem-delete (remove stale).","Transfer flow: mem-export for backup/portability, mem-import to restore."].join(`
214
- `)}listObservations($){let{limit:f=50,offset:J=0,type:Q,sessionId:M}=$;if(M){let Z=this.observations.getBySession(M);if(Q)Z=Z.filter((N)=>N.type===Q);return Z.slice(J,J+f)}let W=this.observations.getIndex(this.projectPath,J+f).slice(J);if(Q)W=W.filter((Z)=>Z.type===Q);return W.map((Z)=>this.observations.getById(Z.id)).filter((Z)=>Z!==null)}getObservation($){return this.observations.getById($)}listSessions($){return this.sessions.getRecent($.projectPath??this.projectPath,$.limit??20)}getSession($){let f=this.sessions.getById($);if(!f)return null;return{session:f,summary:this.summaries.getBySessionId($),observations:this.observations.getBySession($)}}stats(){let $=this.observations.getCount(),J=this.sessions.getAll(this.projectPath).length,Q=this.observations.getIndex(this.projectPath,1e4),M=0,X=0,W={};for(let S of Q)M+=S.tokenCount,X+=S.discoveryTokens,W[S.type]=(W[S.type]||0)+1;let Z=X-M,N=Q.length>0?Math.round(M/Q.length):0;return{totalObservations:$,totalSessions:J,totalTokensSaved:Z,averageObservationSize:N,typeBreakdown:W}}async maintainFolderContext($,f){if($==="rebuild"){let Q=await X1(this.projectPath,this.sessions,this.observations,this.config.folderContextMaxDepth,f);return{action:$,dryRun:f,...Q}}let J=await M1(this.projectPath,f);return{action:"clean",dryRun:f,...J}}}import{existsSync as Pf}from"fs";import{existsSync as Cf}from"fs";import{homedir as jf}from"os";import{join as Z1}from"path";function Rf(){let $=[],f=process.env.BUN_INSTALL;if(f)$.push(Z1(f,"bin","bun"));let J=jf();return $.push(Z1(J,".bun","bin","bun")),$.push("/usr/local/bin/bun"),$.push("/opt/homebrew/bin/bun"),$.push("/home/linuxbrew/.linuxbrew/bin/bun"),$}function kf(){let $=Bun.which("bun");if($)return $;for(let f of Rf())if(Cf(f))return console.debug(`[open-mem] Resolved bun path via candidate scan: ${f}`),f;return"bun"}var p0=null;function W1(){if(p0===null)p0=kf();return p0}import{existsSync as Tf,mkdirSync as e8,readFileSync as If,unlinkSync as xf,writeFileSync as $6}from"fs";function w($){if(!Tf($))return null;let f=If($,"utf-8").trim(),J=Number.parseInt(f,10);if(Number.isNaN(J))return null;return J}function m($){try{return process.kill($,0),!0}catch(f){if(f instanceof Error&&"code"in f&&f.code==="EPERM")return!0;return!1}}function o($){try{xf($)}catch{}}function _0($){let f=$.lastIndexOf("/");if(f>=0)return`${$.substring(0,f)}/worker.pid`;return"worker.pid"}var wf=100,qf=2000;class n0{pidPath;projectPath;daemonScript;subprocess=null;constructor($){this.pidPath=_0($.dbPath),this.projectPath=$.projectPath,this.daemonScript=$.daemonScript}start(){if(this.isRunning())return!1;this.subprocess=Bun.spawn([W1(),"run",this.daemonScript,"--project",this.projectPath],{detached:!0,stdio:["ignore","ignore","ignore"],ipc(f){}}),this.subprocess.unref();let $=Date.now()+qf;while(Date.now()<$)if(Bun.sleepSync(wf),Pf(this.pidPath)){let f=w(this.pidPath);if(f!==null&&m(f))return!0}return!1}signal($){try{this.subprocess?.send($)}catch{}}stop(){let $=w(this.pidPath);if($!==null)try{process.kill($,"SIGTERM")}catch{}this.subprocess=null,o(this.pidPath)}isRunning(){let $=w(this.pidPath);if($===null)return!1;return m($)}getStatus(){let $=w(this.pidPath);if($===null)return{running:!1,pid:null};if(!m($))return{running:!1,pid:null};return{running:!0,pid:$}}}import{existsSync as d0}from"fs";function N1($){let f={reaped:0,errors:[]};try{let J=_0($),Q=w(J);if(Q===null){try{if(d0(J))if(o(J),!d0(J))f.reaped++,console.log("[open-mem] Reaped corrupt daemon PID file");else f.errors.push("Failed to remove corrupt PID file: file still exists after removal")}catch(M){f.errors.push(`Failed to check/remove corrupt PID file: ${M instanceof Error?M.message:String(M)}`)}return f}if(m(Q))return f;if(o(J),!d0(J))f.reaped++,console.log(`[open-mem] Reaped stale daemon PID file (pid=${Q})`);else f.errors.push(`Failed to remove stale PID file (pid=${Q}): file still exists after removal`)}catch(J){f.errors.push(`Reaper error: ${J instanceof Error?J.message:String(J)}`)}return f}import{Database as S1}from"bun:sqlite";import{existsSync as i0,mkdirSync as yf,unlinkSync as K1}from"fs";import*as V1 from"sqlite-vec";class F0{db;dbPath;_hasVectorExtension=!1;static enableExtensionSupport(){let $=["/opt/homebrew/opt/sqlite/lib/libsqlite3.dylib","/usr/local/opt/sqlite/lib/libsqlite3.dylib"];for(let f of $)try{if(i0(f))return S1.setCustomSQLite(f),!0}catch{return!1}return!1}constructor($){this.dbPath=$,this.db=this.open($),this.configure()}open($){let f=$.lastIndexOf("/");if(f>0){let J=$.substring(0,f);yf(J,{recursive:!0})}return new S1($,{create:!0})}configure(){try{this.applyPragmas(),this.loadExtensions()}catch($){console.warn("[open-mem] Database configure failed, attempting recovery by removing WAL/SHM files:",$.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(f){console.warn("[open-mem] WAL/SHM cleanup insufficient, recreating database from scratch:",f.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(J){throw console.warn("[open-mem] All recovery attempts failed, filesystem may be broken:",J.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{V1.load(this.db),this._hasVectorExtension=!0}catch{this._hasVectorExtension=!1}}get hasVectorExtension(){return this._hasVectorExtension}deleteSidecarFiles(){for(let $ of["-wal","-shm"]){let f=this.dbPath+$;try{if(i0(f))K1(f)}catch{}}}deleteDatabaseFiles(){this.deleteSidecarFiles();try{if(i0(this.dbPath))K1(this.dbPath)}catch{}}ensureMigrationTable(){this.db.exec(`
164
+ </rerank_request>`}var x1={"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 v1(f){if(f.includes("."))return f;return x1[f]||`us.anthropic.${f}-v1:0`}function P(f){switch(f.provider){case"anthropic":{let{createAnthropic:n}=v("@ai-sdk/anthropic");return n({apiKey:f.apiKey})(f.model)}case"bedrock":{let{createAmazonBedrock:n}=v("@ai-sdk/amazon-bedrock");return n()(v1(f.model))}case"openai":{let{createOpenAI:n}=v("@ai-sdk/openai");return n({apiKey:f.apiKey})(f.model)}case"google":{let{createGoogleGenerativeAI:n}=v("@ai-sdk/google");return n({apiKey:f.apiKey})(f.model)}default:throw Error(`Unknown provider: ${f.provider}. Supported: anthropic, bedrock, openai, google`)}}function vn(f){try{switch(f.provider){case"google":{let{createGoogleGenerativeAI:n}=v("@ai-sdk/google");return n({apiKey:f.apiKey}).embedding("text-embedding-004")}case"openai":{let{createOpenAI:n}=v("@ai-sdk/openai");return n({apiKey:f.apiKey}).embedding("text-embedding-3-small")}case"bedrock":{let{createAmazonBedrock:n}=v("@ai-sdk/amazon-bedrock");return n().embedding("amazon.titan-embed-text-v2:0")}case"anthropic":return null;default:return null}}catch{return null}}var q1={"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},qn=0;async function k(f,n){if(!n)return;let A=q1[f]||5,E=Math.ceil(60000/A)+100,O=Date.now()-qn;if(O<E){let S=E-O;await new Promise((M)=>setTimeout(M,S))}qn=Date.now()}class Df{model;config;_generate=r1;constructor(f){this.config=f,this.model=null;let n=f.provider!=="bedrock";if(f.compressionEnabled&&(!n||f.apiKey))try{this.model=P({provider:f.provider,model:f.model,apiKey:f.apiKey})}catch{}}static MAX_INPUT_LENGTH=50000;async compress(f,n,A){if(!this.config.compressionEnabled||!this.model)return null;if(n.length<this.config.minOutputLength)return null;let E=Y(n),N=n.length>Df.MAX_INPUT_LENGTH?`${n.substring(0,Df.MAX_INPUT_LENGTH)}
165
+
166
+ [... truncated ...]`:n,O=Pn(f,N,A),S=2;for(let M=0;M<=S;M++)try{if(this.config.provider==="google")await k(this.config.model,this.config.rateLimitingEnabled);let{text:_}=await this._generate({model:this.model,maxOutputTokens:this.config.maxTokensPerCompression,prompt:O}),$=Gn(_);if($)$.discoveryTokens=E;return $}catch(_){if(i1(_)&&M<S){let $=2**M*1000;await rn($);continue}return null}return null}async compressBatch(f){let n=new Map;for(let A=0;A<f.length;A++){let E=f[A],N=await this.compress(E.toolName,E.toolOutput,E.sessionContext);if(n.set(E.callId,N),A<f.length-1)await rn(200)}return n}createFallbackObservation(f,n){let A=b1(n),E=h1[f]??"discovery";return{type:E,title:`${f} execution`,subtitle:n.substring(0,100).replace(/\n/g," "),facts:[],narrative:`Tool ${f} was executed. Output length: ${n.length} chars.`,concepts:[],filesRead:E==="discovery"?A:[],filesModified:E==="change"?A:[],discoveryTokens:Y(n),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 h1={Read:"discovery",Write:"change",Edit:"change",Bash:"change",Glob:"discovery",Grep:"discovery"},p1=/(?:^|\s)((?:\.\/|\/|src\/|tests\/|lib\/)\S+\.\w+)/gm;function b1(f){let n=[];for(let A of f.matchAll(p1))n.push(A[1]);return[...new Set(n)]}function i1(f){if(typeof f!=="object"||f===null)return!1;let n=f,A=n.status;if(A===429||A===500||A===503)return!0;let E=n.error;if(typeof E==="object"&&E!==null&&E.type==="overloaded_error")return!0;return!1}function rn(f){return new Promise((n)=>setTimeout(n,f))}import{generateText as t1}from"ai";class Q0{model;config;_generate=t1;constructor(f){if(this.config=f,this.model=null,f.provider==="bedrock"||f.apiKey)try{this.model=P({provider:f.provider,model:f.model,apiKey:f.apiKey})}catch{}}async evaluate(f,n){if(!this.model||n.length===0)return null;let A=In(f,n),E=2;for(let N=0;N<=E;N++)try{if(this.config.provider==="google")await k(this.config.model,this.config.rateLimitingEnabled);let{text:O}=await this._generate({model:this.model,maxOutputTokens:512,prompt:A});return gn(O)}catch(O){if(a1(O)&&N<E){let S=2**N*1000;await s1(S);continue}return null}return null}}function a1(f){if(typeof f!=="object"||f===null)return!1;let n=f,A=n.status;if(A===429||A===500||A===503)return!0;let E=n.error;if(typeof E==="object"&&E!==null&&E.type==="overloaded_error")return!0;return!1}function s1(f){return new Promise((n)=>setTimeout(n,f))}import{generateText as o1}from"ai";class L0{model;config;_generate=o1;constructor(f){if(this.config=f,this.model=null,f.provider==="bedrock"||f.apiKey)try{this.model=P({provider:f.provider,model:f.model,apiKey:f.apiKey})}catch{}}async extract(f){if(!this.model)return null;let n=wn(f),A=2;for(let E=0;E<=A;E++)try{if(this.config.provider==="google")await k(this.config.model,this.config.rateLimitingEnabled);let{text:N}=await this._generate({model:this.model,maxOutputTokens:1024,prompt:n});return Tn(N)}catch(N){if(d1(N)&&E<A){let O=2**E*1000;await e1(O);continue}return null}return null}}function d1(f){if(typeof f!=="object"||f===null)return!1;let n=f,A=n.status;if(A===429||A===500||A===503)return!0;let E=n.error;if(typeof E==="object"&&E!==null&&E.type==="overloaded_error")return!0;return!1}function e1(f){return new Promise((n)=>setTimeout(n,f))}import{generateText as fE}from"ai";class z0{model;config;_generate=fE;constructor(f){this.config=f,this.model=null;let n=f.provider!=="bedrock";if(f.compressionEnabled&&(!n||f.apiKey))try{this.model=P({provider:f.provider,model:f.model,apiKey:f.apiKey})}catch{}}async summarize(f,n){if(n.length===0)return null;if(!this.config.compressionEnabled||!this.model)return this.createFallbackSummary(n);let A=kn(n.map((E)=>({type:E.type,title:E.title,narrative:E.narrative})),f);try{if(this.config.provider==="google")await k(this.config.model,this.config.rateLimitingEnabled);let{text:E}=await this._generate({model:this.model,maxOutputTokens:this.config.maxTokensPerCompression,prompt:A}),N=jn(E);if(!N)return this.createFallbackSummary(n);return N}catch{return this.createFallbackSummary(n)}}createFallbackSummary(f){let n=new Set,A=new Set,E=[];for(let M of f){for(let _ of M.filesModified)n.add(_);for(let _ of M.concepts)A.add(_);if(M.type==="decision")E.push(M.title)}let N=new Map;for(let M of f)N.set(M.type,(N.get(M.type)??0)+1);let O=Array.from(N.entries()).map(([M,_])=>`${_} ${M}${_>1?"s":""}`).join(", "),S=Array.from(A).slice(0,5).join(", ");return{summary:`Session with ${f.length} observations: ${O}. Files modified: ${n.size}. Key concepts: ${S}.`,keyDecisions:E.slice(0,5),filesModified:Array.from(n),concepts:Array.from(A)}}shouldSummarize(f){return f>=2}}cf();import{randomUUID as nA}from"crypto";var nE={showTokenCosts:!0,observationTypes:"all",fullObservationCount:3,showLastSummary:!0},lf={bugfix:"\uD83D\uDD34",feature:"\uD83D\uDFE3",refactor:"\uD83D\uDD04",change:"\u2705",discovery:"\uD83D\uDD35",decision:"\u2696\uFE0F"};function gf(f,n=nE){let A=[];if(A.push("## open-mem: Past Session Memory"),A.push(""),A.push("**\uD83D\uDCA1 Progressive Disclosure:** This is a compact index showing WHAT was observed and retrieval COST."),A.push("Use `memory.find` to find observations by query, then `memory.get` with IDs to fetch full details."),A.push(""),A.push("**3-Layer Memory Access:**"),A.push("- **Layer 1** `memory.find` \u2014 Find observations by query (returns IDs + summaries)"),A.push("- **Layer 2** `memory.history` \u2014 Browse session history and drill into sessions"),A.push("- **Layer 3** `memory.get` \u2014 Get full details by ID (use IDs from search results or the index below)"),n.showLastSummary&&f.recentSummaries.length>0){A.push(""),A.push("### Recent Sessions"),A.push("| Session | Summary | Decisions |"),A.push("|---------|---------|-----------|");for(let S of f.recentSummaries){let M=S.keyDecisions.length>0?S.keyDecisions.join("; "):"\u2014";A.push(`| ${S.sessionId} | ${S.summary} | ${M} |`)}}let E=n.observationTypes==="all"?f.observationIndex:f.observationIndex.filter((S)=>n.observationTypes.includes(S.type));if(E.length>0){A.push(""),A.push(`### Recent Observations (${E.length} entries)`);let S=EE(E,f.fullObservations);for(let[M,_]of S){if(A.push(""),A.push(`**${M}**`),n.showTokenCosts)A.push("| ID | Type | Title | ~Tokens |"),A.push("|----|------|-------|---------|");else A.push("| ID | Type | Title |"),A.push("|----|------|-------|");for(let $ of _){let R=lf[$.type]||"\uD83D\uDCDD";if(n.showTokenCosts)A.push(`| ${$.id} | ${R} | ${$.title} | ~${$.tokenCount} |`);else A.push(`| ${$.id} | ${R} | ${$.title} |`)}}}let N=f.fullObservations.slice(0,n.fullObservationCount);if(N.length>0){A.push(""),A.push("### Full Details (most recent)");for(let S of N){let M=lf[S.type]||"\uD83D\uDCDD";if(A.push(""),A.push(`#### ${M} ${S.title} (${S.id})`),A.push(S.narrative),S.facts.length>0)A.push(`**Facts:** ${S.facts.map(($)=>`- ${$}`).join(" ")}`);if(S.concepts.length>0)A.push(`**Concepts:** ${S.concepts.join(", ")}`);let _=[...S.filesRead,...S.filesModified];if(_.length>0)A.push(`**Files:** ${_.join(", ")}`)}}let O=AE(f);if(O)A.push(""),A.push(O);return A.join(`
167
+ `)}function AE(f){let n=0,A=0,E=new Set(f.observationIndex.map((S)=>S.id));for(let S of f.observationIndex)n+=S.tokenCount,A+=S.discoveryTokens;for(let S of f.fullObservations)if(!E.has(S.id))n+=S.tokenCount,A+=S.discoveryTokens;if(A===0)return null;let N=A-n,O=Math.max(0,Math.round(N/A*100));return`### \uD83D\uDCB0 Memory Economics
168
+ **Read cost:** ~${n}t | **Discovery cost:** ~${A}t | **Savings:** ${O}% (${N}t saved)`}function EE(f,n){let A=new Map;for(let N of n){let O=N.filesModified[0]||N.filesRead[0];if(O)A.set(N.id,O)}let E=new Map;for(let N of f){let O=A.get(N.id)??"General",S=E.get(O)??[];S.push(N),E.set(O,S)}return E}function Tf(f){let n=[];if(n.push("[open-mem] Memory context:"),f.recentSummaries.length>0){n.push(`
169
+ Recent sessions:`);for(let A of f.recentSummaries)n.push(`- ${A.summary}`)}if(f.observationIndex.length>0){n.push(`
170
+ Recent observations (${f.observationIndex.length} entries):`);for(let A of f.observationIndex)n.push(`- ${lf[A.type]||"\uD83D\uDCDD"} ${A.title}`)}return n.join(`
171
+ `)}function Pf(f,n){if(f.length===0)return"";let A=n,E=[];for(let O of f){let S=O.tokenCount||Y(O.title);if(A-S<0)break;E.push(O),A-=S}if(E.length===0)return"";let N=[];N.push("### Cross-Project Memory"),N.push(""),N.push("| ID | Type | Title | ~Tokens |"),N.push("|----|------|-------|---------|");for(let O of E){let S=lf[O.type]||"\uD83D\uDCDD";N.push(`| ${O.id} | ${S} | ${O.title} | ~${O.tokenCount} |`)}return N.join(`
172
+ `)}function kf(f,n){if(f.length===0)return"";let A=n,E=[];for(let O of f){let S=O.tokenCount||Y(O.title);if(A-S<0)break;E.push(O),A-=S}if(E.length===0)return"";let N=[];N.push(`
173
+ Cross-project observations (${E.length} entries):`);for(let O of E)N.push(`- ${lf[O.type]||"\uD83D\uDCDD"} ${O.title}`);return N.join(`
174
+ `)}var If={recency:0.4,typeImportance:0.3,sessionAffinity:0.2,tokenEfficiency:0.1},NE={decision:1,bugfix:0.9,feature:0.8,refactor:0.6,discovery:0.5,change:0.4};function OE(f,n){let A=new Date(f),N=(n.getTime()-A.getTime())/3600000;if(N<0)return 1;if(N<24)return 1;if(N<48)return 0.8;if(N<168)return 0.5;return 0.2}function ME(f){return NE[f]??0.3}function SE(f,n){if(!n)return 0.5;return f===n?1:0.3}function _E(f){if(f<=10)return 1;if(f>=200)return 0.2;return 1-(f-10)/190*0.8}function $E(f,n){let A=OE(f.createdAt,n.now),E=ME(f.type),N=SE(f.sessionId,n.currentSessionId),O=_E(f.tokenCount);return A*If.recency+E*If.typeImportance+N*If.sessionAffinity+O*If.tokenEfficiency}function hn(f,n){let A=new Map;for(let E of f)A.set(E.id,$E(E,n));return[...f].sort((E,N)=>{let O=A.get(E.id)??0,S=A.get(N.id)??0;if(S!==O)return S-O;return new Date(N.createdAt).getTime()-new Date(E.createdAt).getTime()})}function ff(f,n,A,E,N=[],O){let S=E,M=[],_=[];for(let R of n){let D=R.tokenCount||Y(R.summary);if(S-D<0)break;M.push(R),S-=D}let $=O?hn(A,O):A;for(let R of $){let D=R.tokenCount||Y(R.title);if(S-D<0)break;_.push(R),S-=D}return{recentSummaries:M,observationIndex:_,fullObservations:[...N],totalTokens:E-S}}import{existsSync as XE}from"fs";import{readdir as KE,readFile as ZE,writeFile as UE}from"fs/promises";import{join as mE,resolve as YE}from"path";import{existsSync as bn}from"fs";import{mkdir as RE,readFile as DE,rename as lE,unlink as uE,writeFile as yE}from"fs/promises";import{dirname as K0,isAbsolute as tn,join as xf,normalize as CE,relative as an,resolve as X0,sep as W0}from"path";var wf="<!-- open-mem-context -->",uf="<!-- /open-mem-context -->",VE={bugfix:"\uD83D\uDD34",feature:"\uD83D\uDFE3",refactor:"\uD83D\uDD04",change:"\u2705",discovery:"\uD83D\uDD35",decision:"\u2696\uFE0F"},pn=new Map,BE=new Set(["node_modules",".git","dist","coverage",".open-mem","build","__pycache__",".next",".nuxt"]);async function vf(f,n,A=5){if(n.length===0)return;let E=[];for(let S of n){for(let M of S.filesModified)E.push(M);for(let M of S.filesRead)E.push(M)}let N=zE(E,f,A);if(N.size===0)return;let O=WE(n,N,f);for(let[S,M]of O)try{let _=JE(S,M,f);await QE(S,_)}catch(_){console.error(`[open-mem] Failed to update AGENTS.md in ${S}:`,_)}}function JE(f,n,A){let E=[...n].sort((_,$)=>$.createdAt.localeCompare(_.createdAt)).slice(0,10),N=an(A,f)||".",O=[];O.push(`## Recent Activity in \`${N}/\` (auto-generated by open-mem)`),O.push(""),O.push("| Type | Title | Date |"),O.push("|------|-------|------|");for(let _ of E){let $=VE[_.type]||"\uD83D\uDCDD",R=_.createdAt.split("T")[0],D=_.title.replace(/\|/g,"\\|");O.push(`| ${$} ${_.type} | ${D} | ${R} |`)}let S=new Set;for(let _ of E)for(let $ of _.concepts)S.add($);if(S.size>0){let _=[...S].slice(0,10).join(", ");O.push(""),O.push(`**Key concepts:** ${_}`)}let M=E.filter((_)=>_.type==="decision").map((_)=>_.title);if(M.length>0)O.push(""),O.push(`**Recent decisions:** ${M.slice(0,5).join("; ")}`);return O.join(`
175
+ `)}async function QE(f,n){if(!bn(f))return;let E=(pn.get(f)??Promise.resolve()).then(async()=>{let N=xf(f,"AGENTS.md"),O=xf(f,".AGENTS.md.tmp"),S="";try{S=await DE(N,"utf-8")}catch{}let M=LE(S,n);try{await RE(K0(O),{recursive:!0}),await yE(O,M,"utf-8"),await lE(O,N)}catch(_){try{await uE(O)}catch{}throw _}});return pn.set(f,E.catch(()=>{})),E}function LE(f,n){if(!f)return`${wf}
176
+ ${n}
177
+ ${uf}
178
+ `;let A=f.indexOf(wf),E=f.indexOf(uf);if(A!==-1&&E!==-1&&E>A){let N=f.substring(0,A),O=f.substring(E+uf.length);return`${N}${wf}
179
+ ${n}
180
+ ${uf}${O}`}return`${f}
181
+
182
+ ${wf}
183
+ ${n}
184
+ ${uf}
185
+ `}function zE(f,n,A){let E=new Set,N=X0(n);for(let O of f){if(!O||!O.trim())continue;if(O.startsWith("~")||O.startsWith("http"))continue;let S=tn(O)?O:xf(n,O),M=K0(S),_=X0(M);if(!_.startsWith(N+W0)&&_!==N)continue;if(_===N)continue;let $=an(N,_);if($.split(W0).length>A)continue;if(CE($).split(W0).some((l)=>BE.has(l)))continue;if(!bn(_))continue;E.add(_)}return E}function WE(f,n,A){let E=new Map;for(let N of f){let O=[...N.filesModified,...N.filesRead],S=new Set;for(let M of O){if(!M)continue;let _=tn(M)?M:xf(A,M),$=X0(K0(_));if(n.has($))S.add($)}for(let M of S){let _=E.get(M)??[];_.push(N),E.set(M,_)}}return E}var FE="<!-- open-mem-context -->",sn="<!-- /open-mem-context -->";async function on(f,n){let A;try{A=await KE(f,{withFileTypes:!0,encoding:"utf8"})}catch{return}for(let E of A){let N=String(E.name);if(N===".git"||N==="node_modules"||N===".open-mem"||N==="dist")continue;let O=mE(f,N);if(E.isDirectory())await on(O,n);else if(E.isFile()&&N==="AGENTS.md")n.push(O)}}async function dn(f){let n=YE(f),A=[];return await on(n,A),A}function cE(f){let n=f.indexOf(FE),A=f.indexOf(sn);if(n===-1||A===-1||A<=n)return f;let E=f.slice(0,n).trimEnd(),N=f.slice(A+sn.length).trimStart();if(!E&&!N)return"";if(!E)return`${N}
186
+ `;if(!N)return`${E}
187
+ `;return`${E}
188
+
189
+ ${N}
190
+ `}async function en(f,n=!1){let A=await dn(f),E=0;for(let N of A){let O=await ZE(N,"utf-8"),S=cE(O);if(S!==O){if(E+=1,!n)await UE(N,S,"utf-8")}}return{files:A,changed:E}}async function fA(f,n,A,E,N=!1){let S=n.getAll(f).flatMap((_)=>A.getBySession(_.id));if(N){let _=new Set;for(let $ of S)for(let R of[...$.filesRead,...$.filesModified])_.add(R);return{observations:S.length,filesTouched:_.size}}if(!XE(f))return{observations:0,filesTouched:0};await vf(f,S,E);let M=await dn(f);return{observations:S.length,filesTouched:M.length}}class Z0{observations;sessions;summaries;searchOrchestrator;projectPath;config;userObservationRepo;runtimeSnapshotProvider;configAuditStore;maintenanceHistoryStore;configAuditLogFallback=[];maintenanceLogFallback=[];constructor(f){this.observations=f.observations,this.sessions=f.sessions,this.summaries=f.summaries,this.searchOrchestrator=f.searchOrchestrator,this.projectPath=f.projectPath,this.config=f.config,this.userObservationRepo=f.userObservationRepo??null,this.runtimeSnapshotProvider=f.runtimeSnapshotProvider??null,this.configAuditStore=f.configAuditStore??null,this.maintenanceHistoryStore=f.maintenanceHistoryStore??null}getByIdIncludingArchived(f){let n=this.observations;return n.getByIdIncludingArchived?n.getByIdIncludingArchived(f):this.observations.getById(f)}listByProjectWithState(f){let n=this.observations;if(n.listByProject)return n.listByProject(this.projectPath,f);if(f.state!=="current")return[];return this.listObservations({limit:f.limit,offset:f.offset,type:f.type,sessionId:f.sessionId})}async ingest(f){}async processPending(f){return 0}async search(f,n={}){return this.searchOrchestrator.search(f,{type:n.type,limit:n.limit??10,projectPath:this.projectPath,importanceMin:n.importanceMin,importanceMax:n.importanceMax,createdAfter:n.after,createdBefore:n.before,concepts:n.concepts,files:n.files})}async timeline(f={}){if(f.sessionId){let A=this.sessions.getById(f.sessionId);if(!A)return[];return[{session:A,summary:this.summaries.getBySessionId(A.id),observations:this.observations.getBySession(A.id)}]}return this.sessions.getRecent(this.projectPath,f.limit??5).map((A)=>({session:A,summary:this.summaries.getBySessionId(A.id),observations:[]}))}async recall(f,n=10){let A=[];for(let E of f.slice(0,n)){let N=this.observations.getById(E);if(N){A.push(N);continue}if(!this.userObservationRepo)continue;let O=this.userObservationRepo.getById(E);if(!O)continue;A.push({...O,sessionId:"",rawToolOutput:"",discoveryTokens:0})}return A}async save(f){if(f.scope==="user"){if(!this.userObservationRepo)return null;return{...this.userObservationRepo.create({type:f.type,title:f.title,subtitle:"",facts:[],narrative:f.narrative,concepts:f.concepts??[],filesRead:[],filesModified:f.files??[],toolName:"memory.create",tokenCount:Y(`${f.title} ${f.narrative}`),importance:f.importance??3,sourceProject:this.projectPath}),sessionId:"",rawToolOutput:"",discoveryTokens:0}}this.sessions.getOrCreate(f.sessionId,this.projectPath);let n=this.observations.create({sessionId:f.sessionId,type:f.type,title:f.title,subtitle:"",facts:[],narrative:f.narrative,concepts:f.concepts??[],filesRead:[],filesModified:f.files??[],rawToolOutput:`[Manual save] ${f.narrative}`,toolName:"memory.create",tokenCount:Y(`${f.title} ${f.narrative}`),discoveryTokens:0,importance:f.importance??3});return this.sessions.incrementObservationCount(f.sessionId),n}async update(f){let n=this.observations.getById(f.id);if(!n)return null;let A=this.sessions.getById(n.sessionId);if(!A||A.projectPath!==this.projectPath)return null;let{id:E,...N}=f;return this.observations.update(f.id,N)??null}async delete(f){let n=0;for(let A of f){let E=this.observations.getById(A);if(!E)continue;let N=this.sessions.getById(E.sessionId);if(!N||N.projectPath!==this.projectPath)continue;if(this.observations.delete(A))n+=1}return n}async export(f,n={}){if(f!=="project")throw Error("Only project scope export is supported.");let A=this.sessions.getAll(this.projectPath),E=[];for(let M of A)E.push(...this.observations.getBySession(M.id));if(n.type)E=E.filter((M)=>M.type===n.type);if(E.sort((M,_)=>new Date(M.createdAt).getTime()-new Date(_.createdAt).getTime()),n.limit&&n.limit<E.length)E=E.slice(0,n.limit);let N=E.map(({rawToolOutput:M,..._})=>_),O=A.map((M)=>this.summaries.getBySessionId(M.id)).filter((M)=>M!==null);return{version:1,exportedAt:new Date().toISOString(),project:this.projectPath,observations:N,summaries:O}}async import(f,n={}){let A;try{A=JSON.parse(f)}catch{throw Error("Invalid JSON payload.")}if(typeof A!=="object"||A===null)throw Error("Invalid import payload.");let E=A;if(E.version!==1||!Array.isArray(E.observations))throw Error("Unsupported export format.");let N=n.mode??"skip-duplicates",O=0,S=0;for(let M of E.observations){let _=this.observations.getById(M.id);if(_&&N==="skip-duplicates"){S+=1;continue}if(_&&N==="overwrite")this.observations.delete(M.id);this.sessions.getOrCreate(M.sessionId,this.projectPath),this.observations.importObservation({id:M.id,sessionId:M.sessionId,type:M.type,title:M.title,subtitle:M.subtitle??"",facts:M.facts??[],narrative:M.narrative??"",concepts:M.concepts??[],filesRead:M.filesRead??[],filesModified:M.filesModified??[],rawToolOutput:M.rawToolOutput??"",toolName:M.toolName??"unknown",createdAt:M.createdAt,tokenCount:M.tokenCount??0,discoveryTokens:M.discoveryTokens??0,importance:M.importance??3,supersededBy:M.supersededBy??null,supersededAt:M.supersededAt??null}),this.sessions.incrementObservationCount(M.sessionId),O+=1}for(let M of E.summaries??[]){let _=this.summaries.getBySessionId(M.sessionId);if(_&&N==="skip-duplicates")continue;if(_&&N==="overwrite")continue;this.sessions.getOrCreate(M.sessionId,this.projectPath),this.summaries.importSummary(M),this.sessions.setSummary(M.sessionId,M.id)}return{imported:O,skipped:S}}async buildContext(f,n="normal"){let A=this.sessions.getRecent(this.projectPath,5),E=A.map((R)=>R.summaryId?this.summaries.getBySessionId(R.id):null).filter((R)=>R!==null),N=this.observations.getIndex(this.projectPath,this.config.maxObservations),S=N.slice(0,this.config.contextFullObservationCount).map((R)=>R.id).map((R)=>this.observations.getById(R)).filter((R)=>R!==null),M=ff(A,E,N,this.config.maxContextTokens,S);if(n==="compaction"){let R=Tf(M);if(this.config.userMemoryEnabled&&this.userObservationRepo)R+=kf(this.userObservationRepo.getIndex(this.config.maxObservations),this.config.userMemoryMaxContextTokens);return R}let _={showTokenCosts:this.config.contextShowTokenCosts,observationTypes:this.config.contextObservationTypes,fullObservationCount:this.config.contextFullObservationCount,showLastSummary:this.config.contextShowLastSummary},$=gf(M,_);if(this.config.userMemoryEnabled&&this.userObservationRepo){let R=Pf(this.userObservationRepo.getIndex(this.config.maxObservations),this.config.userMemoryMaxContextTokens);if(R)$+=`
191
+
192
+ ${R}`}return $}guide(){return["open-mem workflow:","1) Use memory.find to find candidate observations by query.","2) Use memory.history to inspect session-level history and summaries.","3) Use memory.get with IDs from find/history to fetch full details.","Write/edit flow: memory.create (new), memory.revise (refine), memory.remove (tombstone).","Transfer flow: memory.transfer.export for backup/portability, memory.transfer.import to restore."].join(`
193
+ `)}listObservations(f){let{limit:n=50,offset:A=0,type:E,sessionId:N,state:O}=f;if(O)return this.listByProjectWithState({limit:n,offset:A,type:E,state:O,sessionId:N});if(N){let _=this.observations.getBySession(N);if(E)_=_.filter(($)=>$.type===E);return _.slice(A,A+n)}let M=this.observations.getIndex(this.projectPath,A+n).slice(A);if(E)M=M.filter((_)=>_.type===E);return M.map((_)=>this.observations.getById(_.id)).filter((_)=>_!==null)}getObservation(f){return this.observations.getById(f)}getLineage(f){let A=this.getByIdIncludingArchived(f);if(!A)return null;let E=A,N=0,O=new Set([A.id]);while(E.revisionOf&&N<256){let R=this.getByIdIncludingArchived(E.revisionOf);if(!R||O.has(R.id))break;E=R,O.add(R.id),N+=1}let S=[],M=E,_=new Set,$=0;while(M&&!_.has(M.id)&&$<256){_.add(M.id);let R=M.deletedAt?"tombstoned":M.supersededBy?"superseded":"current";S.push({id:M.id,revisionOf:M.revisionOf??null,supersededBy:M.supersededBy??null,supersededAt:M.supersededAt??null,deletedAt:M.deletedAt??null,state:R,observation:M}),M=M.supersededBy?this.getByIdIncludingArchived(M.supersededBy):null,$+=1}return S}listSessions(f){return this.sessions.getRecent(f.projectPath??this.projectPath,f.limit??20)}getSession(f){let n=this.sessions.getById(f);if(!n)return null;return{session:n,summary:this.summaries.getBySessionId(f),observations:this.observations.getBySession(f)}}stats(){let f=this.observations.getCount(),A=this.sessions.getAll(this.projectPath).length,E=this.observations.getIndex(this.projectPath,1e4),N=0,O=0,S={};for(let $ of E)N+=$.tokenCount,O+=$.discoveryTokens,S[$.type]=(S[$.type]||0)+1;let M=O-N,_=E.length>0?Math.round(N/E.length):0;return{totalObservations:f,totalSessions:A,totalTokensSaved:M,averageObservationSize:_,typeBreakdown:S}}async maintainFolderContext(f,n){if(f==="rebuild"){let E=await fA(this.projectPath,this.sessions,this.observations,this.config.folderContextMaxDepth,n);return{action:f,dryRun:n,...E}}let A=await en(this.projectPath,n);return{action:"clean",dryRun:n,...A}}getRevisionDiff(f,n){let A=this.getByIdIncludingArchived(f),E=this.getByIdIncludingArchived(n);if(!A||!E)return null;let N=[],O=(M,_,$)=>{if(JSON.stringify(_)!==JSON.stringify($))N.push({field:M,before:_,after:$})};O("title",E.title,A.title),O("subtitle",E.subtitle,A.subtitle),O("narrative",E.narrative,A.narrative),O("type",E.type,A.type),O("facts",E.facts,A.facts),O("concepts",E.concepts,A.concepts),O("filesRead",E.filesRead,A.filesRead),O("filesModified",E.filesModified,A.filesModified),O("importance",E.importance,A.importance);let S=N.length===0?"No material changes between revisions.":`Changed ${N.length} field${N.length===1?"":"s"}: ${N.map((M)=>M.field).join(", ")}.`;return{fromId:n,toId:f,summary:S,changedFields:N}}getHealth(){let f=this.runtimeSnapshotProvider?.(),n=f&&f.queue.lastError?"degraded":"ok";return{status:f?.status??"ok",timestamp:f?.timestamp??new Date().toISOString(),components:{database:{status:"ok"},search:{status:"ok"},config:{status:"ok"},queue:{status:n,detail:f?.queue.lastError??void 0}}}}getMetrics(){let f=this.stats();return{timestamp:this.runtimeSnapshotProvider?.()?.timestamp??new Date().toISOString(),memory:{totalObservations:f.totalObservations,totalSessions:f.totalSessions,totalTokensSaved:f.totalTokensSaved,averageObservationSize:f.averageObservationSize}}}getPlatforms(){return{name:"open-mem",provider:this.config.provider,dashboardEnabled:this.config.dashboardEnabled,vectorEnabled:Boolean(this.config.embeddingDimension&&this.config.embeddingDimension>0)}}getAdapterStatuses(){let f={opencode:this.config.platformOpenCodeEnabled??!0,"claude-code":this.config.platformClaudeCodeEnabled??!1,cursor:this.config.platformCursorEnabled??!1};return[{name:"opencode",version:"1.0",capabilities:{nativeSessionLifecycle:!0,nativeToolCapture:!0,nativeChatCapture:!0,emulatedIdleFlush:!1}},{name:"claude-code",version:"0.1",capabilities:{nativeSessionLifecycle:!0,nativeToolCapture:!0,nativeChatCapture:!0,emulatedIdleFlush:!0}},{name:"cursor",version:"0.1",capabilities:{nativeSessionLifecycle:!1,nativeToolCapture:!0,nativeChatCapture:!0,emulatedIdleFlush:!0}}].map((A)=>({name:A.name,version:A.version,enabled:f[A.name]??!1,capabilities:A.capabilities}))}getConfigAuditTimeline(){if(this.configAuditStore)return this.configAuditStore.list();return[...this.configAuditLogFallback].reverse()}trackConfigAudit(f){if(this.configAuditStore){this.configAuditStore.append(f);return}this.configAuditLogFallback.push(f)}async rollbackConfig(f){let n=this.configAuditStore?this.configAuditStore.getById(f):this.configAuditLogFallback.find((O)=>O.id===f)??null;if(!n)return null;if(!n.previousValues||typeof n.previousValues!=="object")return null;let{patchConfig:A}=await Promise.resolve().then(() => (u0(),Kn)),E=n.previousValues;try{await A(this.projectPath,E)}catch(O){let S={id:`rollback-failed-${nA()}`,timestamp:new Date().toISOString(),patch:n.previousValues,previousValues:n.patch,source:"rollback-failed"};throw this.trackConfigAudit(S),O}let N={id:`rollback-${nA()}`,timestamp:new Date().toISOString(),patch:n.previousValues,previousValues:n.patch,source:"rollback"};return this.trackConfigAudit(N),N}getMaintenanceHistory(){if(this.maintenanceHistoryStore)return this.maintenanceHistoryStore.list();return[...this.maintenanceLogFallback].reverse()}trackMaintenanceResult(f){if(this.maintenanceHistoryStore){this.maintenanceHistoryStore.append(f);return}this.maintenanceLogFallback.push(f)}}import{existsSync as IE}from"fs";import{existsSync as GE}from"fs";import{homedir as jE}from"os";import{join as AA}from"path";function HE(){let f=[],n=process.env.BUN_INSTALL;if(n)f.push(AA(n,"bin","bun"));let A=jE();return f.push(AA(A,".bun","bin","bun")),f.push("/usr/local/bin/bun"),f.push("/opt/homebrew/bin/bun"),f.push("/home/linuxbrew/.linuxbrew/bin/bun"),f}function gE(){let f=Bun.which("bun");if(f)return f;for(let n of HE())if(GE(n))return console.debug(`[open-mem] Resolved bun path via candidate scan: ${n}`),n;return"bun"}var U0=null;function EA(){if(U0===null)U0=gE();return U0}import{existsSync as TE,mkdirSync as TS,readFileSync as PE,unlinkSync as kE,writeFileSync as PS}from"fs";function i(f){if(!TE(f))return null;let n=PE(f,"utf-8").trim(),A=Number.parseInt(n,10);if(Number.isNaN(A))return null;return A}function nf(f){try{return process.kill(f,0),!0}catch(n){if(n instanceof Error&&"code"in n&&n.code==="EPERM")return!0;return!1}}function yf(f){try{kE(f)}catch{}}function qf(f){let n=f.lastIndexOf("/");if(n>=0)return`${f.substring(0,n)}/worker.pid`;return"worker.pid"}var wE=100,xE=2000;class m0{pidPath;projectPath;daemonScript;subprocess=null;constructor(f){this.pidPath=qf(f.dbPath),this.projectPath=f.projectPath,this.daemonScript=f.daemonScript}start(){if(this.isRunning())return!1;this.subprocess=Bun.spawn([EA(),"run",this.daemonScript,"--project",this.projectPath],{detached:!0,stdio:["ignore","ignore","ignore"],ipc(n){}}),this.subprocess.unref();let f=Date.now()+xE;while(Date.now()<f)if(Bun.sleepSync(wE),IE(this.pidPath)){let n=i(this.pidPath);if(n!==null&&nf(n))return!0}return!1}signal(f){try{this.subprocess?.send(f)}catch{}}stop(){let f=i(this.pidPath);if(f!==null)try{process.kill(f,"SIGTERM")}catch{}this.subprocess=null,yf(this.pidPath)}isRunning(){let f=i(this.pidPath);if(f===null)return!1;return nf(f)}getStatus(){let f=i(this.pidPath);if(f===null)return{running:!1,pid:null};if(!nf(f))return{running:!1,pid:null};return{running:!0,pid:f}}}import{existsSync as Y0}from"fs";function NA(f){let n={reaped:0,errors:[]};try{let A=qf(f),E=i(A);if(E===null){try{if(Y0(A))if(yf(A),!Y0(A))n.reaped++,console.log("[open-mem] Reaped corrupt daemon PID file");else n.errors.push("Failed to remove corrupt PID file: file still exists after removal")}catch(N){n.errors.push(`Failed to check/remove corrupt PID file: ${N instanceof Error?N.message:String(N)}`)}return n}if(nf(E))return n;if(yf(A),!Y0(A))n.reaped++,console.log(`[open-mem] Reaped stale daemon PID file (pid=${E})`);else n.errors.push(`Failed to remove stale PID file (pid=${E}): file still exists after removal`)}catch(A){n.errors.push(`Reaper error: ${A instanceof Error?A.message:String(A)}`)}return n}import{Database as OA}from"bun:sqlite";import{existsSync as F0,mkdirSync as vE,unlinkSync as MA}from"fs";import*as SA from"sqlite-vec";class rf{db;dbPath;_hasVectorExtension=!1;static enableExtensionSupport(){let f=["/opt/homebrew/opt/sqlite/lib/libsqlite3.dylib","/usr/local/opt/sqlite/lib/libsqlite3.dylib"];for(let n of f)try{if(F0(n))return OA.setCustomSQLite(n),!0}catch{return!1}return!1}constructor(f){this.dbPath=f,this.db=this.open(f),this.configure()}open(f){let n=f.lastIndexOf("/");if(n>0){let A=f.substring(0,n);vE(A,{recursive:!0})}return new OA(f,{create:!0})}configure(){try{this.applyPragmas(),this.loadExtensions()}catch(f){console.warn("[open-mem] Database configure failed, attempting recovery by removing WAL/SHM files:",f.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(n){console.warn("[open-mem] WAL/SHM cleanup insufficient, recreating database from scratch:",n.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(A){throw console.warn("[open-mem] All recovery attempts failed, filesystem may be broken:",A.message),f}}}}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{SA.load(this.db),this._hasVectorExtension=!0}catch{this._hasVectorExtension=!1}}get hasVectorExtension(){return this._hasVectorExtension}deleteSidecarFiles(){for(let f of["-wal","-shm"]){let n=this.dbPath+f;try{if(F0(n))MA(n)}catch{}}}deleteDatabaseFiles(){this.deleteSidecarFiles();try{if(F0(this.dbPath))MA(this.dbPath)}catch{}}ensureMigrationTable(){this.db.exec(`
215
194
  CREATE TABLE IF NOT EXISTS _migrations (
216
195
  version INTEGER PRIMARY KEY,
217
196
  name TEXT NOT NULL,
218
197
  applied_at TEXT NOT NULL DEFAULT (datetime('now'))
219
198
  )
220
- `)}migrate($){this.ensureMigrationTable();let f=this.db.query("SELECT version FROM _migrations ORDER BY version").all(),J=new Set(f.map((M)=>M.version)),Q=$.filter((M)=>!J.has(M.version)).sort((M,X)=>M.version-X.version);for(let M of Q)this.db.transaction(()=>{this.db.exec(M.up),this.db.query("INSERT INTO _migrations (version, name) VALUES ($version, $name)").run({$version:M.version,$name:M.name})})()}run($,f){let J=this.db.query($);if(f)J.run(...f);else J.run()}get($,f){let J=this.db.query($);return f?J.get(...f):J.get()}all($,f){let J=this.db.query($);return f?J.all(...f):J.all()}exec($){this.db.exec($)}transaction($){return this.db.transaction($)()}close(){this.db.close()}get isOpen(){try{return this.db.query("SELECT 1").get(),!0}catch{return!1}}get raw(){return this.db}}function E0($){return new F0($)}import{randomUUID as Y1}from"crypto";class r0{db;constructor($){this.db=$}upsertEntity($,f){let J=Y1(),Q=new Date().toISOString();this.db.run(`INSERT INTO entities (id, name, entity_type, first_seen_at, last_seen_at, mention_count)
199
+ `)}migrate(f){this.ensureMigrationTable();let n=this.db.query("SELECT version FROM _migrations ORDER BY version").all(),A=new Set(n.map((N)=>N.version)),E=f.filter((N)=>!A.has(N.version)).sort((N,O)=>N.version-O.version);for(let N of E)this.db.transaction(()=>{this.db.exec(N.up),this.db.query("INSERT INTO _migrations (version, name) VALUES ($version, $name)").run({$version:N.version,$name:N.name})})()}run(f,n){let A=this.db.query(f);if(n)A.run(...n);else A.run()}get(f,n){let A=this.db.query(f);return n?A.get(...n):A.get()}all(f,n){let A=this.db.query(f);return n?A.all(...n):A.all()}exec(f){this.db.exec(f)}transaction(f){return this.db.transaction(f)()}close(){this.db.close()}get isOpen(){try{return this.db.query("SELECT 1").get(),!0}catch{return!1}}get raw(){return this.db}}function hf(f){return new rf(f)}function pf(f){try{let n=JSON.parse(f);return n&&typeof n==="object"?n:{}}catch{return{}}}class c0{db;constructor(f){this.db=f}list(){return this.db.all("SELECT id, timestamp, patch, previous_values, source FROM config_audit_events ORDER BY timestamp DESC").map((f)=>({id:f.id,timestamp:f.timestamp,patch:pf(f.patch),previousValues:pf(f.previous_values),source:f.source}))}getById(f){let n=this.db.get("SELECT id, timestamp, patch, previous_values, source FROM config_audit_events WHERE id = ?",[f]);if(!n)return null;return{id:n.id,timestamp:n.timestamp,patch:pf(n.patch),previousValues:pf(n.previous_values),source:n.source}}append(f){this.db.run("INSERT INTO config_audit_events (id, timestamp, patch, previous_values, source) VALUES (?, ?, ?, ?, ?)",[f.id,f.timestamp,JSON.stringify(f.patch??{}),JSON.stringify(f.previousValues??{}),f.source])}}import{randomUUID as _A}from"crypto";class G0{db;constructor(f){this.db=f}upsertEntity(f,n){let A=_A(),E=new Date().toISOString();this.db.run(`INSERT INTO entities (id, name, entity_type, first_seen_at, last_seen_at, mention_count)
221
200
  VALUES (?, ?, ?, ?, ?, 1)
222
201
  ON CONFLICT(name, entity_type) DO UPDATE SET
223
202
  mention_count = mention_count + 1,
224
- last_seen_at = ?`,[J,$,f,Q,Q,Q]);let M=this.db.get("SELECT * FROM entities WHERE name = ? AND entity_type = ?",[$,f]);if(!M)throw Error(`Failed to upsert entity: ${$} (${f})`);return this.mapEntityRow(M)}createRelation($,f,J,Q){let M=Y1(),X=new Date().toISOString();try{this.db.run(`INSERT OR IGNORE INTO entity_relations
203
+ last_seen_at = ?`,[A,f,n,E,E,E]);let N=this.db.get("SELECT * FROM entities WHERE name = ? AND entity_type = ?",[f,n]);if(!N)throw Error(`Failed to upsert entity: ${f} (${n})`);return this.mapEntityRow(N)}createRelation(f,n,A,E){let N=_A(),O=new Date().toISOString();try{this.db.run(`INSERT OR IGNORE INTO entity_relations
225
204
  (id, source_entity_id, target_entity_id, relationship, observation_id, created_at)
226
- VALUES (?, ?, ?, ?, ?, ?)`,[M,$,f,J,Q,X])}catch{return null}let W=this.db.get(`SELECT * FROM entity_relations
227
- WHERE source_entity_id = ? AND target_entity_id = ? AND relationship = ?`,[$,f,J]);return W?this.mapRelationRow(W):null}linkObservation($,f){this.db.run("INSERT OR IGNORE INTO entity_observations (entity_id, observation_id) VALUES (?, ?)",[$,f])}findByName($){try{return this.db.all(`SELECT e.*
205
+ VALUES (?, ?, ?, ?, ?, ?)`,[N,f,n,A,E,O])}catch{return null}let S=this.db.get(`SELECT * FROM entity_relations
206
+ WHERE source_entity_id = ? AND target_entity_id = ? AND relationship = ?`,[f,n,A]);return S?this.mapRelationRow(S):null}linkObservation(f,n){this.db.run("INSERT OR IGNORE INTO entity_observations (entity_id, observation_id) VALUES (?, ?)",[f,n])}findByName(f){try{return this.db.all(`SELECT e.*
228
207
  FROM entities e
229
208
  JOIN entities_fts fts ON e._rowid = fts.rowid
230
209
  WHERE entities_fts MATCH ?
231
- ORDER BY rank`,[$]).map((J)=>this.mapEntityRow(J))}catch{return[]}}getRelationsFor($){return this.db.all(`SELECT * FROM entity_relations
232
- WHERE source_entity_id = ? OR target_entity_id = ?`,[$,$]).map((J)=>this.mapRelationRow(J))}traverseRelations($,f=1){let J=Math.min(f,2),Q=100,M=new Set,X=[{id:$,currentDepth:0}];M.add($);while(X.length>0){if(M.size>=100)break;let W=X.shift();if(W.currentDepth>=J)continue;let Z=this.getRelationsFor(W.id);for(let N of Z){let S=N.sourceEntityId===W.id?N.targetEntityId:N.sourceEntityId;if(!M.has(S))M.add(S),X.push({id:S,currentDepth:W.currentDepth+1})}}return M}getObservationsForEntity($){return this.db.all("SELECT observation_id FROM entity_observations WHERE entity_id = ?",[$]).map((J)=>J.observation_id)}getById($){let f=this.db.get("SELECT * FROM entities WHERE id = ?",[$]);return f?this.mapEntityRow(f):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 gf}from"crypto";import{embed as vf}from"ai";async function q($,f){try{let{embedding:J}=await vf({model:$,value:f});return J}catch{return null}}function l($,f){if($.length!==f.length||$.length===0)return 0;let J=0,Q=0,M=0;for(let W=0;W<$.length;W++)J+=$[W]*f[W],Q+=$[W]*$[W],M+=f[W]*f[W];let X=Math.sqrt(Q)*Math.sqrt(M);if(X===0)return 0;return J/X}function s0($){let f=[$.title,$.narrative];if($.concepts.length>0)f.push($.concepts.join(", "));return f.join(`
233
- `)}function hf($){return $.replace(/[%_\\]/g,"\\$&")}class a0{db;constructor($){this.db=$}create($){let f=gf(),J=new Date().toISOString(),Q=$.discoveryTokens??0,M=$.importance??3,X=$.scope??"project";return this.db.run(`INSERT INTO observations
210
+ ORDER BY rank`,[f]).map((A)=>this.mapEntityRow(A))}catch{return[]}}getRelationsFor(f){return this.db.all(`SELECT * FROM entity_relations
211
+ WHERE source_entity_id = ? OR target_entity_id = ?`,[f,f]).map((A)=>this.mapRelationRow(A))}traverseRelations(f,n=1){let A=Math.min(n,2),E=100,N=new Set,O=[{id:f,currentDepth:0}];N.add(f);while(O.length>0){if(N.size>=100)break;let S=O.shift();if(!S)continue;if(S.currentDepth>=A)continue;let M=this.getRelationsFor(S.id);for(let _ of M){let $=_.sourceEntityId===S.id?_.targetEntityId:_.sourceEntityId;if(!N.has($))N.add($),O.push({id:$,currentDepth:S.currentDepth+1})}}return N}getObservationsForEntity(f){return this.db.all("SELECT observation_id FROM entity_observations WHERE entity_id = ?",[f]).map((A)=>A.observation_id)}getById(f){let n=this.db.get("SELECT * FROM entities WHERE id = ?",[f]);return n?this.mapEntityRow(n):null}mapEntityRow(f){return{id:f.id,name:f.name,entityType:f.entity_type,firstSeenAt:f.first_seen_at,lastSeenAt:f.last_seen_at,mentionCount:f.mention_count}}mapRelationRow(f){return{id:f.id,sourceEntityId:f.source_entity_id,targetEntityId:f.target_entity_id,relationship:f.relationship,observationId:f.observation_id,createdAt:f.created_at}}}function qE(f){try{let n=JSON.parse(f);return n&&typeof n==="object"?n:{}}catch{return{}}}class j0{db;constructor(f){this.db=f}list(){return this.db.all("SELECT id, timestamp, action, dry_run, result FROM maintenance_history ORDER BY timestamp DESC").map((f)=>({id:f.id,timestamp:f.timestamp,action:f.action,dryRun:f.dry_run===1,result:qE(f.result)}))}append(f){this.db.run("INSERT INTO maintenance_history (id, timestamp, action, dry_run, result) VALUES (?, ?, ?, ?, ?)",[f.id,f.timestamp,f.action,f.dryRun?1:0,JSON.stringify(f.result??{})])}}import{randomUUID as hE}from"crypto";import{embed as rE}from"ai";async function t(f,n){try{let{embedding:A}=await rE({model:f,value:n});return A}catch{return null}}function Af(f,n){if(f.length!==n.length||f.length===0)return 0;let A=0,E=0,N=0;for(let S=0;S<f.length;S++)A+=f[S]*n[S],E+=f[S]*f[S],N+=n[S]*n[S];let O=Math.sqrt(E)*Math.sqrt(N);if(O===0)return 0;return A/O}function H0(f){let n=[f.title,f.narrative];if(f.concepts.length>0)n.push(f.concepts.join(", "));return n.join(`
212
+ `)}function pE(f){return f.replace(/[%_\\]/g,"\\$&")}class g0{db;constructor(f){this.db=f}create(f){let n=hE(),A=new Date().toISOString(),E=f.discoveryTokens??0,N=f.importance??3,O=f.scope??"project";return this.db.run(`INSERT INTO observations
234
213
  (id, session_id, scope, type, title, subtitle, facts, narrative,
235
214
  concepts, files_read, files_modified, raw_tool_output,
236
215
  tool_name, created_at, token_count, discovery_tokens, importance, revision_of, deleted_at)
237
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[f,$.sessionId,X,$.type,$.title,$.subtitle,JSON.stringify($.facts),$.narrative,JSON.stringify($.concepts),JSON.stringify($.filesRead),JSON.stringify($.filesModified),$.rawToolOutput,$.toolName,J,$.tokenCount,Q,M,null,null]),{...$,id:f,scope:X,createdAt:J,discoveryTokens:Q,importance:M,revisionOf:null,deletedAt:null,supersededBy:null,supersededAt:null}}importObservation($){this.db.run(`INSERT INTO observations
216
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[n,f.sessionId,O,f.type,f.title,f.subtitle,JSON.stringify(f.facts),f.narrative,JSON.stringify(f.concepts),JSON.stringify(f.filesRead),JSON.stringify(f.filesModified),f.rawToolOutput,f.toolName,A,f.tokenCount,E,N,null,null]),{...f,id:n,scope:O,createdAt:A,discoveryTokens:E,importance:N,revisionOf:null,deletedAt:null,supersededBy:null,supersededAt:null}}importObservation(f){this.db.run(`INSERT INTO observations
238
217
  (id, session_id, scope, type, title, subtitle, facts, narrative,
239
218
  concepts, files_read, files_modified, raw_tool_output,
240
219
  tool_name, created_at, token_count, discovery_tokens, importance, revision_of, deleted_at)
241
- 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 f=this.db.get("SELECT * FROM observations WHERE id = ? AND superseded_by IS NULL AND deleted_at IS NULL",[$]);return f?this.mapRow(f):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((f)=>this.mapRow(f))}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($,f=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
220
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[f.id,f.sessionId,f.scope??"project",f.type,f.title,f.subtitle,JSON.stringify(f.facts),f.narrative,JSON.stringify(f.concepts),JSON.stringify(f.filesRead),JSON.stringify(f.filesModified),f.rawToolOutput,f.toolName,f.createdAt,f.tokenCount,f.discoveryTokens??0,f.importance??3,f.revisionOf??null,f.deletedAt??null])}getById(f){let n=this.db.get("SELECT * FROM observations WHERE id = ? AND superseded_by IS NULL AND deleted_at IS NULL",[f]);return n?this.mapRow(n):null}getByIdIncludingArchived(f){let n=this.db.get("SELECT * FROM observations WHERE id = ?",[f]);return n?this.mapRow(n):null}getBySession(f){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",[f]).map((n)=>this.mapRow(n))}getCount(f){if(f)return this.db.get("SELECT COUNT(*) as count FROM observations WHERE session_id = ?",[f])?.count??0;return this.db.get("SELECT COUNT(*) as count FROM observations")?.count??0}getIndex(f,n=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
242
221
  FROM observations o
243
222
  JOIN sessions s ON o.session_id = s.id
244
223
  WHERE s.project_path = ? AND o.superseded_by IS NULL AND o.deleted_at IS NULL
245
224
  ORDER BY o.created_at DESC
246
- LIMIT ?`,[$,f]).map((J)=>({id:J.id,sessionId:J.session_id,type:J.type,title:J.title,tokenCount:J.token_count,discoveryTokens:J.discovery_tokens??0,createdAt:J.created_at,importance:J.importance??3}))}search($){let f=!!$.projectPath,J=`
225
+ LIMIT ?`,[f,n]).map((A)=>({id:A.id,sessionId:A.session_id,type:A.type,title:A.title,tokenCount:A.token_count,discoveryTokens:A.discovery_tokens??0,createdAt:A.created_at,importance:A.importance??3}))}listByProject(f,n={}){let{limit:A=50,offset:E=0,type:N,state:O,sessionId:S}=n,M=`SELECT o.*
226
+ FROM observations o
227
+ JOIN sessions s ON o.session_id = s.id
228
+ WHERE s.project_path = ?`,_=[f];if(S)M+=" AND o.session_id = ?",_.push(S);if(N)M+=" AND o.type = ?",_.push(N);if(O==="current")M+=" AND o.superseded_by IS NULL AND o.deleted_at IS NULL";else if(O==="superseded")M+=" AND o.superseded_by IS NOT NULL AND o.deleted_at IS NULL";else if(O==="tombstoned")M+=" AND o.deleted_at IS NOT NULL";else M+=" AND o.superseded_by IS NULL AND o.deleted_at IS NULL";return M+=" ORDER BY o.created_at DESC LIMIT ? OFFSET ?",_.push(A,E),this.db.all(M,_).map(($)=>this.mapRow($))}search(f){let n=!!f.projectPath,A=`
247
229
  SELECT o.*, rank
248
230
  FROM observations o
249
231
  JOIN observations_fts fts ON o._rowid = fts.rowid
250
- ${f?"JOIN sessions s ON o.session_id = s.id":""}
232
+ ${n?"JOIN sessions s ON o.session_id = s.id":""}
251
233
  WHERE observations_fts MATCH ? AND o.superseded_by IS NULL AND o.deleted_at IS NULL
252
- `,Q=[$.query];if(f&&$.projectPath)J+=" AND s.project_path = ?",Q.push($.projectPath);if($.sessionId)J+=" AND o.session_id = ?",Q.push($.sessionId);if($.type)J+=" AND o.type = ?",Q.push($.type);if($.importanceMin!==void 0)J+=" AND o.importance >= ?",Q.push($.importanceMin);if($.importanceMax!==void 0)J+=" AND o.importance <= ?",Q.push($.importanceMax);if($.createdAfter)J+=" AND o.created_at >= ?",Q.push($.createdAfter);if($.createdBefore)J+=" AND o.created_at <= ?",Q.push($.createdBefore);if($.concepts&&$.concepts.length>0){let M=$.concepts.map(()=>"EXISTS (SELECT 1 FROM json_each(o.concepts) WHERE LOWER(value) = LOWER(?))");J+=` AND (${M.join(" OR ")})`;for(let X of $.concepts)Q.push(X)}if($.files&&$.files.length>0){let M=$.files.map(()=>`(EXISTS (SELECT 1 FROM json_each(o.files_read) WHERE LOWER(value) LIKE LOWER(?) ESCAPE '\\')
253
- OR EXISTS (SELECT 1 FROM json_each(o.files_modified) WHERE LOWER(value) LIKE LOWER(?) ESCAPE '\\'))`);J+=` AND (${M.join(" OR ")})`;for(let X of $.files){let W=`%${hf(X)}%`;Q.push(W,W)}}return J+=" ORDER BY rank LIMIT ? OFFSET ?",Q.push($.limit??10),Q.push($.offset??0),this.db.all(J,Q).map((M)=>({observation:this.mapRow(M),rank:M.rank,snippet:M.title}))}searchByConcept($,f=10,J){let Q=!!J,M=`SELECT o.*
234
+ `,E=[f.query];if(n&&f.projectPath)A+=" AND s.project_path = ?",E.push(f.projectPath);if(f.sessionId)A+=" AND o.session_id = ?",E.push(f.sessionId);if(f.type)A+=" AND o.type = ?",E.push(f.type);if(f.importanceMin!==void 0)A+=" AND o.importance >= ?",E.push(f.importanceMin);if(f.importanceMax!==void 0)A+=" AND o.importance <= ?",E.push(f.importanceMax);if(f.createdAfter)A+=" AND o.created_at >= ?",E.push(f.createdAfter);if(f.createdBefore)A+=" AND o.created_at <= ?",E.push(f.createdBefore);if(f.concepts&&f.concepts.length>0){let N=f.concepts.map(()=>"EXISTS (SELECT 1 FROM json_each(o.concepts) WHERE LOWER(value) = LOWER(?))");A+=` AND (${N.join(" OR ")})`;for(let O of f.concepts)E.push(O)}if(f.files&&f.files.length>0){let N=f.files.map(()=>`(EXISTS (SELECT 1 FROM json_each(o.files_read) WHERE LOWER(value) LIKE LOWER(?) ESCAPE '\\')
235
+ OR EXISTS (SELECT 1 FROM json_each(o.files_modified) WHERE LOWER(value) LIKE LOWER(?) ESCAPE '\\'))`);A+=` AND (${N.join(" OR ")})`;for(let O of f.files){let S=`%${pE(O)}%`;E.push(S,S)}}return A+=" ORDER BY rank LIMIT ? OFFSET ?",E.push(f.limit??10),E.push(f.offset??0),this.db.all(A,E).map((N)=>({observation:this.mapRow(N),rank:N.rank,snippet:N.title}))}searchByConcept(f,n=10,A){let E=!!A,N=`SELECT o.*
254
236
  FROM observations o
255
237
  JOIN observations_fts fts ON o._rowid = fts.rowid
256
- ${Q?"JOIN sessions s ON o.session_id = s.id":""}
238
+ ${E?"JOIN sessions s ON o.session_id = s.id":""}
257
239
  WHERE observations_fts MATCH ?
258
240
  AND o.superseded_by IS NULL AND o.deleted_at IS NULL
259
- ${Q?"AND s.project_path = ?":""}
241
+ ${E?"AND s.project_path = ?":""}
260
242
  ORDER BY rank
261
- LIMIT ?`,X=[`concepts:${$}`];if(Q&&J)X.push(J);return X.push(f),this.db.all(M,X).map((W)=>this.mapRow(W))}searchByFile($,f=10,J){let Q=!!J,M=`SELECT o.*
243
+ LIMIT ?`,O=[`concepts:${f}`];if(E&&A)O.push(A);return O.push(n),this.db.all(N,O).map((S)=>this.mapRow(S))}searchByFile(f,n=10,A){let E=!!A,N=`SELECT o.*
262
244
  FROM observations o
263
245
  JOIN observations_fts fts ON o._rowid = fts.rowid
264
- ${Q?"JOIN sessions s ON o.session_id = s.id":""}
246
+ ${E?"JOIN sessions s ON o.session_id = s.id":""}
265
247
  WHERE observations_fts MATCH ?
266
248
  AND o.superseded_by IS NULL AND o.deleted_at IS NULL
267
- ${Q?"AND s.project_path = ?":""}
249
+ ${E?"AND s.project_path = ?":""}
268
250
  ORDER BY rank
269
- LIMIT ?`,X=[`files_read:"${$.replace(/"/g,'""')}" OR files_modified:"${$.replace(/"/g,'""')}"`];if(Q&&J)X.push(J);return X.push(f),this.db.all(M,X).map((W)=>this.mapRow(W))}setEmbedding($,f){this.db.run("UPDATE observations SET embedding = ? WHERE id = ?",[JSON.stringify(f),$])}getWithEmbeddings($,f){return this.db.all(`SELECT o.id, o.embedding, o.title
251
+ LIMIT ?`,O=[`files_read:"${f.replace(/"/g,'""')}" OR files_modified:"${f.replace(/"/g,'""')}"`];if(E&&A)O.push(A);return O.push(n),this.db.all(N,O).map((S)=>this.mapRow(S))}setEmbedding(f,n){this.db.run("UPDATE observations SET embedding = ? WHERE id = ?",[JSON.stringify(n),f])}getWithEmbeddings(f,n){return this.db.all(`SELECT o.id, o.embedding, o.title
270
252
  FROM observations o
271
253
  JOIN sessions s ON o.session_id = s.id
272
254
  WHERE s.project_path = ? AND o.embedding IS NOT NULL AND o.superseded_by IS NULL AND o.deleted_at IS NULL
273
255
  ORDER BY o.created_at DESC
274
- LIMIT ?`,[$,f]).map((J)=>{try{return{id:J.id,embedding:JSON.parse(J.embedding),title:J.title}}catch{return null}}).filter((J)=>J!==null)}findSimilar($,f,J,Q){let M=this.db.all(`SELECT id, embedding FROM observations
256
+ LIMIT ?`,[f,n]).map((A)=>{try{return{id:A.id,embedding:JSON.parse(A.embedding),title:A.title}}catch{return null}}).filter((A)=>A!==null)}findSimilar(f,n,A,E){let N=this.db.all(`SELECT id, embedding FROM observations
275
257
  WHERE embedding IS NOT NULL AND type = ? AND superseded_by IS NULL AND deleted_at IS NULL
276
258
  ORDER BY created_at DESC
277
- LIMIT 200`,[f]),X=[];for(let W of M)try{let Z=JSON.parse(W.embedding);if(!Array.isArray(Z)||Z.length!==$.length)continue;let N=l($,Z);if(N>=J)X.push({id:W.id,similarity:N})}catch{}return X.sort((W,Z)=>Z.similarity-W.similarity).slice(0,Q)}insertVecEmbedding($,f){let J=new Float32Array(f);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 (?, ?)",[$,J]),this.db.run("COMMIT")}catch(Q){throw this.db.run("ROLLBACK"),Q}}migrateExistingEmbeddings($){let f=this.db.all("SELECT id, embedding FROM observations WHERE embedding IS NOT NULL"),J=0,Q=0;for(let M of f)try{let X=JSON.parse(M.embedding);if(!Array.isArray(X)||X.length!==$){Q++;continue}this.insertVecEmbedding(M.id,X),J++}catch{Q++}return{migrated:J,skipped:Q}}getVecEmbeddingMatches($,f){try{let J=new Float32Array($);return this.db.all(`SELECT observation_id, distance
259
+ LIMIT 200`,[n]),O=[];for(let S of N)try{let M=JSON.parse(S.embedding);if(!Array.isArray(M)||M.length!==f.length)continue;let _=Af(f,M);if(_>=A)O.push({id:S.id,similarity:_})}catch{}return O.sort((S,M)=>M.similarity-S.similarity).slice(0,E)}insertVecEmbedding(f,n){let A=new Float32Array(n);this.db.run("BEGIN");try{this.db.run("DELETE FROM observation_embeddings WHERE observation_id = ?",[f]),this.db.run("INSERT INTO observation_embeddings (observation_id, embedding) VALUES (?, ?)",[f,A]),this.db.run("COMMIT")}catch(E){throw this.db.run("ROLLBACK"),E}}migrateExistingEmbeddings(f){let n=this.db.all("SELECT id, embedding FROM observations WHERE embedding IS NOT NULL"),A=0,E=0;for(let N of n)try{let O=JSON.parse(N.embedding);if(!Array.isArray(O)||O.length!==f){E++;continue}this.insertVecEmbedding(N.id,O),A++}catch{E++}return{migrated:A,skipped:E}}getVecEmbeddingMatches(f,n){try{let A=new Float32Array(f);return this.db.all(`SELECT observation_id, distance
278
260
  FROM observation_embeddings
279
- WHERE embedding MATCH ? AND k = ?`,[J,f]).map((Q)=>({observationId:Q.observation_id,distance:Q.distance}))}catch{return[]}}searchVecSubset($,f,J){if(f.length===0)return[];try{let Q=new Float32Array($),M=Math.max(J*5,f.length),X=this.db.all(`SELECT observation_id, distance
261
+ WHERE embedding MATCH ? AND k = ?`,[A,n]).map((E)=>({observationId:E.observation_id,distance:E.distance}))}catch{return[]}}searchVecSubset(f,n,A){if(n.length===0)return[];try{let E=new Float32Array(f),N=Math.max(A*5,n.length),O=this.db.all(`SELECT observation_id, distance
280
262
  FROM observation_embeddings
281
- WHERE embedding MATCH ? AND k = ?`,[Q,M]),W=new Set(f);return X.filter((Z)=>W.has(Z.observation_id)).slice(0,J).map((Z)=>({observationId:Z.observation_id,distance:Z.distance}))}catch{return[]}}update($,f){let J=this.getById($);if(!J)return null;if(Object.keys(f).length===0)return J;let Q=this.create({sessionId:J.sessionId,scope:J.scope??"project",type:f.type??J.type,title:f.title??J.title,subtitle:f.subtitle??J.subtitle,facts:f.facts??J.facts,narrative:f.narrative??J.narrative,concepts:f.concepts??J.concepts,filesRead:f.filesRead??J.filesRead,filesModified:f.filesModified??J.filesModified,rawToolOutput:J.rawToolOutput,toolName:"mem-update",tokenCount:J.tokenCount,discoveryTokens:J.discoveryTokens,importance:f.importance??J.importance});return this.db.run("UPDATE observations SET revision_of = ? WHERE id = ?",[$,Q.id]),this.supersede($,Q.id),this.getById(Q.id)}supersede($,f){let J=new Date().toISOString();this.db.run("UPDATE observations SET superseded_by = ?, superseded_at = ? WHERE id = ?",[f,J,$])}delete($){if(this.db.all("SELECT id FROM observations WHERE id = ?",[$]).length===0)return!1;let J=new Date().toISOString();return this.db.run("UPDATE observations SET deleted_at = ? WHERE id = ?",[J,$]),this.deleteEmbeddingsForObservations([$]),!0}deleteOlderThan($){return this.db.all(`DELETE FROM observations
263
+ WHERE embedding MATCH ? AND k = ?`,[E,N]),S=new Set(n);return O.filter((M)=>S.has(M.observation_id)).slice(0,A).map((M)=>({observationId:M.observation_id,distance:M.distance}))}catch{return[]}}update(f,n){let A=this.getById(f);if(!A)return null;if(Object.keys(n).length===0)return A;let E=this.create({sessionId:A.sessionId,scope:A.scope??"project",type:n.type??A.type,title:n.title??A.title,subtitle:n.subtitle??A.subtitle,facts:n.facts??A.facts,narrative:n.narrative??A.narrative,concepts:n.concepts??A.concepts,filesRead:n.filesRead??A.filesRead,filesModified:n.filesModified??A.filesModified,rawToolOutput:A.rawToolOutput,toolName:"memory.revise",tokenCount:A.tokenCount,discoveryTokens:A.discoveryTokens,importance:n.importance??A.importance});return this.db.run("UPDATE observations SET revision_of = ? WHERE id = ?",[f,E.id]),this.supersede(f,E.id),this.getById(E.id)}supersede(f,n){let A=new Date().toISOString();this.db.run("UPDATE observations SET superseded_by = ?, superseded_at = ? WHERE id = ?",[n,A,f])}delete(f){if(this.db.all("SELECT id FROM observations WHERE id = ?",[f]).length===0)return!1;let A=new Date().toISOString();return this.db.run("UPDATE observations SET deleted_at = ? WHERE id = ?",[A,f]),this.deleteEmbeddingsForObservations([f]),!0}getLineage(f){let n=this.getByIdIncludingArchived(f);if(!n)return[];let A=new Set([n.id]),E=[n];while(E[0].revisionOf){let N=this.getByIdIncludingArchived(E[0].revisionOf);if(!N||A.has(N.id))break;E.unshift(N),A.add(N.id)}while(E[E.length-1].supersededBy){let N=E[E.length-1].supersededBy;if(!N)break;let O=this.getByIdIncludingArchived(N);if(!O||A.has(O.id))break;E.push(O),A.add(O.id)}return E}deleteOlderThan(f){return this.db.all(`DELETE FROM observations
282
264
  WHERE (created_at < datetime('now', '-' || ? || ' days') OR deleted_at IS NOT NULL)
283
265
  AND session_id NOT IN (SELECT id FROM sessions WHERE status != 'completed')
284
- RETURNING id`,[$]).length}deleteEmbeddingsForObservations($){if($.length===0)return;let f=$.map(()=>"?").join(",");try{this.db.run(`DELETE FROM observation_embeddings WHERE observation_id IN (${f})`,$)}catch{}this.db.run(`UPDATE observations SET embedding = NULL WHERE id IN (${f})`,$)}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 bf}from"crypto";class o0{db;constructor($){this.db=$}create($){let f=bf(),J=new Date().toISOString();return this.db.run(`INSERT INTO pending_messages
266
+ RETURNING id`,[f]).length}deleteEmbeddingsForObservations(f){if(f.length===0)return;let n=f.map(()=>"?").join(",");try{this.db.run(`DELETE FROM observation_embeddings WHERE observation_id IN (${n})`,f)}catch{}this.db.run(`UPDATE observations SET embedding = NULL WHERE id IN (${n})`,f)}mapRow(f){return{id:f.id,sessionId:f.session_id,scope:f.scope??"project",type:f.type,title:f.title,subtitle:f.subtitle,facts:JSON.parse(f.facts),narrative:f.narrative,concepts:JSON.parse(f.concepts),filesRead:JSON.parse(f.files_read),filesModified:JSON.parse(f.files_modified),rawToolOutput:f.raw_tool_output,toolName:f.tool_name,createdAt:f.created_at,tokenCount:f.token_count,discoveryTokens:f.discovery_tokens??0,importance:f.importance??3,revisionOf:f.revision_of??null,deletedAt:f.deleted_at??null,supersededBy:f.superseded_by??null,supersededAt:f.superseded_at??null}}}import{randomUUID as bE}from"crypto";class T0{db;constructor(f){this.db=f}create(f){let n=bE(),A=new Date().toISOString();return this.db.run(`INSERT INTO pending_messages
285
267
  (id, session_id, tool_name, tool_output, call_id, created_at)
286
- VALUES (?, ?, ?, ?, ?, ?)`,[f,$.sessionId,$.toolName,$.toolOutput,$.callId,J]),{...$,id:f,createdAt:J,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((f)=>this.mapRow(f))}getByStatus($){return this.db.all("SELECT * FROM pending_messages WHERE status = ? ORDER BY created_at ASC",[$]).map((f)=>this.mapRow(f))}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($,f){this.db.run("UPDATE pending_messages SET status = 'failed', error = ?, retry_count = retry_count + 1 WHERE id = ?",[f,$])}resetStale($=5){return this.db.all(`UPDATE pending_messages SET status = 'pending'
268
+ VALUES (?, ?, ?, ?, ?, ?)`,[n,f.sessionId,f.toolName,f.toolOutput,f.callId,A]),{...f,id:n,createdAt:A,status:"pending",retryCount:0,error:null}}getPending(f=10){return this.db.all("SELECT * FROM pending_messages WHERE status = 'pending' ORDER BY created_at ASC LIMIT ?",[f]).map((n)=>this.mapRow(n))}getByStatus(f){return this.db.all("SELECT * FROM pending_messages WHERE status = ? ORDER BY created_at ASC",[f]).map((n)=>this.mapRow(n))}markProcessing(f){this.db.run("UPDATE pending_messages SET status = 'processing' WHERE id = ?",[f])}markCompleted(f){this.db.run("UPDATE pending_messages SET status = 'completed' WHERE id = ?",[f])}markFailed(f,n){this.db.run("UPDATE pending_messages SET status = 'failed', error = ?, retry_count = retry_count + 1 WHERE id = ?",[n,f])}resetStale(f=5){return this.db.all(`UPDATE pending_messages SET status = 'pending'
287
269
  WHERE status = 'processing'
288
270
  AND created_at < datetime('now', ? || ' minutes')
289
- RETURNING id`,[`-${$}`]).length}deleteCompletedOlderThan($){return this.db.all(`DELETE FROM pending_messages
271
+ RETURNING id`,[`-${f}`]).length}deleteCompletedOlderThan(f){return this.db.all(`DELETE FROM pending_messages
290
272
  WHERE status = 'completed'
291
273
  AND created_at < datetime('now', '-' || ? || ' days')
292
- 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 uf=[{version:1,name:"create-core-tables",up:`
274
+ RETURNING id`,[f]).length}mapRow(f){return{id:f.id,sessionId:f.session_id,toolName:f.tool_name,toolOutput:f.tool_output,callId:f.call_id,createdAt:f.created_at,status:f.status,retryCount:f.retry_count,error:f.error??null}}}var iE=[{version:1,name:"create-schema",up:`
293
275
  -- Sessions table
294
276
  CREATE TABLE IF NOT EXISTS sessions (
295
277
  _rowid INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -328,6 +310,15 @@ ${K}`}return S}guide(){return["open-mem workflow:","1) Use mem-search to find ca
328
310
  tool_name TEXT NOT NULL,
329
311
  created_at TEXT NOT NULL DEFAULT (datetime('now')),
330
312
  token_count INTEGER NOT NULL DEFAULT 0,
313
+ discovery_tokens INTEGER NOT NULL DEFAULT 0,
314
+ embedding TEXT,
315
+ importance INTEGER NOT NULL DEFAULT 3,
316
+ superseded_by TEXT,
317
+ superseded_at TEXT,
318
+ scope TEXT NOT NULL DEFAULT 'project'
319
+ CHECK (scope IN ('project','user')),
320
+ revision_of TEXT,
321
+ deleted_at TEXT,
331
322
  FOREIGN KEY (session_id) REFERENCES sessions(id)
332
323
  );
333
324
 
@@ -337,6 +328,23 @@ ${K}`}return S}guide(){return["open-mem workflow:","1) Use mem-search to find ca
337
328
  ON observations(type);
338
329
  CREATE INDEX IF NOT EXISTS idx_observations_created
339
330
  ON observations(created_at DESC);
331
+ CREATE INDEX IF NOT EXISTS idx_observations_superseded
332
+ ON observations(superseded_by);
333
+ CREATE INDEX IF NOT EXISTS idx_observations_scope
334
+ ON observations(scope);
335
+ CREATE INDEX IF NOT EXISTS idx_observations_revision_of
336
+ ON observations(revision_of);
337
+ CREATE INDEX IF NOT EXISTS idx_observations_deleted_at
338
+ ON observations(deleted_at);
339
+
340
+ -- Clean up superseded_by when the superseding observation is deleted
341
+ CREATE TRIGGER IF NOT EXISTS trg_clear_superseded_by
342
+ AFTER DELETE ON observations
343
+ BEGIN
344
+ UPDATE observations
345
+ SET superseded_by = NULL, superseded_at = NULL
346
+ WHERE superseded_by = OLD.id;
347
+ END;
340
348
 
341
349
  -- Session summaries table
342
350
  CREATE TABLE IF NOT EXISTS session_summaries (
@@ -349,6 +357,11 @@ ${K}`}return S}guide(){return["open-mem workflow:","1) Use mem-search to find ca
349
357
  concepts TEXT NOT NULL DEFAULT '[]',
350
358
  created_at TEXT NOT NULL DEFAULT (datetime('now')),
351
359
  token_count INTEGER NOT NULL DEFAULT 0,
360
+ request TEXT NOT NULL DEFAULT '',
361
+ investigated TEXT NOT NULL DEFAULT '',
362
+ learned TEXT NOT NULL DEFAULT '',
363
+ completed TEXT NOT NULL DEFAULT '',
364
+ next_steps TEXT NOT NULL DEFAULT '',
352
365
  FOREIGN KEY (session_id) REFERENCES sessions(id)
353
366
  );
354
367
 
@@ -372,8 +385,83 @@ ${K}`}return S}guide(){return["open-mem workflow:","1) Use mem-search to find ca
372
385
  ON pending_messages(status);
373
386
  CREATE INDEX IF NOT EXISTS idx_pending_session
374
387
  ON pending_messages(session_id);
375
- `},{version:2,name:"create-fts5-tables",up:`
376
- -- FTS5 for observations (title, subtitle, narrative, facts, concepts, files)
388
+
389
+ -- Embedding metadata
390
+ CREATE TABLE IF NOT EXISTS _embedding_meta (
391
+ key TEXT PRIMARY KEY,
392
+ value TEXT NOT NULL
393
+ );
394
+
395
+ -- Config audit events
396
+ CREATE TABLE IF NOT EXISTS config_audit_events (
397
+ _rowid INTEGER PRIMARY KEY AUTOINCREMENT,
398
+ id TEXT UNIQUE NOT NULL,
399
+ timestamp TEXT NOT NULL,
400
+ patch TEXT NOT NULL,
401
+ previous_values TEXT NOT NULL,
402
+ source TEXT NOT NULL
403
+ CHECK (source IN ('api','mode','rollback','rollback-failed'))
404
+ );
405
+ CREATE INDEX IF NOT EXISTS idx_config_audit_timestamp
406
+ ON config_audit_events(timestamp DESC);
407
+
408
+ -- Maintenance history
409
+ CREATE TABLE IF NOT EXISTS maintenance_history (
410
+ _rowid INTEGER PRIMARY KEY AUTOINCREMENT,
411
+ id TEXT UNIQUE NOT NULL,
412
+ timestamp TEXT NOT NULL,
413
+ action TEXT NOT NULL,
414
+ dry_run INTEGER NOT NULL DEFAULT 0,
415
+ result TEXT NOT NULL
416
+ );
417
+ CREATE INDEX IF NOT EXISTS idx_maintenance_history_timestamp
418
+ ON maintenance_history(timestamp DESC);
419
+
420
+ -- Entities table
421
+ CREATE TABLE IF NOT EXISTS entities (
422
+ _rowid INTEGER PRIMARY KEY AUTOINCREMENT,
423
+ id TEXT UNIQUE NOT NULL,
424
+ name TEXT NOT NULL,
425
+ entity_type TEXT NOT NULL
426
+ CHECK (entity_type IN ('technology','library','pattern','concept','file','person','project','other')),
427
+ first_seen_at TEXT NOT NULL DEFAULT (datetime('now')),
428
+ last_seen_at TEXT NOT NULL DEFAULT (datetime('now')),
429
+ mention_count INTEGER NOT NULL DEFAULT 1,
430
+ UNIQUE(name, entity_type)
431
+ );
432
+
433
+ CREATE INDEX IF NOT EXISTS idx_entities_name ON entities(name);
434
+ CREATE INDEX IF NOT EXISTS idx_entities_type ON entities(entity_type);
435
+
436
+ -- Entity relations table
437
+ CREATE TABLE IF NOT EXISTS entity_relations (
438
+ _rowid INTEGER PRIMARY KEY AUTOINCREMENT,
439
+ id TEXT UNIQUE NOT NULL,
440
+ source_entity_id TEXT NOT NULL,
441
+ target_entity_id TEXT NOT NULL,
442
+ relationship TEXT NOT NULL
443
+ CHECK (relationship IN ('uses','depends_on','implements','extends','related_to','replaces','configures')),
444
+ observation_id TEXT NOT NULL,
445
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
446
+ UNIQUE(source_entity_id, target_entity_id, relationship),
447
+ FOREIGN KEY (source_entity_id) REFERENCES entities(id) ON DELETE CASCADE,
448
+ FOREIGN KEY (target_entity_id) REFERENCES entities(id) ON DELETE CASCADE,
449
+ FOREIGN KEY (observation_id) REFERENCES observations(id) ON DELETE CASCADE
450
+ );
451
+
452
+ CREATE INDEX IF NOT EXISTS idx_entity_relations_source ON entity_relations(source_entity_id);
453
+ CREATE INDEX IF NOT EXISTS idx_entity_relations_target ON entity_relations(target_entity_id);
454
+
455
+ -- Entity-Observation junction table
456
+ CREATE TABLE IF NOT EXISTS entity_observations (
457
+ entity_id TEXT NOT NULL,
458
+ observation_id TEXT NOT NULL,
459
+ PRIMARY KEY (entity_id, observation_id),
460
+ FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE,
461
+ FOREIGN KEY (observation_id) REFERENCES observations(id) ON DELETE CASCADE
462
+ );
463
+
464
+ -- FTS5 for observations
377
465
  CREATE VIRTUAL TABLE IF NOT EXISTS observations_fts USING fts5(
378
466
  title,
379
467
  subtitle,
@@ -387,7 +475,6 @@ ${K}`}return S}guide(){return["open-mem workflow:","1) Use mem-search to find ca
387
475
  tokenize='porter unicode61'
388
476
  );
389
477
 
390
- -- Triggers to keep FTS5 in sync with observations table
391
478
  CREATE TRIGGER observations_ai AFTER INSERT ON observations BEGIN
392
479
  INSERT INTO observations_fts(
393
480
  rowid, title, subtitle, narrative, facts, concepts,
@@ -444,88 +531,14 @@ ${K}`}return S}guide(){return["open-mem workflow:","1) Use mem-search to find ca
444
531
  VALUES (new._rowid, new.summary, new.key_decisions, new.concepts);
445
532
  END;
446
533
 
447
- CREATE TRIGGER summaries_ad AFTER DELETE ON session_summaries BEGIN
448
- INSERT INTO summaries_fts(
449
- summaries_fts, rowid, summary, key_decisions, concepts
450
- )
451
- VALUES (
452
- 'delete', old._rowid, old.summary, old.key_decisions, old.concepts
453
- );
454
- END;
455
- `},{version:3,name:"add-structured-summary-columns",up:`
456
- ALTER TABLE session_summaries ADD COLUMN request TEXT NOT NULL DEFAULT '';
457
- ALTER TABLE session_summaries ADD COLUMN investigated TEXT NOT NULL DEFAULT '';
458
- ALTER TABLE session_summaries ADD COLUMN learned TEXT NOT NULL DEFAULT '';
459
- ALTER TABLE session_summaries ADD COLUMN completed TEXT NOT NULL DEFAULT '';
460
- ALTER TABLE session_summaries ADD COLUMN next_steps TEXT NOT NULL DEFAULT '';
461
- `},{version:4,name:"add-discovery-tokens",up:`
462
- ALTER TABLE observations ADD COLUMN discovery_tokens INTEGER NOT NULL DEFAULT 0;
463
- `},{version:5,name:"add-embedding-column",up:`
464
- ALTER TABLE observations ADD COLUMN embedding TEXT;
465
- `},{version:6,name:"create-embedding-meta-table",up:`
466
- CREATE TABLE IF NOT EXISTS _embedding_meta (
467
- key TEXT PRIMARY KEY,
468
- value TEXT NOT NULL
469
- );
470
- `},{version:7,name:"add-importance-column",up:`
471
- ALTER TABLE observations ADD COLUMN importance INTEGER NOT NULL DEFAULT 3;
472
- `},{version:8,name:"add-conflict-resolution-columns",up:`
473
- ALTER TABLE observations ADD COLUMN superseded_by TEXT;
474
- ALTER TABLE observations ADD COLUMN superseded_at TEXT;
475
- CREATE INDEX IF NOT EXISTS idx_observations_superseded ON observations(superseded_by);
476
-
477
- -- Clean up superseded_by when the superseding observation is deleted
478
- CREATE TRIGGER IF NOT EXISTS trg_clear_superseded_by
479
- AFTER DELETE ON observations
480
- BEGIN
481
- UPDATE observations
482
- SET superseded_by = NULL, superseded_at = NULL
483
- WHERE superseded_by = OLD.id;
534
+ CREATE TRIGGER summaries_ad AFTER DELETE ON session_summaries BEGIN
535
+ INSERT INTO summaries_fts(
536
+ summaries_fts, rowid, summary, key_decisions, concepts
537
+ )
538
+ VALUES (
539
+ 'delete', old._rowid, old.summary, old.key_decisions, old.concepts
540
+ );
484
541
  END;
485
- `},{version:9,name:"create-entity-graph-tables",up:`
486
- -- Entities table
487
- CREATE TABLE IF NOT EXISTS entities (
488
- _rowid INTEGER PRIMARY KEY AUTOINCREMENT,
489
- id TEXT UNIQUE NOT NULL,
490
- name TEXT NOT NULL,
491
- entity_type TEXT NOT NULL
492
- CHECK (entity_type IN ('technology','library','pattern','concept','file','person','project','other')),
493
- first_seen_at TEXT NOT NULL DEFAULT (datetime('now')),
494
- last_seen_at TEXT NOT NULL DEFAULT (datetime('now')),
495
- mention_count INTEGER NOT NULL DEFAULT 1,
496
- UNIQUE(name, entity_type)
497
- );
498
-
499
- CREATE INDEX IF NOT EXISTS idx_entities_name ON entities(name);
500
- CREATE INDEX IF NOT EXISTS idx_entities_type ON entities(entity_type);
501
-
502
- -- Entity relations table
503
- CREATE TABLE IF NOT EXISTS entity_relations (
504
- _rowid INTEGER PRIMARY KEY AUTOINCREMENT,
505
- id TEXT UNIQUE NOT NULL,
506
- source_entity_id TEXT NOT NULL,
507
- target_entity_id TEXT NOT NULL,
508
- relationship TEXT NOT NULL
509
- CHECK (relationship IN ('uses','depends_on','implements','extends','related_to','replaces','configures')),
510
- observation_id TEXT NOT NULL,
511
- created_at TEXT NOT NULL DEFAULT (datetime('now')),
512
- UNIQUE(source_entity_id, target_entity_id, relationship),
513
- FOREIGN KEY (source_entity_id) REFERENCES entities(id) ON DELETE CASCADE,
514
- FOREIGN KEY (target_entity_id) REFERENCES entities(id) ON DELETE CASCADE,
515
- FOREIGN KEY (observation_id) REFERENCES observations(id) ON DELETE CASCADE
516
- );
517
-
518
- CREATE INDEX IF NOT EXISTS idx_entity_relations_source ON entity_relations(source_entity_id);
519
- CREATE INDEX IF NOT EXISTS idx_entity_relations_target ON entity_relations(target_entity_id);
520
-
521
- -- Entity-Observation junction table
522
- CREATE TABLE IF NOT EXISTS entity_observations (
523
- entity_id TEXT NOT NULL,
524
- observation_id TEXT NOT NULL,
525
- PRIMARY KEY (entity_id, observation_id),
526
- FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE,
527
- FOREIGN KEY (observation_id) REFERENCES observations(id) ON DELETE CASCADE
528
- );
529
542
 
530
543
  -- FTS5 for entity search
531
544
  CREATE VIRTUAL TABLE IF NOT EXISTS entities_fts USING fts5(
@@ -536,7 +549,6 @@ ${K}`}return S}guide(){return["open-mem workflow:","1) Use mem-search to find ca
536
549
  tokenize='porter unicode61'
537
550
  );
538
551
 
539
- -- FTS5 sync triggers
540
552
  CREATE TRIGGER entities_ai AFTER INSERT ON entities BEGIN
541
553
  INSERT INTO entities_fts(rowid, name, entity_type)
542
554
  VALUES (new._rowid, new.name, new.entity_type);
@@ -553,33 +565,24 @@ ${K}`}return S}guide(){return["open-mem workflow:","1) Use mem-search to find ca
553
565
  INSERT INTO entities_fts(rowid, name, entity_type)
554
566
  VALUES (new._rowid, new.name, new.entity_type);
555
567
  END;
556
- `},{version:10,name:"add-v1-revision-tombstone-columns",up:`
557
- ALTER TABLE observations ADD COLUMN scope TEXT NOT NULL DEFAULT 'project'
558
- CHECK (scope IN ('project','user'));
559
- ALTER TABLE observations ADD COLUMN revision_of TEXT;
560
- ALTER TABLE observations ADD COLUMN deleted_at TEXT;
561
-
562
- CREATE INDEX IF NOT EXISTS idx_observations_scope ON observations(scope);
563
- CREATE INDEX IF NOT EXISTS idx_observations_revision_of ON observations(revision_of);
564
- CREATE INDEX IF NOT EXISTS idx_observations_deleted_at ON observations(deleted_at);
565
- `}];function U1($,f){if($.migrate(uf),f?.hasVectorExtension&&f?.embeddingDimension&&f.embeddingDimension>0)mf($,f.embeddingDimension)}function mf($,f){if($.get("SELECT name FROM sqlite_master WHERE type='table' AND name='observation_embeddings'")){let Q=$.get("SELECT value FROM _embedding_meta WHERE key = 'dimension'");if(Q&&Number(Q.value)!==f){console.warn(`[open-mem] vec0 table exists with dimension ${Q.value}, but config specifies ${f}. Drop observation_embeddings to re-create with new dimension.`);return}}else $.exec(`CREATE VIRTUAL TABLE observation_embeddings USING vec0(
568
+ `}];function $A(f,n){if(f.migrate(iE),n?.hasVectorExtension&&n?.embeddingDimension&&n.embeddingDimension>0)tE(f,n.embeddingDimension)}function tE(f,n){if(f.get("SELECT name FROM sqlite_master WHERE type='table' AND name='observation_embeddings'")){let E=f.get("SELECT value FROM _embedding_meta WHERE key = 'dimension'");if(E&&Number(E.value)!==n){console.warn(`[open-mem] vec0 table exists with dimension ${E.value}, but config specifies ${n}. Drop observation_embeddings to re-create with new dimension.`);return}}else f.exec(`CREATE VIRTUAL TABLE observation_embeddings USING vec0(
566
569
  observation_id TEXT PRIMARY KEY,
567
- embedding float[${f}] distance_metric=cosine
568
- )`);$.run("INSERT OR REPLACE INTO _embedding_meta (key, value) VALUES (?, ?)",["dimension",String(f)])}class t0{db;constructor($){this.db=$}create($,f){let J=new Date().toISOString();return this.db.run(`INSERT INTO sessions (id, project_path, started_at, status)
569
- VALUES (?, ?, ?, 'active')`,[$,f,J]),this.getById($)}getOrCreate($,f){let J=this.getById($);if(J)return J;return this.create($,f)}getById($){let f=this.db.get("SELECT * FROM sessions WHERE id = ?",[$]);return f?this.mapRow(f):null}getRecent($,f=10){return this.db.all("SELECT * FROM sessions WHERE project_path = ? ORDER BY started_at DESC LIMIT ?",[$,f]).map((J)=>this.mapRow(J))}getAll($){return this.db.all("SELECT * FROM sessions WHERE project_path = ? ORDER BY started_at DESC",[$]).map((f)=>this.mapRow(f))}getActive(){return this.db.all("SELECT * FROM sessions WHERE status = 'active' ORDER BY started_at DESC").map(($)=>this.mapRow($))}updateStatus($,f){this.db.run("UPDATE sessions SET status = ? WHERE id = ?",[f,$])}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($,f){this.db.run("UPDATE sessions SET summary_id = ? WHERE id = ?",[f,$])}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 lf}from"crypto";class e0{db;constructor($){this.db=$}create($){let f=lf(),J=new Date().toISOString();return this.db.run(`INSERT INTO session_summaries
570
+ embedding float[${n}] distance_metric=cosine
571
+ )`);f.run("INSERT OR REPLACE INTO _embedding_meta (key, value) VALUES (?, ?)",["dimension",String(n)])}class P0{db;constructor(f){this.db=f}create(f,n){let A=new Date().toISOString();return this.db.run(`INSERT INTO sessions (id, project_path, started_at, status)
572
+ VALUES (?, ?, ?, 'active')`,[f,n,A]),this.getById(f)}getOrCreate(f,n){let A=this.getById(f);if(A)return A;return this.create(f,n)}getById(f){let n=this.db.get("SELECT * FROM sessions WHERE id = ?",[f]);return n?this.mapRow(n):null}getRecent(f,n=10){return this.db.all("SELECT * FROM sessions WHERE project_path = ? ORDER BY started_at DESC LIMIT ?",[f,n]).map((A)=>this.mapRow(A))}getAll(f){return this.db.all("SELECT * FROM sessions WHERE project_path = ? ORDER BY started_at DESC",[f]).map((n)=>this.mapRow(n))}getActive(){return this.db.all("SELECT * FROM sessions WHERE status = 'active' ORDER BY started_at DESC").map((f)=>this.mapRow(f))}updateStatus(f,n){this.db.run("UPDATE sessions SET status = ? WHERE id = ?",[n,f])}markCompleted(f){this.db.run("UPDATE sessions SET status = 'completed', ended_at = datetime('now') WHERE id = ?",[f])}incrementObservationCount(f){this.db.run("UPDATE sessions SET observation_count = observation_count + 1 WHERE id = ?",[f])}setSummary(f,n){this.db.run("UPDATE sessions SET summary_id = ? WHERE id = ?",[n,f])}mapRow(f){return{id:f.id,projectPath:f.project_path,startedAt:f.started_at,endedAt:f.ended_at??null,status:f.status,observationCount:f.observation_count,summaryId:f.summary_id??null}}}import{randomUUID as aE}from"crypto";class k0{db;constructor(f){this.db=f}create(f){let n=aE(),A=new Date().toISOString();return this.db.run(`INSERT INTO session_summaries
570
573
  (id, session_id, summary, key_decisions, files_modified,
571
574
  concepts, created_at, token_count,
572
575
  request, investigated, learned, completed, next_steps)
573
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[f,$.sessionId,$.summary,JSON.stringify($.keyDecisions),JSON.stringify($.filesModified),JSON.stringify($.concepts),J,$.tokenCount,$.request??"",$.investigated??"",$.learned??"",$.completed??"",$.nextSteps??""]),{...$,id:f,createdAt:J}}importSummary($){this.db.run(`INSERT INTO session_summaries
576
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[n,f.sessionId,f.summary,JSON.stringify(f.keyDecisions),JSON.stringify(f.filesModified),JSON.stringify(f.concepts),A,f.tokenCount,f.request??"",f.investigated??"",f.learned??"",f.completed??"",f.nextSteps??""]),{...f,id:n,createdAt:A}}importSummary(f){this.db.run(`INSERT INTO session_summaries
574
577
  (id, session_id, summary, key_decisions, files_modified,
575
578
  concepts, created_at, token_count,
576
579
  request, investigated, learned, completed, next_steps)
577
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[$.id,$.sessionId,$.summary,JSON.stringify($.keyDecisions),JSON.stringify($.filesModified),JSON.stringify($.concepts),$.createdAt,$.tokenCount,$.request??"",$.investigated??"",$.learned??"",$.completed??"",$.nextSteps??""])}getBySessionId($){let f=this.db.get("SELECT * FROM session_summaries WHERE session_id = ?",[$]);return f?this.mapRow(f):null}getRecent($=10){return this.db.all("SELECT * FROM session_summaries ORDER BY created_at DESC LIMIT ?",[$]).map((f)=>this.mapRow(f))}search($,f=10){return this.db.all(`SELECT ss.*
580
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[f.id,f.sessionId,f.summary,JSON.stringify(f.keyDecisions),JSON.stringify(f.filesModified),JSON.stringify(f.concepts),f.createdAt,f.tokenCount,f.request??"",f.investigated??"",f.learned??"",f.completed??"",f.nextSteps??""])}getBySessionId(f){let n=this.db.get("SELECT * FROM session_summaries WHERE session_id = ?",[f]);return n?this.mapRow(n):null}getRecent(f=10){return this.db.all("SELECT * FROM session_summaries ORDER BY created_at DESC LIMIT ?",[f]).map((n)=>this.mapRow(n))}search(f,n=10){return this.db.all(`SELECT ss.*
578
581
  FROM session_summaries ss
579
582
  JOIN summaries_fts fts ON ss._rowid = fts.rowid
580
583
  WHERE summaries_fts MATCH ?
581
584
  ORDER BY rank
582
- LIMIT ?`,[$,f]).map((J)=>this.mapRow(J))}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}}}import{randomUUID as cf}from"crypto";var pf=[{version:1,name:"create-user-observations",up:`
585
+ LIMIT ?`,[f,n]).map((A)=>this.mapRow(A))}mapRow(f){return{id:f.id,sessionId:f.session_id,summary:f.summary,keyDecisions:JSON.parse(f.key_decisions),filesModified:JSON.parse(f.files_modified),concepts:JSON.parse(f.concepts),createdAt:f.created_at,tokenCount:f.token_count,request:f.request||void 0,investigated:f.investigated||void 0,learned:f.learned||void 0,completed:f.completed||void 0,nextSteps:f.next_steps||void 0}}}import{randomUUID as sE}from"crypto";var oE=[{version:1,name:"create-user-observations",up:`
583
586
  CREATE TABLE IF NOT EXISTS user_observations (
584
587
  _rowid INTEGER PRIMARY KEY AUTOINCREMENT,
585
588
  id TEXT UNIQUE NOT NULL,
@@ -650,22 +653,17 @@ ${K}`}return S}guide(){return["open-mem workflow:","1) Use mem-search to find ca
650
653
  new.facts, new.concepts, new.files_read, new.files_modified
651
654
  );
652
655
  END;
653
- `}];class $${db;constructor($){let f=nf($);this.db=E0(f),this.initializeUserSchema()}initializeUserSchema(){this.db.migrate(pf)}get database(){return this.db}close(){this.db.close()}}class f${db;constructor($){this.db=$}create($){let f=cf(),J=new Date().toISOString();return this.db.run(`INSERT INTO user_observations
656
+ `}];class I0{db;constructor(f){let n=dE(f);this.db=hf(n),this.initializeUserSchema()}initializeUserSchema(){this.db.migrate(oE)}get database(){return this.db}close(){this.db.close()}}class w0{db;constructor(f){this.db=f}create(f){let n=sE(),A=new Date().toISOString();return this.db.run(`INSERT INTO user_observations
654
657
  (id, type, title, subtitle, facts, narrative,
655
658
  concepts, files_read, files_modified, tool_name,
656
659
  created_at, token_count, importance, source_project)
657
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[f,$.type,$.title,$.subtitle,JSON.stringify($.facts),$.narrative,JSON.stringify($.concepts),JSON.stringify($.filesRead),JSON.stringify($.filesModified),$.toolName,J,$.tokenCount,$.importance??3,$.sourceProject]),{...$,id:f,createdAt:J,importance:$.importance??3}}search($){try{let f=`
660
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[n,f.type,f.title,f.subtitle,JSON.stringify(f.facts),f.narrative,JSON.stringify(f.concepts),JSON.stringify(f.filesRead),JSON.stringify(f.filesModified),f.toolName,A,f.tokenCount,f.importance??3,f.sourceProject]),{...f,id:n,createdAt:A,importance:f.importance??3}}search(f){try{let n=`
658
661
  SELECT o.*, rank
659
662
  FROM user_observations o
660
663
  JOIN user_observations_fts fts ON o._rowid = fts.rowid
661
664
  WHERE user_observations_fts MATCH ?
662
- `,J=[$.query];if($.sourceProject)f+=" AND o.source_project = ?",J.push($.sourceProject);return f+=" ORDER BY rank LIMIT ?",J.push($.limit??10),this.db.all(f,J).map((Q)=>({observation:this.mapRow(Q),rank:Q.rank}))}catch{return[]}}getIndex($,f){let J=`SELECT id, type, title, token_count, created_at, importance, source_project
663
- FROM user_observations`,Q=[];if(f)J+=" WHERE source_project = ?",Q.push(f);return J+=" ORDER BY created_at DESC LIMIT ?",Q.push($??20),this.db.all(J,Q).map((M)=>({id:M.id,sessionId:"",type:M.type,title:M.title,tokenCount:M.token_count,discoveryTokens:0,createdAt:M.created_at,importance:M.importance??3}))}getById($){let f=this.db.get("SELECT * FROM user_observations WHERE id = ?",[$]);return f?this.mapRow(f):null}delete($){return this.db.all("DELETE FROM user_observations WHERE id = ? RETURNING id",[$]).length>0}mapRow($){return{id:$.id,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),toolName:$.tool_name,createdAt:$.created_at,tokenCount:$.token_count,importance:$.importance??3,sourceProject:$.source_project}}}function nf($){if($.startsWith("~/")){let f=process.env.HOME||process.env.USERPROFILE||"";if(!f)throw Error("Cannot resolve user DB path: HOME environment variable is not set");let J=`${f}${$.slice(1)}`,Q=J.substring(0,J.lastIndexOf("/"));return I("fs").mkdirSync(Q,{recursive:!0}),J}return $}import{EventEmitter as df}from"events";function A1(){return new df}function L0($,f=""){if(!$)return $;return $.replace(/<private>[\s\S]*?<\/private>/gi,f)}var z1=200,rf=/(\([\s\S]*[+*]\)\s*[+*?])|(\(\.\*\)\+)|(\(\.\+\)\+)/;function H0($,f,J="[REDACTED]"){if(!$||f.length===0)return $;let Q=$;for(let M of f){if(M.length>z1){console.warn(`[open-mem] Skipping oversized redaction pattern (${M.length} chars, max ${z1})`);continue}if(rf.test(M)){console.warn("[open-mem] Skipping potentially dangerous redaction pattern (nested quantifiers detected)");continue}try{Q=Q.replace(new RegExp(M,"g"),J)}catch{}}return Q}var sf=20,B1=2000,G1=60;function af($){return typeof $==="object"&&$!==null&&"text"in $&&typeof $.text==="string"}function of($){let f=[];for(let J of $)if(typeof J==="string")f.push(J);else if(af(J))f.push(J.text);return f.join(`
664
- `).trim()}function tf($){let f=$.toLowerCase().replace(/[^a-z0-9\s-]/g," ").split(/\s+/).filter((J)=>J.length>4);return[...new Set(f)].slice(0,5)}function _1($,f,J,Q=[]){return async(M,X)=>{try{let{sessionID:W,agent:Z}=M;if(Z!==void 0&&Z!=="user")return;let N=of(X.parts),S=H0(L0(N),Q);if(S.length<sf)return;f.getOrCreate(W,J);let V=`User request: ${S.length>G1?`${S.slice(0,G1)}...`:S}`,Y=S.length>B1?`${S.slice(0,B1)}...`:S;$.create({sessionId:W,type:"discovery",title:V,subtitle:"",facts:[],narrative:Y,concepts:tf(S),filesRead:[],filesModified:[],rawToolOutput:"",toolName:"chat.message",tokenCount:Math.ceil(Y.length/4),discoveryTokens:0,importance:3})}catch(W){console.error("[open-mem] Chat capture error:",W)}}}function F1($,f,J,Q,M,X){return async(W,Z)=>{try{if(!$.contextInjectionEnabled)return;let N=J.getRecent(M,3),S=N.map((U)=>U.summaryId?Q.getBySessionId(U.id):null).filter((U)=>U!==null),K=f.getIndex(M,10);if(S.length===0&&K.length===0)return;let V=u(N,S,K,Math.floor($.maxContextTokens/2)),Y=V0(V);if($.userMemoryEnabled&&X){let U=X.getIndex(10),G=U0(U,Math.floor($.userMemoryMaxContextTokens/2));if(G)Y+=G}Z.context.push(Y)}catch(N){console.error("[open-mem] Compaction hook error:",N)}}}function E1($,f,J,Q,M,X){return async(W,Z)=>{try{if(!$.contextInjectionEnabled)return;let N=J.getRecent(M,5);if(N.length===0)return;let S=N.map((B)=>B.summaryId?Q.getBySessionId(B.id):null).filter((B)=>B!==null),K=f.getIndex(M,$.maxObservations);if(S.length===0&&K.length===0)return;let Y=K.slice(0,$.contextFullObservationCount).map((B)=>B.id).map((B)=>f.getById(B)).filter((B)=>B!==null),U=u(N,S,K,$.maxContextTokens,Y),G={showTokenCosts:$.contextShowTokenCosts,observationTypes:$.contextObservationTypes,fullObservationCount:$.contextFullObservationCount,showLastSummary:$.contextShowLastSummary},A=K0(U,G);if($.userMemoryEnabled&&X){let B=X.getIndex($.maxObservations),_=Y0(B,$.userMemoryMaxContextTokens);if(_)A+=`
665
-
666
- ${_}`}Z.system.push(A)}catch(N){console.error("[open-mem] Context injection error:",N)}}}function L1($,f,J){if($.retentionDays===0)return;try{let Q=f.deleteOlderThan($.retentionDays),M=J.deleteCompletedOlderThan($.retentionDays);if(Q>0||M>0)console.log(`[open-mem] Retention: deleted ${Q} observations, ${M} pending messages`)}catch(Q){console.error("[open-mem] Retention enforcement error:",Q)}}function O1($,f,J,Q,M,X){return async(W)=>{try{let{event:Z}=W,N=Z.properties.sessionID,S=typeof N==="string"?N:void 0;switch(Z.type){case"session.created":{if(S)f.getOrCreate(S,J);try{L1(Q,M,X)}catch(K){console.error("[open-mem] Retention enforcement error:",K)}break}case"session.idle":{if($.processBatch().catch((K)=>{console.error("[open-mem] Background processing error:",K)}),S)f.updateStatus(S,"idle"),H1(S,J,Q,M).catch((K)=>{console.error("[open-mem] Folder context error:",K)});break}case"session.completed":case"session.ended":{if(S)await $.processBatch(),await $.summarizeSession(S),f.markCompleted(S),await H1(S,J,Q,M);break}default:break}}catch(Z){console.error("[open-mem] Event handler error:",Z)}}}async function H1($,f,J,Q){if(!J.folderContextEnabled)return;try{let M=Q.getBySession($);if(M.length>0)await G0(f,M,J.folderContextMaxDepth)}catch(M){console.error("[open-mem] Folder context update error:",M)}}function D1($,f,J,Q){return async(M,X)=>{try{let{tool:W,sessionID:Z,callID:N}=M,{output:S}=X;if($.ignoredTools.includes(W))return;if(!S||S.length<$.minOutputLength)return;let K=H0(S,$.sensitivePatterns);K=L0(K,"[PRIVATE]"),J.getOrCreate(Z,Q),f.enqueue(Z,W,K,N)}catch(W){console.error("[open-mem] Tool capture error:",W)}}}class J${config;compressor;summarizer;pendingRepo;observationRepo;sessionRepo;summaryRepo;embeddingModel;conflictEvaluator;entityExtractor;entityRepo;processing=!1;timer=null;mode="in-process";onEnqueue=null;constructor($,f,J,Q,M,X,W,Z=null,N=null,S=null,K=null){this.config=$;this.compressor=f;this.summarizer=J;this.pendingRepo=Q;this.observationRepo=M;this.sessionRepo=X;this.summaryRepo=W;this.embeddingModel=Z;this.conflictEvaluator=N;this.entityExtractor=S;this.entityRepo=K}setMode($){if(this.mode=$,$==="enqueue-only")this.stop()}getMode(){return this.mode}setOnEnqueue($){this.onEnqueue=$}enqueue($,f,J,Q){if(this.pendingRepo.create({sessionId:$,toolName:f,toolOutput:J,callId:Q}),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;try{this.pendingRepo.resetStale(5);let f=this.pendingRepo.getPending(this.config.batchSize);if(f.length===0)return 0;for(let J of f)try{this.pendingRepo.markProcessing(J.id);let M=await this.compressor.compress(J.toolName,J.toolOutput)??this.compressor.createFallbackObservation(J.toolName,J.toolOutput),X=!1,W=null;if(this.embeddingModel)try{let N=s0({title:M.title,narrative:M.narrative,concepts:M.concepts}),S=await q(this.embeddingModel,N);if(S){let K=this.config.conflictResolutionEnabled&&this.conflictEvaluator,V=this.config.conflictSimilarityBandLow??0.7,Y=this.config.conflictSimilarityBandHigh??0.92;if(K){let U=this.observationRepo.findSimilar(S,M.type,V,5),G=U.find((A)=>A.similarity>Y);if(G)console.log(`[open-mem] Dedup: skipping duplicate of ${G.id} (similarity: ${G.similarity.toFixed(3)})`),X=!0;else{let A=U.filter((B)=>B.similarity>=V&&B.similarity<=Y);if(A.length>0)try{let B=A.map((_)=>{let D=this.observationRepo.getById(_.id);return D?{id:D.id,title:D.title,narrative:D.narrative,concepts:D.concepts,type:D.type}:null}).filter((_)=>_!==null);if(B.length>0){let _=await this.conflictEvaluator.evaluate({title:M.title,narrative:M.narrative,concepts:M.concepts,type:M.type},B);if(_&&_.outcome==="duplicate")console.log(`[open-mem] Conflict eval: duplicate (${_.reason})`),X=!0;else if(_&&_.outcome==="update"&&_.supersedesId)console.log(`[open-mem] Conflict eval: update supersedes ${_.supersedesId} (${_.reason})`),W=_.supersedesId}}catch{}}}else{let U=this.observationRepo.findSimilar(S,M.type,0.92,1);if(U.length>0)console.log(`[open-mem] Dedup: skipping duplicate of ${U[0].id} (similarity: ${U[0].similarity.toFixed(3)})`),X=!0}}}catch{}if(X){this.pendingRepo.markCompleted(J.id);continue}let Z=this.observationRepo.create({sessionId:J.sessionId,type:M.type,title:M.title,subtitle:M.subtitle,facts:M.facts,narrative:M.narrative,concepts:M.concepts,filesRead:M.filesRead,filesModified:M.filesModified,rawToolOutput:J.toolOutput,toolName:J.toolName,tokenCount:L(`${M.title} ${M.narrative} ${M.facts.join(" ")}`),discoveryTokens:M.discoveryTokens??L(J.toolOutput),importance:M.importance??3});if(this.embeddingModel)try{let N=s0({title:Z.title,narrative:Z.narrative,concepts:Z.concepts}),S=await q(this.embeddingModel,N);if(S)this.observationRepo.setEmbedding(Z.id,S)}catch{}if(W)try{this.observationRepo.supersede(W,Z.id),console.log(`[open-mem] Superseded observation ${W} with ${Z.id}`)}catch(N){console.error(`[open-mem] Failed to supersede ${W}:`,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 S=new Map;for(let K of N.entities){let V=this.entityRepo.upsertEntity(K.name,K.entityType);S.set(K.name,V.id),this.entityRepo.linkObservation(V.id,Z.id)}for(let K of N.relations){let V=S.get(K.sourceName),Y=S.get(K.targetName);if(V&&Y)this.entityRepo.createRelation(V,Y,K.relationship,Z.id)}}}catch{}this.sessionRepo.incrementObservationCount(J.sessionId),this.pendingRepo.markCompleted(J.id),$++}catch(Q){this.pendingRepo.markFailed(J.id,String(Q))}return $}finally{this.processing=!1}}async summarizeSession($){let f=this.observationRepo.getBySession($);if(!this.summarizer.shouldSummarize(f.length))return;if(this.summaryRepo.getBySessionId($))return;let Q=await this.summarizer.summarize($,f);if(!Q)return;let M=this.summaryRepo.create({sessionId:$,summary:Q.summary,keyDecisions:Q.keyDecisions,filesModified:Q.filesModified,concepts:Q.concepts,tokenCount:L(Q.summary)});this.sessionRepo.setSummary($,M.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 C1($){return{start:()=>$.start(),stop:()=>{$.setOnEnqueue(null),$.stop()},setInProcess:()=>{$.setMode("in-process"),$.start()},setEnqueueOnly:(f)=>{$.setMode("enqueue-only"),$.setOnEnqueue(f)}}}function c($,f){if(f.type&&$.type!==f.type)return!1;if(f.importanceMin!==void 0&&$.importance<f.importanceMin)return!1;if(f.importanceMax!==void 0&&$.importance>f.importanceMax)return!1;if(f.createdAfter&&$.createdAt<f.createdAfter)return!1;if(f.createdBefore&&$.createdAt>f.createdBefore)return!1;if(f.concepts&&f.concepts.length>0){if(!f.concepts.some((Q)=>$.concepts.some((M)=>M.toLowerCase().includes(Q.toLowerCase()))))return!1}if(f.files&&f.files.length>0){let J=[...$.filesRead,...$.filesModified];if(!f.files.some((M)=>J.some((X)=>X.toLowerCase().includes(M.toLowerCase()))))return!1}return!0}async function j1($,f,J,Q,M){if(!$.trim())return f;let X=ef($),W=new Set;for(let S of X){let K=J.findByName(S);for(let V of K){let Y=J.traverseRelations(V.id,1);for(let U of Y){let G=J.getObservationsForEntity(U);for(let A of G)W.add(A)}}}if(W.size===0)return f;let Z=new Set(f.map((S)=>S.observation.id)),N=[];for(let S of W){if(Z.has(S))continue;let K=Q.getById(S);if(!K)continue;if(K.supersededBy)continue;N.push({observation:K,rank:0,snippet:K.title,source:"project"})}return[...f,...N].slice(0,M)}function ef($){let f=$.split(/\s+/).filter((Q)=>Q.length>=2),J=[];for(let Q of f)J.push(Q);for(let Q=0;Q<f.length-1;Q++)J.push(`${f[Q]} ${f[Q+1]}`);return J}var R1=60;async function k1($,f,J,Q){let M=Q.limit??10,X=$5(f,$,Q,M);if(!J)return X;let W=await q(J,$);if(!W)return X;let Z=X.map((S)=>S.observation.id),N=f5(f,W,Q.projectPath,Q,M,Q.hasVectorExtension??!1,Z);if(N.length===0)return X;return M5(X,N,M)}function $5($,f,J,Q){try{return $.search({query:f,type:J.type,limit:Q,projectPath:J.projectPath,importanceMin:J.importanceMin,importanceMax:J.importanceMax,createdAfter:J.createdAfter,createdBefore:J.createdBefore,concepts:J.concepts,files:J.files})}catch{return[]}}function f5($,f,J,Q,M,X,W){if(X)return J5($,f,Q,M,W);return Q5($,f,J,Q,M)}function J5($,f,J,Q,M){try{let X;if(M.length>0){if(X=$.searchVecSubset(f,M,Q*3),X.length===0)X=$.getVecEmbeddingMatches(f,Q*3)}else X=$.getVecEmbeddingMatches(f,Q*3);if(X.length===0)return[];let W=[];for(let{observationId:Z,distance:N}of X){if(W.length>=Q)break;let S=$.getById(Z);if(!S)continue;if(!c(S,J))continue;W.push({observation:S,rank:N-1,snippet:S.title})}return W}catch{return[]}}function Q5($,f,J,Q,M){let X=$.getWithEmbeddings(J,M*10);if(X.length===0)return[];let W=X.map((N)=>({id:N.id,similarity:l(f,N.embedding)})).filter(({similarity:N})=>N>=0.3).sort((N,S)=>S.similarity-N.similarity),Z=[];for(let{id:N,similarity:S}of W){if(Z.length>=M)break;let K=$.getById(N);if(!K)continue;if(!c(K,Q))continue;Z.push({observation:K,rank:-S,snippet:K.title})}return Z}function M5($,f,J){let Q=new Map;for(let M=0;M<$.length;M++){let X=$[M],W=1/(R1+M+1);Q.set(X.observation.id,{score:W,result:X})}for(let M=0;M<f.length;M++){let X=f[M],W=1/(R1+M+1),Z=Q.get(X.observation.id);if(Z)Z.score+=W;else Q.set(X.observation.id,{score:W,result:X})}return[...Q.values()].sort((M,X)=>X.score-M.score).slice(0,J).map(({result:M})=>M)}class Q${observations;embeddingModel;hasVectorExtension;reranker;userObservationRepo;entityRepo;constructor($,f,J,Q=null,M=null,X=null){this.observations=$;this.embeddingModel=f;this.hasVectorExtension=J;this.reranker=Q;this.userObservationRepo=M;this.entityRepo=X}async search($,f){let J=f.strategy??"hybrid",Q=f.limit??10,M;switch(J){case"filter-only":M=this.filterOnlySearch($,f,Q);break;case"semantic":M=await this.semanticSearch($,f,Q);break;case"hybrid":M=await this.hybridSearchStrategy($,f,Q);break}for(let X of M)X.source="project";if(this.entityRepo&&$.trim())M=await j1($,M,this.entityRepo,this.observations,Q);if(this.userObservationRepo){let X=this.searchUserMemory($,f,Q);M=this.mergeResults(M,X,Q)}if(this.reranker&&M.length>1)return this.reranker.rerank($,M,Q);return M}filterOnlySearch($,f,J){if(f.concept)return this.observations.searchByConcept(f.concept,J,f.projectPath).map((M)=>({observation:M,rank:0,snippet:M.title}));if(f.file)return this.observations.searchByFile(f.file,J,f.projectPath).map((M)=>({observation:M,rank:0,snippet:M.title}));return this.observations.search({query:$,type:f.type,limit:J,projectPath:f.projectPath,importanceMin:f.importanceMin,importanceMax:f.importanceMax,createdAfter:f.createdAfter,createdBefore:f.createdBefore,concepts:f.concepts,files:f.files})}async semanticSearch($,f,J){if(!this.embeddingModel)return this.filterOnlySearch($,f,J);let Q=await q(this.embeddingModel,$);if(!Q)return this.filterOnlySearch($,f,J);if(this.hasVectorExtension)return this.nativeVectorSearch(Q,f,J);return this.jsFallbackVectorSearch(Q,f,J)}async hybridSearchStrategy($,f,J){return k1($,this.observations,this.embeddingModel,{type:f.type,limit:J,projectPath:f.projectPath,hasVectorExtension:this.hasVectorExtension,importanceMin:f.importanceMin,importanceMax:f.importanceMax,createdAfter:f.createdAfter,createdBefore:f.createdBefore,concepts:f.concepts,files:f.files})}nativeVectorSearch($,f,J){try{let Q=this.observations.getVecEmbeddingMatches($,J*3);if(Q.length===0)return[];let M=[];for(let{observationId:X,distance:W}of Q){if(M.length>=J)break;let Z=this.observations.getById(X);if(!Z)continue;if(!c(Z,f))continue;M.push({observation:Z,rank:W-1,snippet:Z.title})}return M}catch{return[]}}jsFallbackVectorSearch($,f,J){let Q=this.observations.getWithEmbeddings(f.projectPath,J*10);if(Q.length===0)return[];let M=Q.map((W)=>({id:W.id,similarity:l($,W.embedding)})).filter(({similarity:W})=>W>=0.3).sort((W,Z)=>Z.similarity-W.similarity),X=[];for(let{id:W,similarity:Z}of M){if(X.length>=J)break;let N=this.observations.getById(W);if(!N)continue;if(!c(N,f))continue;X.push({observation:N,rank:-Z,snippet:N.title})}return X}searchUserMemory($,f,J){if(!this.userObservationRepo)return[];try{return this.userObservationRepo.search({query:$,limit:J}).map(({observation:M,rank:X})=>({observation:X5(M),rank:X,snippet:M.title,source:"user"}))}catch{return[]}}mergeResults($,f,J){let Q=new Set($.map((W)=>W.observation.id)),M=new Set($.map((W)=>`${W.observation.title}::${W.observation.narrative}`)),X=f.filter((W)=>{if(Q.has(W.observation.id))return!1;let Z=`${W.observation.title}::${W.observation.narrative}`;if(M.has(Z))return!1;return M.add(Z),!0});return[...$,...X].slice(0,J)}}function X5($){return{id:$.id,sessionId:"",type:$.type,title:$.title,subtitle:$.subtitle,facts:$.facts,narrative:$.narrative,concepts:$.concepts,filesRead:$.filesRead,filesModified:$.filesModified,rawToolOutput:"",toolName:$.toolName,createdAt:$.createdAt,tokenCount:$.tokenCount,discoveryTokens:0,importance:$.importance}}import{generateText as Z5}from"ai";class T1{languageModel;maxCandidates;provider;modelName;rateLimitingEnabled;_generate=Z5;constructor($,f){this.languageModel=$,this.maxCandidates=f.rerankingMaxCandidates,this.provider=f.provider??"",this.modelName=f.model??"",this.rateLimitingEnabled=f.rateLimitingEnabled??!0}async rerank($,f,J){if(f.length<=1)return f;let Q=f.slice(0,this.maxCandidates),M=f.slice(this.maxCandidates),X=c$($,Q.map((Z)=>({title:Z.observation.title,narrative:Z.observation.narrative}))),W=2;for(let Z=0;Z<=W;Z++)try{if(this.provider==="google")await T(this.modelName,this.rateLimitingEnabled);let{text:N}=await this._generate({model:this.languageModel,maxOutputTokens:512,prompt:X}),S=v$(N);if(!S)return f.slice(0,J);let K=this.applyReranking(Q,S,J);for(let V of M){if(K.length>=J)break;K.push(V)}return K}catch(N){if(W5(N)&&Z<W){await N5(2**Z*1000);continue}return f.slice(0,J)}return f.slice(0,J)}applyReranking($,f,J){let Q=[],M=new Set;for(let X of f)if(X>=0&&X<$.length&&!M.has(X)){if(M.add(X),Q.push($[X]),Q.length>=J)break}if(Q.length<J){for(let X=0;X<$.length&&Q.length<J;X++)if(!M.has(X))Q.push($[X])}return Q}}class I1{async rerank($,f,J){if(f.length<=1)return f.slice(0,J);let Q=M$($),M=f.map((X)=>({result:X,score:this.scoreCandidate(X,Q)}));return M.sort((X,W)=>W.score-X.score),M.slice(0,J).map((X)=>X.result)}scoreCandidate($,f){let J=$.observation,Q=M$(J.title),M=M$(J.narrative),X=new Set(J.concepts.map((_)=>_.toLowerCase())),W=0,Z=0,N=0;for(let _ of f){if(Q.has(_))W++;if(M.has(_))Z++;if(X.has(_))N++}let S=f.size||1,K=W/S*0.4,V=Z/S*0.3,Y=N/S*0.15,G=(Date.now()-new Date(J.createdAt).getTime())/86400000,A=G<1?0.1:G<7?0.05:0,B=J.importance/5*0.05;return K+V+Y+A+B}}function x1($,f){if(!$.rerankingEnabled)return null;if(f)return new T1(f,$);return new I1}function M$($){return new Set($.toLowerCase().split(/[\s\-_./\\,;:!?()[\]{}'"]+/).filter((f)=>f.length>1))}function W5($){if(typeof $!=="object"||$===null)return!1;let f=$,J=f.status;if(J===429||J===500||J===503)return!0;let Q=f.error;if(typeof Q==="object"&&Q!==null&&Q.type==="overloaded_error")return!0;return!1}function N5($){return new Promise((f)=>setTimeout(f,$))}import{normalize as w5,resolve as B$,sep as X2}from"path";import{fileURLToPath as q5}from"url";var X$=($,f,J)=>{return(Q,M)=>{let X=-1;return W(0);async function W(Z){if(Z<=X)throw Error("next() called multiple times");X=Z;let N,S=!1,K;if($[Z])K=$[Z][0][0],Q.req.routeIndex=Z;else K=Z===$.length&&M||void 0;if(K)try{N=await K(Q,()=>W(Z+1))}catch(V){if(V instanceof Error&&f)Q.error=V,N=await f(V,Q),S=!0;else throw V}else if(Q.finalized===!1&&J)N=await J(Q);if(N&&(Q.finalized===!1||S))Q.res=N;return Q}}};var P1=Symbol();var w1=async($,f=Object.create(null))=>{let{all:J=!1,dot:Q=!1}=f,X=($ instanceof O0?$.raw.headers:$.headers).get("Content-Type");if(X?.startsWith("multipart/form-data")||X?.startsWith("application/x-www-form-urlencoded"))return S5($,{all:J,dot:Q});return{}};async function S5($,f){let J=await $.formData();if(J)return K5(J,f);return{}}function K5($,f){let J=Object.create(null);if($.forEach((Q,M)=>{if(!(f.all||M.endsWith("[]")))J[M]=Q;else V5(J,M,Q)}),f.dot)Object.entries(J).forEach(([Q,M])=>{if(Q.includes("."))Y5(J,Q,M),delete J[Q]});return J}var V5=($,f,J)=>{if($[f]!==void 0)if(Array.isArray($[f]))$[f].push(J);else $[f]=[$[f],J];else if(!f.endsWith("[]"))$[f]=J;else $[f]=[J]},Y5=($,f,J)=>{let Q=$,M=f.split(".");M.forEach((X,W)=>{if(W===M.length-1)Q[X]=J;else{if(!Q[X]||typeof Q[X]!=="object"||Array.isArray(Q[X])||Q[X]instanceof File)Q[X]=Object.create(null);Q=Q[X]}})};var W$=($)=>{let f=$.split("/");if(f[0]==="")f.shift();return f},q1=($)=>{let{groups:f,path:J}=U5($),Q=W$(J);return A5(Q,f)},U5=($)=>{let f=[];return $=$.replace(/\{[^}]+\}/g,(J,Q)=>{let M=`@${Q}`;return f.push([M,J]),M}),{groups:f,path:$}},A5=($,f)=>{for(let J=f.length-1;J>=0;J--){let[Q]=f[J];for(let M=$.length-1;M>=0;M--)if($[M].includes(Q)){$[M]=$[M].replace(Q,f[J][1]);break}}return $},D0={},y1=($,f)=>{if($==="*")return"*";let J=$.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);if(J){let Q=`${$}#${f}`;if(!D0[Q])if(J[2])D0[Q]=f&&f[0]!==":"&&f[0]!=="*"?[Q,J[1],new RegExp(`^${J[2]}(?=/${f})`)]:[$,J[1],new RegExp(`^${J[2]}$`)];else D0[Q]=[$,J[1],!0];return D0[Q]}return null},C0=($,f)=>{try{return f($)}catch{return $.replace(/(?:%[0-9A-Fa-f]{2})+/g,(J)=>{try{return f(J)}catch{return J}})}},z5=($)=>C0($,decodeURI),N$=($)=>{let f=$.url,J=f.indexOf("/",f.indexOf(":")+4),Q=J;for(;Q<f.length;Q++){let M=f.charCodeAt(Q);if(M===37){let X=f.indexOf("?",Q),W=f.slice(J,X===-1?void 0:X);return z5(W.includes("%25")?W.replace(/%25/g,"%2525"):W)}else if(M===63)break}return f.slice(J,Q)};var v1=($)=>{let f=N$($);return f.length>1&&f.at(-1)==="/"?f.slice(0,-1):f},y=($,f,...J)=>{if(J.length)f=y(f,...J);return`${$?.[0]==="/"?"":"/"}${$}${f==="/"?"":`${$?.at(-1)==="/"?"":"/"}${f?.[0]==="/"?f.slice(1):f}`}`},j0=($)=>{if($.charCodeAt($.length-1)!==63||!$.includes(":"))return null;let f=$.split("/"),J=[],Q="";return f.forEach((M)=>{if(M!==""&&!/\:/.test(M))Q+="/"+M;else if(/\:/.test(M))if(/\?/.test(M)){if(J.length===0&&Q==="")J.push("/");else J.push(Q);let X=M.replace("?","");Q+="/"+X,J.push(Q)}else Q+="/"+M}),J.filter((M,X,W)=>W.indexOf(M)===X)},Z$=($)=>{if(!/[%+]/.test($))return $;if($.indexOf("+")!==-1)$=$.replace(/\+/g," ");return $.indexOf("%")!==-1?C0($,S$):$},g1=($,f,J)=>{let Q;if(!J&&f&&!/[%+]/.test(f)){let W=$.indexOf("?",8);if(W===-1)return;if(!$.startsWith(f,W+1))W=$.indexOf(`&${f}`,W+1);while(W!==-1){let Z=$.charCodeAt(W+f.length+1);if(Z===61){let N=W+f.length+2,S=$.indexOf("&",N);return Z$($.slice(N,S===-1?void 0:S))}else if(Z==38||isNaN(Z))return"";W=$.indexOf(`&${f}`,W+1)}if(Q=/[%+]/.test($),!Q)return}let M={};Q??=/[%+]/.test($);let X=$.indexOf("?",8);while(X!==-1){let W=$.indexOf("&",X+1),Z=$.indexOf("=",X);if(Z>W&&W!==-1)Z=-1;let N=$.slice(X+1,Z===-1?W===-1?void 0:W:Z);if(Q)N=Z$(N);if(X=W,N==="")continue;let S;if(Z===-1)S="";else if(S=$.slice(Z+1,W===-1?void 0:W),Q)S=Z$(S);if(J){if(!(M[N]&&Array.isArray(M[N])))M[N]=[];M[N].push(S)}else M[N]??=S}return f?M[f]:M},h1=g1,b1=($,f)=>{return g1($,f,!0)},S$=decodeURIComponent;var u1=($)=>C0($,S$),O0=class{raw;#$;#f;routeIndex=0;path;bodyCache={};constructor($,f="/",J=[[]]){this.raw=$,this.path=f,this.#f=J,this.#$={}}param($){return $?this.#J($):this.#X()}#J($){let f=this.#f[0][this.routeIndex][1][$],J=this.#M(f);return J&&/\%/.test(J)?u1(J):J}#X(){let $={},f=Object.keys(this.#f[0][this.routeIndex][1]);for(let J of f){let Q=this.#M(this.#f[0][this.routeIndex][1][J]);if(Q!==void 0)$[J]=/\%/.test(Q)?u1(Q):Q}return $}#M($){return this.#f[1]?this.#f[1][$]:$}query($){return h1(this.url,$)}queries($){return b1(this.url,$)}header($){if($)return this.raw.headers.get($)??void 0;let f={};return this.raw.headers.forEach((J,Q)=>{f[Q]=J}),f}async parseBody($){return this.bodyCache.parsedBody??=await w1(this,$)}#Q=($)=>{let{bodyCache:f,raw:J}=this,Q=f[$];if(Q)return Q;let M=Object.keys(f)[0];if(M)return f[M].then((X)=>{if(M==="json")X=JSON.stringify(X);return new Response(X)[$]()});return f[$]=J[$]()};json(){return this.#Q("text").then(($)=>JSON.parse($))}text(){return this.#Q("text")}arrayBuffer(){return this.#Q("arrayBuffer")}blob(){return this.#Q("blob")}formData(){return this.#Q("formData")}addValidatedData($,f){this.#$[$]=f}valid($){return this.#$[$]}get url(){return this.raw.url}get method(){return this.raw.method}get[P1](){return this.#f}get matchedRoutes(){return this.#f[0].map(([[,$]])=>$)}get routePath(){return this.#f[0].map(([[,$]])=>$)[this.routeIndex].path}};var R0={Stringify:1,BeforeStream:2,Stream:3},B5=($,f)=>{let J=new String($);return J.isEscaped=!0,J.callbacks=f,J};var t=async($,f,J,Q,M)=>{if(typeof $==="object"&&!($ instanceof String)){if(!($ instanceof Promise))$=$.toString();if($ instanceof Promise)$=await $}let X=$.callbacks;if(!X?.length)return Promise.resolve($);if(M)M[0]+=$;else M=[$];let W=Promise.all(X.map((Z)=>Z({phase:f,buffer:M,context:Q}))).then((Z)=>Promise.all(Z.filter(Boolean).map((N)=>t(N,f,!1,Q,M))).then(()=>M[0]));if(J)return B5(await W,X);else return W};var m1="text/plain; charset=UTF-8",K$=($,f)=>{return{"Content-Type":$,...f}},l1=class{#$;#f;env={};#J;finalized=!1;error;#X;#M;#Q;#K;#N;#S;#W;#V;#Y;constructor($,f){if(this.#$=$,f)this.#M=f.executionCtx,this.env=f.env,this.#S=f.notFoundHandler,this.#Y=f.path,this.#V=f.matchResult}get req(){return this.#f??=new O0(this.#$,this.#Y,this.#V),this.#f}get event(){if(this.#M&&"respondWith"in this.#M)return this.#M;else throw Error("This context has no FetchEvent")}get executionCtx(){if(this.#M)return this.#M;else throw Error("This context has no ExecutionContext")}get res(){return this.#Q||=new Response(null,{headers:this.#W??=new Headers})}set res($){if(this.#Q&&$){$=new Response($.body,$);for(let[f,J]of this.#Q.headers.entries()){if(f==="content-type")continue;if(f==="set-cookie"){let Q=this.#Q.headers.getSetCookie();$.headers.delete("set-cookie");for(let M of Q)$.headers.append("set-cookie",M)}else $.headers.set(f,J)}}this.#Q=$,this.finalized=!0}render=(...$)=>{return this.#N??=(f)=>this.html(f),this.#N(...$)};setLayout=($)=>this.#K=$;getLayout=()=>this.#K;setRenderer=($)=>{this.#N=$};header=($,f,J)=>{if(this.finalized)this.#Q=new Response(this.#Q.body,this.#Q);let Q=this.#Q?this.#Q.headers:this.#W??=new Headers;if(f===void 0)Q.delete($);else if(J?.append)Q.append($,f);else Q.set($,f)};status=($)=>{this.#X=$};set=($,f)=>{this.#J??=new Map,this.#J.set($,f)};get=($)=>{return this.#J?this.#J.get($):void 0};get var(){if(!this.#J)return{};return Object.fromEntries(this.#J)}#Z($,f,J){let Q=this.#Q?new Headers(this.#Q.headers):this.#W??new Headers;if(typeof f==="object"&&"headers"in f){let X=f.headers instanceof Headers?f.headers:new Headers(f.headers);for(let[W,Z]of X)if(W.toLowerCase()==="set-cookie")Q.append(W,Z);else Q.set(W,Z)}if(J)for(let[X,W]of Object.entries(J))if(typeof W==="string")Q.set(X,W);else{Q.delete(X);for(let Z of W)Q.append(X,Z)}let M=typeof f==="number"?f:f?.status??this.#X;return new Response($,{status:M,headers:Q})}newResponse=(...$)=>this.#Z(...$);body=($,f,J)=>this.#Z($,f,J);text=($,f,J)=>{return!this.#W&&!this.#X&&!f&&!J&&!this.finalized?new Response($):this.#Z($,f,K$(m1,J))};json=($,f,J)=>{return this.#Z(JSON.stringify($),f,K$("application/json",J))};html=($,f,J)=>{let Q=(M)=>this.#Z(M,f,K$("text/html; charset=UTF-8",J));return typeof $==="object"?t($,R0.Stringify,!1,{}).then(Q):Q($)};redirect=($,f)=>{let J=String($);return this.header("Location",!/[^\x00-\xFF]/.test(J)?J:encodeURI(J)),this.newResponse(null,f??302)};notFound=()=>{return this.#S??=()=>new Response,this.#S(this)}};var E="ALL",c1="all",p1=["get","post","put","delete","options","patch"],k0="Can not add a route since the matcher is already built.",T0=class extends Error{};var n1="__COMPOSED_HANDLER";var G5=($)=>{return $.text("404 Not Found",404)},d1=($,f)=>{if("getResponse"in $){let J=$.getResponse();return f.newResponse(J.body,J)}return console.error($),f.text("Internal Server Error",500)},i1=class ${get;post;put;delete;options;patch;all;on;use;router;getPath;_basePath="/";#$="/";routes=[];constructor(f={}){[...p1,c1].forEach((X)=>{this[X]=(W,...Z)=>{if(typeof W==="string")this.#$=W;else this.#X(X,this.#$,W);return Z.forEach((N)=>{this.#X(X,this.#$,N)}),this}}),this.on=(X,W,...Z)=>{for(let N of[W].flat()){this.#$=N;for(let S of[X].flat())Z.map((K)=>{this.#X(S.toUpperCase(),this.#$,K)})}return this},this.use=(X,...W)=>{if(typeof X==="string")this.#$=X;else this.#$="*",W.unshift(X);return W.forEach((Z)=>{this.#X(E,this.#$,Z)}),this};let{strict:Q,...M}=f;Object.assign(this,M),this.getPath=Q??!0?f.getPath??N$:v1}#f(){let f=new $({router:this.router,getPath:this.getPath});return f.errorHandler=this.errorHandler,f.#J=this.#J,f.routes=this.routes,f}#J=G5;errorHandler=d1;route(f,J){let Q=this.basePath(f);return J.routes.map((M)=>{let X;if(J.errorHandler===d1)X=M.handler;else X=async(W,Z)=>(await X$([],J.errorHandler)(W,()=>M.handler(W,Z))).res,X[n1]=M.handler;Q.#X(M.method,M.path,X)}),this}basePath(f){let J=this.#f();return J._basePath=y(this._basePath,f),J}onError=(f)=>{return this.errorHandler=f,this};notFound=(f)=>{return this.#J=f,this};mount(f,J,Q){let M,X;if(Q)if(typeof Q==="function")X=Q;else if(X=Q.optionHandler,Q.replaceRequest===!1)M=(N)=>N;else M=Q.replaceRequest;let W=X?(N)=>{let S=X(N);return Array.isArray(S)?S:[S]}:(N)=>{let S=void 0;try{S=N.executionCtx}catch{}return[N.env,S]};M||=(()=>{let N=y(this._basePath,f),S=N==="/"?0:N.length;return(K)=>{let V=new URL(K.url);return V.pathname=V.pathname.slice(S)||"/",new Request(V,K)}})();let Z=async(N,S)=>{let K=await J(M(N.req.raw),...W(N));if(K)return K;await S()};return this.#X(E,y(f,"*"),Z),this}#X(f,J,Q){f=f.toUpperCase(),J=y(this._basePath,J);let M={basePath:this._basePath,path:J,method:f,handler:Q};this.router.add(f,J,[Q,M]),this.routes.push(M)}#M(f,J){if(f instanceof Error)return this.errorHandler(f,J);throw f}#Q(f,J,Q,M){if(M==="HEAD")return(async()=>new Response(null,await this.#Q(f,J,Q,"GET")))();let X=this.getPath(f,{env:Q}),W=this.router.match(M,X),Z=new l1(f,{path:X,matchResult:W,env:Q,executionCtx:J,notFoundHandler:this.#J});if(W[0].length===1){let S;try{S=W[0][0][0][0](Z,async()=>{Z.res=await this.#J(Z)})}catch(K){return this.#M(K,Z)}return S instanceof Promise?S.then((K)=>K||(Z.finalized?Z.res:this.#J(Z))).catch((K)=>this.#M(K,Z)):S??this.#J(Z)}let N=X$(W[0],this.errorHandler,this.#J);return(async()=>{try{let S=await N(Z);if(!S.finalized)throw Error("Context is not finalized. Did you forget to return a Response object or `await next()`?");return S.res}catch(S){return this.#M(S,Z)}})()}fetch=(f,...J)=>{return this.#Q(f,J[1],J[0],f.method)};request=(f,J,Q,M)=>{if(f instanceof Request)return this.fetch(J?new Request(f,J):f,Q,M);return f=f.toString(),this.fetch(new Request(/^https?:\/\//.test(f)?f:`http://localhost${y("/",f)}`,J),Q,M)};fire=()=>{addEventListener("fetch",(f)=>{f.respondWith(this.#Q(f.request,f,void 0,f.request.method))})}};var e=[];function I0($,f){let J=this.buildAllMatchers(),Q=(M,X)=>{let W=J[M]||J[E],Z=W[2][X];if(Z)return Z;let N=X.match(W[0]);if(!N)return[[],e];let S=N.indexOf("",1);return[W[1][S],N]};return this.match=Q,Q($,f)}var x0="[^/]+",$0=".*",f0="(?:|/.*)",v=Symbol(),_5=new Set(".\\+*[^]$()");function F5($,f){if($.length===1)return f.length===1?$<f?-1:1:-1;if(f.length===1)return 1;if($===$0||$===f0)return 1;else if(f===$0||f===f0)return-1;if($===x0)return 1;else if(f===x0)return-1;return $.length===f.length?$<f?-1:1:f.length-$.length}var r1=class ${#$;#f;#J=Object.create(null);insert(f,J,Q,M,X){if(f.length===0){if(this.#$!==void 0)throw v;if(X)return;this.#$=J;return}let[W,...Z]=f,N=W==="*"?Z.length===0?["","",$0]:["","",x0]:W==="/*"?["","",f0]:W.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/),S;if(N){let K=N[1],V=N[2]||x0;if(K&&N[2]){if(V===".*")throw v;if(V=V.replace(/^\((?!\?:)(?=[^)]+\)$)/,"(?:"),/\((?!\?:)/.test(V))throw v}if(S=this.#J[V],!S){if(Object.keys(this.#J).some((Y)=>Y!==$0&&Y!==f0))throw v;if(X)return;if(S=this.#J[V]=new $,K!=="")S.#f=M.varIndex++}if(!X&&K!=="")Q.push([K,S.#f])}else if(S=this.#J[W],!S){if(Object.keys(this.#J).some((K)=>K.length>1&&K!==$0&&K!==f0))throw v;if(X)return;S=this.#J[W]=new $}S.insert(Z,J,Q,M,X)}buildRegExpStr(){let J=Object.keys(this.#J).sort(F5).map((Q)=>{let M=this.#J[Q];return(typeof M.#f==="number"?`(${Q})@${M.#f}`:_5.has(Q)?`\\${Q}`:Q)+M.buildRegExpStr()});if(typeof this.#$==="number")J.unshift(`#${this.#$}`);if(J.length===0)return"";if(J.length===1)return J[0];return"(?:"+J.join("|")+")"}};var s1=class{#$={varIndex:0};#f=new r1;insert($,f,J){let Q=[],M=[];for(let W=0;;){let Z=!1;if($=$.replace(/\{[^}]+\}/g,(N)=>{let S=`@\\${W}`;return M[W]=[S,N],W++,Z=!0,S}),!Z)break}let X=$.match(/(?::[^\/]+)|(?:\/\*$)|./g)||[];for(let W=M.length-1;W>=0;W--){let[Z]=M[W];for(let N=X.length-1;N>=0;N--)if(X[N].indexOf(Z)!==-1){X[N]=X[N].replace(Z,M[W][1]);break}}return this.#f.insert(X,f,Q,this.#$,J),Q}buildRegExp(){let $=this.#f.buildRegExpStr();if($==="")return[/^$/,[],[]];let f=0,J=[],Q=[];return $=$.replace(/#(\d+)|@(\d+)|\.\*\$/g,(M,X,W)=>{if(X!==void 0)return J[++f]=Number(X),"$()";if(W!==void 0)return Q[Number(W)]=++f,"";return""}),[new RegExp(`^${$}`),J,Q]}};var E5=[/^$/,[],Object.create(null)],a1=Object.create(null);function o1($){return a1[$]??=new RegExp($==="*"?"":`^${$.replace(/\/\*$|([.\\+*[^\]$()])/g,(f,J)=>J?`\\${J}`:"(?:|/.*)")}$`)}function L5(){a1=Object.create(null)}function H5($){let f=new s1,J=[];if($.length===0)return E5;let Q=$.map((S)=>[!/\*|\/:/.test(S[0]),...S]).sort(([S,K],[V,Y])=>S?1:V?-1:K.length-Y.length),M=Object.create(null);for(let S=0,K=-1,V=Q.length;S<V;S++){let[Y,U,G]=Q[S];if(Y)M[U]=[G.map(([B])=>[B,Object.create(null)]),e];else K++;let A;try{A=f.insert(U,K,Y)}catch(B){throw B===v?new T0(U):B}if(Y)continue;J[K]=G.map(([B,_])=>{let D=Object.create(null);_-=1;for(;_>=0;_--){let[x,H]=A[_];D[x]=H}return[B,D]})}let[X,W,Z]=f.buildRegExp();for(let S=0,K=J.length;S<K;S++)for(let V=0,Y=J[S].length;V<Y;V++){let U=J[S][V]?.[1];if(!U)continue;let G=Object.keys(U);for(let A=0,B=G.length;A<B;A++)U[G[A]]=Z[U[G[A]]]}let N=[];for(let S in W)N[S]=J[W[S]];return[X,N,M]}function p($,f){if(!$)return;for(let J of Object.keys($).sort((Q,M)=>M.length-Q.length))if(o1(J).test(f))return[...$[J]];return}var P0=class{name="RegExpRouter";#$;#f;constructor(){this.#$={[E]:Object.create(null)},this.#f={[E]:Object.create(null)}}add($,f,J){let Q=this.#$,M=this.#f;if(!Q||!M)throw Error(k0);if(!Q[$])[Q,M].forEach((Z)=>{Z[$]=Object.create(null),Object.keys(Z[E]).forEach((N)=>{Z[$][N]=[...Z[E][N]]})});if(f==="/*")f="*";let X=(f.match(/\/:/g)||[]).length;if(/\*$/.test(f)){let Z=o1(f);if($===E)Object.keys(Q).forEach((N)=>{Q[N][f]||=p(Q[N],f)||p(Q[E],f)||[]});else Q[$][f]||=p(Q[$],f)||p(Q[E],f)||[];Object.keys(Q).forEach((N)=>{if($===E||$===N)Object.keys(Q[N]).forEach((S)=>{Z.test(S)&&Q[N][S].push([J,X])})}),Object.keys(M).forEach((N)=>{if($===E||$===N)Object.keys(M[N]).forEach((S)=>Z.test(S)&&M[N][S].push([J,X]))});return}let W=j0(f)||[f];for(let Z=0,N=W.length;Z<N;Z++){let S=W[Z];Object.keys(M).forEach((K)=>{if($===E||$===K)M[K][S]||=[...p(Q[K],S)||p(Q[E],S)||[]],M[K][S].push([J,X-N+Z+1])})}}match=I0;buildAllMatchers(){let $=Object.create(null);return Object.keys(this.#f).concat(Object.keys(this.#$)).forEach((f)=>{$[f]||=this.#J(f)}),this.#$=this.#f=void 0,L5(),$}#J($){let f=[],J=$===E;if([this.#$,this.#f].forEach((Q)=>{let M=Q[$]?Object.keys(Q[$]).map((X)=>[X,Q[$][X]]):[];if(M.length!==0)J||=!0,f.push(...M);else if($!==E)f.push(...Object.keys(Q[E]).map((X)=>[X,Q[E][X]]))}),!J)return null;else return H5(f)}};var O5=class{name="PreparedRegExpRouter";#$;#f;constructor($,f){this.#$=$,this.#f=f}#J($,f){let J=this.#$[$];J[1].forEach((Q)=>Q&&Q.push(f)),Object.values(J[2]).forEach((Q)=>Q[0].push(f))}#X($,f,J,Q,M){let X=this.#$[$];if(!M)X[2][f][0].push([J,{}]);else Q.forEach((W)=>{if(typeof W==="number")X[1][W].push([J,M]);else X[2][W||f][0].push([J,M])})}add($,f,J){if(!this.#$[$]){let M=this.#$[E],X={};for(let W in M[2])X[W]=[M[2][W][0].slice(),e];this.#$[$]=[M[0],M[1].map((W)=>Array.isArray(W)?W.slice():0),X]}if(f==="/*"||f==="*"){let M=[J,{}];if($===E)for(let X in this.#$)this.#J(X,M);else this.#J($,M);return}let Q=this.#f[f];if(!Q)throw Error(`Path ${f} is not registered`);for(let[M,X]of Q)if($===E)for(let W in this.#$)this.#X(W,f,J,M,X);else this.#X($,f,J,M,X)}buildAllMatchers(){return this.#$}match=I0};var V$=class{name="SmartRouter";#$=[];#f=[];constructor($){this.#$=$.routers}add($,f,J){if(!this.#f)throw Error(k0);this.#f.push([$,f,J])}match($,f){if(!this.#f)throw Error("Fatal error");let J=this.#$,Q=this.#f,M=J.length,X=0,W;for(;X<M;X++){let Z=J[X];try{for(let N=0,S=Q.length;N<S;N++)Z.add(...Q[N]);W=Z.match($,f)}catch(N){if(N instanceof T0)continue;throw N}this.match=Z.match.bind(Z),this.#$=[Z],this.#f=void 0;break}if(X===M)throw Error("Fatal error");return this.name=`SmartRouter + ${this.activeRouter.name}`,W}get activeRouter(){if(this.#f||this.#$.length!==1)throw Error("No active router has been determined yet.");return this.#$[0]}};var J0=Object.create(null),t1=class ${#$;#f;#J;#X=0;#M=J0;constructor(f,J,Q){if(this.#f=Q||Object.create(null),this.#$=[],f&&J){let M=Object.create(null);M[f]={handler:J,possibleKeys:[],score:0},this.#$=[M]}this.#J=[]}insert(f,J,Q){this.#X=++this.#X;let M=this,X=q1(J),W=[];for(let Z=0,N=X.length;Z<N;Z++){let S=X[Z],K=X[Z+1],V=y1(S,K),Y=Array.isArray(V)?V[0]:S;if(Y in M.#f){if(M=M.#f[Y],V)W.push(V[1]);continue}if(M.#f[Y]=new $,V)M.#J.push(V),W.push(V[1]);M=M.#f[Y]}return M.#$.push({[f]:{handler:Q,possibleKeys:W.filter((Z,N,S)=>S.indexOf(Z)===N),score:this.#X}}),M}#Q(f,J,Q,M){let X=[];for(let W=0,Z=f.#$.length;W<Z;W++){let N=f.#$[W],S=N[J]||N[E],K={};if(S!==void 0){if(S.params=Object.create(null),X.push(S),Q!==J0||M&&M!==J0)for(let V=0,Y=S.possibleKeys.length;V<Y;V++){let U=S.possibleKeys[V],G=K[S.score];S.params[U]=M?.[U]&&!G?M[U]:Q[U]??M?.[U],K[S.score]=!0}}}return X}search(f,J){let Q=[];this.#M=J0;let X=[this],W=W$(J),Z=[];for(let N=0,S=W.length;N<S;N++){let K=W[N],V=N===S-1,Y=[];for(let U=0,G=X.length;U<G;U++){let A=X[U],B=A.#f[K];if(B)if(B.#M=A.#M,V){if(B.#f["*"])Q.push(...this.#Q(B.#f["*"],f,A.#M));Q.push(...this.#Q(B,f,A.#M))}else Y.push(B);for(let _=0,D=A.#J.length;_<D;_++){let x=A.#J[_],H=A.#M===J0?{}:{...A.#M};if(x==="*"){let O=A.#f["*"];if(O)Q.push(...this.#Q(O,f,A.#M)),O.#M=H,Y.push(O);continue}let[y0,M0,P]=x;if(!K&&!(P instanceof RegExp))continue;let C=A.#f[y0],j=W.slice(N).join("/");if(P instanceof RegExp){let O=P.exec(j);if(O){if(H[M0]=O[0],Q.push(...this.#Q(C,f,A.#M,H)),Object.keys(C.#f).length){C.#M=H;let d=O[0].match(/\//)?.length??0;(Z[d]||=[]).push(C)}continue}}if(P===!0||P.test(K))if(H[M0]=K,V){if(Q.push(...this.#Q(C,f,H,A.#M)),C.#f["*"])Q.push(...this.#Q(C.#f["*"],f,H,A.#M))}else C.#M=H,Y.push(C)}}X=Y.concat(Z.shift()??[])}if(Q.length>1)Q.sort((N,S)=>{return N.score-S.score});return[Q.map(({handler:N,params:S})=>[N,S])]}};var Y$=class{name="TrieRouter";#$;constructor(){this.#$=new t1}add($,f,J){let Q=j0(f);if(Q){for(let M=0,X=Q.length;M<X;M++)this.#$.insert($,Q[M],J);return}this.#$.insert($,f,J)}match($,f){return this.#$.search($,f)}};var U$=class extends i1{constructor($={}){super($);this.router=$.router??new V$({routers:[new P0,new Y$]})}};import{existsSync as D5}from"fs";import{mkdir as C5,readFile as j5,writeFile as R5}from"fs/promises";import{dirname as k5,join as T5}from"path";var e1=[{key:"dbPath",label:"Database Path",type:"string",group:"Storage",liveApply:!1,restartRequired:!0},{key:"provider",label:"Provider",type:"string",group:"AI",liveApply:!1,restartRequired:!0,enum:["google","anthropic","openai","bedrock"]},{key:"model",label:"Model",type:"string",group:"AI",liveApply:!1,restartRequired:!0},{key:"maxTokensPerCompression",label:"Max Tokens Per Compression",type:"number",group:"AI",liveApply:!0,restartRequired:!1,min:128,max:8192},{key:"compressionEnabled",label:"Compression Enabled",type:"boolean",group:"Behavior",liveApply:!0,restartRequired:!1},{key:"contextInjectionEnabled",label:"Context Injection Enabled",type:"boolean",group:"Behavior",liveApply:!0,restartRequired:!1},{key:"maxContextTokens",label:"Max Context Tokens",type:"number",group:"Behavior",liveApply:!0,restartRequired:!1,min:500,max:64000},{key:"batchSize",label:"Batch Size",type:"number",group:"Behavior",liveApply:!0,restartRequired:!1,min:1,max:100},{key:"batchIntervalMs",label:"Batch Interval (ms)",type:"number",group:"Behavior",liveApply:!0,restartRequired:!1,min:1000,max:300000},{key:"ignoredTools",label:"Ignored Tools",type:"array",group:"Filtering",liveApply:!0,restartRequired:!1},{key:"minOutputLength",label:"Min Output Length",type:"number",group:"Filtering",liveApply:!0,restartRequired:!1,min:0,max:1e4},{key:"maxObservations",label:"Max Observations",type:"number",group:"Progressive Disclosure",liveApply:!0,restartRequired:!1,min:1,max:200},{key:"contextFullObservationCount",label:"Full Observation Count",type:"number",group:"Progressive Disclosure",liveApply:!0,restartRequired:!1,min:0,max:20},{key:"contextShowTokenCosts",label:"Show Token Costs",type:"boolean",group:"Progressive Disclosure",liveApply:!0,restartRequired:!1},{key:"sensitivePatterns",label:"Sensitive Patterns",type:"array",group:"Privacy",liveApply:!0,restartRequired:!1},{key:"retentionDays",label:"Retention Days",type:"number",group:"Data Retention",liveApply:!1,restartRequired:!0,min:0,max:3650},{key:"maxDatabaseSizeMb",label:"Max Database Size (MB)",type:"number",group:"Data Retention",liveApply:!1,restartRequired:!0,min:0,max:1e5},{key:"dashboardEnabled",label:"Dashboard Enabled",type:"boolean",group:"Dashboard",liveApply:!1,restartRequired:!0},{key:"dashboardPort",label:"Dashboard Port",type:"number",group:"Dashboard",liveApply:!1,restartRequired:!0,min:1,max:65535},{key:"rerankingEnabled",label:"Reranking Enabled",type:"boolean",group:"Advanced",liveApply:!0,restartRequired:!1},{key:"entityExtractionEnabled",label:"Entity Extraction Enabled",type:"boolean",group:"Advanced",liveApply:!0,restartRequired:!1},{key:"userMemoryEnabled",label:"User Memory Enabled",type:"boolean",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"userMemoryMaxContextTokens",label:"User Memory Max Context Tokens",type:"number",group:"Advanced",liveApply:!0,restartRequired:!1,min:0,max:8000}],I5={dbPath:["OPEN_MEM_DB_PATH"],provider:["OPEN_MEM_PROVIDER"],model:["OPEN_MEM_MODEL"],compressionEnabled:["OPEN_MEM_COMPRESSION"],contextInjectionEnabled:["OPEN_MEM_CONTEXT_INJECTION"],maxContextTokens:["OPEN_MEM_MAX_CONTEXT_TOKENS"],ignoredTools:["OPEN_MEM_IGNORED_TOOLS"],batchSize:["OPEN_MEM_BATCH_SIZE"],retentionDays:["OPEN_MEM_RETENTION_DAYS"],contextShowTokenCosts:["OPEN_MEM_CONTEXT_SHOW_TOKEN_COSTS"],contextFullObservationCount:["OPEN_MEM_CONTEXT_FULL_COUNT"],maxObservations:["OPEN_MEM_MAX_OBSERVATIONS"],dashboardEnabled:["OPEN_MEM_DASHBOARD"],dashboardPort:["OPEN_MEM_DASHBOARD_PORT"],rerankingEnabled:["OPEN_MEM_RERANKING"],userMemoryEnabled:["OPEN_MEM_USER_MEMORY"]};function $2($){return T5($,".open-mem","config.json")}function f2($){return e1.find((f)=>f.key===$)}function x5($,f){let J=f2($);if(!J)return null;if(J.type==="string"&&typeof f!=="string")return`${String($)} must be a string`;if(J.type==="number"&&typeof f!=="number")return`${String($)} must be a number`;if(J.type==="boolean"&&typeof f!=="boolean")return`${String($)} must be a boolean`;if(J.type==="array"&&!Array.isArray(f))return`${String($)} must be an array`;if(J.enum&&typeof f==="string"&&!J.enum.includes(f))return`${String($)} must be one of: ${J.enum.join(", ")}`;if(typeof f==="number"){if(J.min!==void 0&&f<J.min)return`${String($)} must be >= ${J.min}`;if(J.max!==void 0&&f>J.max)return`${String($)} must be <= ${J.max}`}return null}function J2(){return e1}async function A$($){let f=$2($);if(!D5(f))return{};try{let J=await j5(f,"utf-8"),Q=JSON.parse(J);if(!Q||typeof Q!=="object"||Array.isArray(Q))return{};return Q}catch{return{}}}async function P5($,f){let J=$2($),M={...await A$($),...f};await C5(k5(J),{recursive:!0}),await R5(J,JSON.stringify(M,null,2),"utf-8")}function Q2($){let f=[];for(let[J,Q]of Object.entries($)){let X=x5(J,Q);if(X)f.push(X)}return f}async function n($){let f=S0(),J=await A$($),Q=b($),M=[],X={};for(let[W,Z]of Object.entries(f)){let N=W,S=f2(N),V=(I5[N]??[]).some((G)=>typeof process.env[G]==="string"),Y=Object.prototype.hasOwnProperty.call(J,N),U="default";if(Y)U="file";if(V)U="env";if(X[N]={source:U,locked:V,restartRequired:S?.restartRequired??!1,liveApply:S?.liveApply??!1},U==="env"&&Y)M.push(`${String(N)} is overridden by environment variable.`);if(Q[N]===void 0&&Z!==void 0)M.push(`${String(N)} resolved to undefined unexpectedly.`)}return{config:Q,meta:X,warnings:M}}async function M2($,f){let J=Q2(f);if(J.length>0)return{...await n($),warnings:J};let Q=S0(),M=await A$($),X={...Q,...M,...f},Z={...b($,f),...X},N=(await n($)).meta;return{config:Z,meta:N,warnings:[]}}async function z$($,f){let J=Q2(f);if(J.length>0)return{...await n($),warnings:J};return await P5($,f),n($)}var y5=new Set(["decision","bugfix","feature","refactor","discovery","change"]);function G$($,f,J=100){if(!$)return f;let Q=Number.parseInt($,10);if(Number.isNaN(Q))return f;return Math.max(1,Math.min(Q,J))}function v5($){if(!$)return 0;let f=Number.parseInt($,10);if(Number.isNaN(f))return 0;return Math.max(0,f)}function Z2($){if(!$)return;if(y5.has($))return $;return}function Q0($){let f={};for(let[J,Q]of Object.entries($)){let M=J.toLowerCase();if(typeof Q==="string"&&(M.includes("key")||M.includes("api")))f[J]="***REDACTED***";else f[J]=Q}return f}function _$($){let{config:f,projectPath:J,memoryEngine:Q,dashboardDir:M}=$,X=new U$;X.get("/api/observations",(Z)=>{let N=G$(Z.req.query("limit"),50),S=v5(Z.req.query("offset")),K=Z2(Z.req.query("type")),V=Z.req.query("sessionId"),Y=Q.listObservations({limit:N,offset:S,type:K,sessionId:V});return Z.json(Y)}),X.get("/api/observations/:id",(Z)=>{let N=Z.req.param("id"),S=Q.getObservation(N);if(!S)return Z.json({error:"Observation not found"},404);return Z.json(S)}),X.get("/api/sessions",(Z)=>{let N=G$(Z.req.query("limit"),20),S=Z.req.query("projectPath")||J;return Z.json(Q.listSessions({limit:N,projectPath:S}))}),X.get("/api/sessions/:id",(Z)=>{let N=Z.req.param("id"),S=Q.getSession(N);if(!S)return Z.json({error:"Session not found"},404);return Z.json({...S.session,observations:S.observations})}),X.get("/api/search",async(Z)=>{let N=Z.req.query("q");if(!N)return Z.json({error:"Query parameter 'q' is required"},400);let S=Z2(Z.req.query("type")),K=G$(Z.req.query("limit"),20);try{let V=await Q.search(N,{type:S,limit:K});return Z.json(V)}catch{return Z.json([],200)}}),X.get("/api/stats",(Z)=>{return Z.json(Q.stats())}),X.get("/api/config",(Z)=>{return Z.json(Q0(f))}),X.get("/api/config/schema",(Z)=>{return Z.json(J2())}),X.get("/api/config/effective",async(Z)=>{let N=await n(J);return Z.json({config:Q0(N.config),meta:N.meta,warnings:N.warnings})}),X.post("/api/config/preview",async(Z)=>{try{let N=await Z.req.json(),S=await M2(J,N);return Z.json({config:Q0(S.config),meta:S.meta,warnings:S.warnings})}catch{return Z.json({error:"Invalid JSON body"},400)}}),X.patch("/api/config",async(Z)=>{try{let N=await Z.req.json(),S=await z$(J,N);return Z.json({config:Q0(S.config),meta:S.meta,warnings:S.warnings})}catch{return Z.json({error:"Invalid JSON body"},400)}});let W={balanced:{minOutputLength:50,contextFullObservationCount:3,maxObservations:50,batchSize:5},focus:{minOutputLength:120,contextFullObservationCount:2,maxObservations:30,batchSize:3},chill:{minOutputLength:200,contextFullObservationCount:1,maxObservations:15,batchSize:2,compressionEnabled:!1}};if(X.get("/api/modes",(Z)=>{return Z.json({modes:Object.entries(W).map(([N,S])=>({id:N,patch:S}))})}),X.post("/api/modes/:id/apply",async(Z)=>{let N=Z.req.param("id"),S=W[N];if(!S)return Z.json({error:"Unknown mode"},404);let K=await z$(J,S);return Z.json({applied:N,config:Q0(K.config),meta:K.meta,warnings:K.warnings})}),X.post("/api/maintenance/folder-context/dry-run",async(Z)=>{let S=(await Z.req.json().catch(()=>({}))).action??"clean",K=await Q.maintainFolderContext(S,!0);return Z.json(K)}),X.post("/api/maintenance/folder-context/clean",async(Z)=>{let N=await Q.maintainFolderContext("clean",!1);return Z.json(N)}),X.post("/api/maintenance/folder-context/rebuild",async(Z)=>{let N=await Q.maintainFolderContext("rebuild",!1);return Z.json(N)}),$.sseHandler)X.get("/api/events",$.sseHandler);return X.get("*",async(Z)=>{let N=Z.req.path;if(N.startsWith("/api/"))return Z.json({error:"Not found"},404);let S=M??B$(q5(import.meta.url),"../../dist/dashboard"),K=w5(S),V=K.endsWith(X2)?K:K+X2,Y=N==="/"?"index.html":N.replace(/^\//,""),U=B$(S,Y);if(!U.startsWith(V))return Z.json({error:"Not found"},404);try{let A=Bun.file(U);if(await A.exists())return new Response(A)}catch(A){console.debug("[open-mem] Failed to serve static file:",A)}let G=B$(S,"index.html");if(!G.startsWith(V))return Z.json({error:"Not found"},404);try{let A=Bun.file(G);if(await A.exists())return new Response(A,{headers:{"Content-Type":"text/html; charset=utf-8"}})}catch(A){console.debug("[open-mem] Failed to serve dashboard index:",A)}return Z.json({error:"Dashboard not found. Run the dashboard build first."},404)}),X}var F$=class{writer;encoder;writable;abortSubscribers=[];responseReadable;aborted=!1;closed=!1;constructor($,f){this.writable=$,this.writer=$.getWriter(),this.encoder=new TextEncoder;let J=f.getReader();this.abortSubscribers.push(async()=>{await J.cancel()}),this.responseReadable=new ReadableStream({async pull(Q){let{done:M,value:X}=await J.read();M?Q.close():Q.enqueue(X)},cancel:()=>{this.abort()}})}async write($){try{if(typeof $==="string")$=this.encoder.encode($);await this.writer.write($)}catch{}return this}async writeln($){return await this.write($+`
667
- `),this}sleep($){return new Promise((f)=>setTimeout(f,$))}async close(){try{await this.writer.close()}catch{}this.closed=!0}async pipe($){this.writer.releaseLock(),await $.pipeTo(this.writable,{preventClose:!0}),this.writer=this.writable.getWriter()}onAbort($){this.abortSubscribers.push($)}abort(){if(!this.aborted)this.aborted=!0,this.abortSubscribers.forEach(($)=>$())}};var w0=()=>{let $=typeof Bun<"u"?Bun.version:void 0;if($===void 0)return!1;let f=$.startsWith("1.1")||$.startsWith("1.0")||$.startsWith("0.");return w0=()=>f,f};var W2=class extends F${constructor($,f){super($,f)}async writeSSE($){let J=(await t($.data,R0.Stringify,!1,{})).split(/\r\n|\r|\n/).map((M)=>{return`data: ${M}`}).join(`
668
- `),Q=[$.event&&`event: ${$.event}`,J,$.id&&`id: ${$.id}`,$.retry&&`retry: ${$.retry}`].filter(Boolean).join(`
669
- `)+`
665
+ `,A=[f.query];if(f.sourceProject)n+=" AND o.source_project = ?",A.push(f.sourceProject);return n+=" ORDER BY rank LIMIT ?",A.push(f.limit??10),this.db.all(n,A).map((E)=>({observation:this.mapRow(E),rank:E.rank}))}catch{return[]}}getIndex(f,n){let A=`SELECT id, type, title, token_count, created_at, importance, source_project
666
+ FROM user_observations`,E=[];if(n)A+=" WHERE source_project = ?",E.push(n);return A+=" ORDER BY created_at DESC LIMIT ?",E.push(f??20),this.db.all(A,E).map((N)=>({id:N.id,sessionId:"",type:N.type,title:N.title,tokenCount:N.token_count,discoveryTokens:0,createdAt:N.created_at,importance:N.importance??3}))}getById(f){let n=this.db.get("SELECT * FROM user_observations WHERE id = ?",[f]);return n?this.mapRow(n):null}delete(f){return this.db.all("DELETE FROM user_observations WHERE id = ? RETURNING id",[f]).length>0}mapRow(f){return{id:f.id,type:f.type,title:f.title,subtitle:f.subtitle,facts:JSON.parse(f.facts),narrative:f.narrative,concepts:JSON.parse(f.concepts),filesRead:JSON.parse(f.files_read),filesModified:JSON.parse(f.files_modified),toolName:f.tool_name,createdAt:f.created_at,tokenCount:f.token_count,importance:f.importance??3,sourceProject:f.source_project}}}function dE(f){if(f.startsWith("~/")){let n=process.env.HOME||process.env.USERPROFILE||"";if(!n)throw Error("Cannot resolve user DB path: HOME environment variable is not set");let A=`${n}${f.slice(1)}`,E=A.substring(0,A.lastIndexOf("/"));return v("fs").mkdirSync(E,{recursive:!0}),A}return f}import{EventEmitter as eE}from"events";function RA(){return new eE}function bf(f,n=""){if(!f)return f;return f.replace(/<private>[\s\S]*?<\/private>/gi,n)}var DA=200,fN=/(\([\s\S]*[+*]\)\s*[+*?])|(\(\.\*\)\+)|(\(\.\+\)\+)/;function tf(f,n,A="[REDACTED]"){if(!f||n.length===0)return f;let E=f;for(let N of n){if(N.length>DA){console.warn(`[open-mem] Skipping oversized redaction pattern (${N.length} chars, max ${DA})`);continue}if(fN.test(N)){console.warn("[open-mem] Skipping potentially dangerous redaction pattern (nested quantifiers detected)");continue}try{E=E.replace(new RegExp(N,"g"),A)}catch{}}return E}var nN=20,lA=2000,uA=60;function AN(f){return typeof f==="object"&&f!==null&&"text"in f&&typeof f.text==="string"}function EN(f){let n=[];for(let A of f)if(typeof A==="string")n.push(A);else if(AN(A))n.push(A.text);return n.join(`
667
+ `).trim()}function NN(f){let n=f.toLowerCase().replace(/[^a-z0-9\s-]/g," ").split(/\s+/).filter((A)=>A.length>4);return[...new Set(n)].slice(0,5)}function x0(f){let{observations:n,sessions:A,projectPath:E,sessionId:N,text:O,agent:S,sensitivePatterns:M=[]}=f;if(S!==void 0&&S!=="user")return!1;let _=tf(bf(O),M);if(_.length<nN)return!1;A.getOrCreate(N,E);let R=`User request: ${_.length>uA?`${_.slice(0,uA)}...`:_}`,D=_.length>lA?`${_.slice(0,lA)}...`:_;return n.create({sessionId:N,type:"discovery",title:R,subtitle:"",facts:[],narrative:D,concepts:NN(_),filesRead:[],filesModified:[],rawToolOutput:"",toolName:"chat.message",tokenCount:Math.ceil(D.length/4),discoveryTokens:0,importance:3}),!0}function yA(f,n,A,E=[]){return async(N,O)=>{try{let{sessionID:S,agent:M}=N;if(M!==void 0&&M!=="user")return;let _=EN(O.parts);x0({observations:f,sessions:n,projectPath:A,sessionId:S,text:_,agent:M,sensitivePatterns:E})}catch(S){console.error("[open-mem] Chat capture error:",S)}}}function CA(f,n,A,E,N,O){return async(S,M)=>{try{if(!f.contextInjectionEnabled)return;let _=A.getRecent(N,3),$=_.map((u)=>u.summaryId?E.getBySessionId(u.id):null).filter((u)=>u!==null),R=n.getIndex(N,10);if($.length===0&&R.length===0)return;let D=ff(_,$,R,Math.floor(f.maxContextTokens/2)),l=Tf(D);if(f.userMemoryEnabled&&O){let u=O.getIndex(10),Q=kf(u,Math.floor(f.userMemoryMaxContextTokens/2));if(Q)l+=Q}M.context.push(l)}catch(_){console.error("[open-mem] Compaction hook error:",_)}}}function VA(f,n,A,E,N,O){return async(S,M)=>{try{if(!f.contextInjectionEnabled)return;let _=A.getRecent(N,5);if(_.length===0)return;let $=_.map((J)=>J.summaryId?E.getBySessionId(J.id):null).filter((J)=>J!==null),R=n.getIndex(N,f.maxObservations);if($.length===0&&R.length===0)return;let l=R.slice(0,f.contextFullObservationCount).map((J)=>J.id).map((J)=>n.getById(J)).filter((J)=>J!==null),u=ff(_,$,R,f.maxContextTokens,l),Q={showTokenCosts:f.contextShowTokenCosts,observationTypes:f.contextObservationTypes,fullObservationCount:f.contextFullObservationCount,showLastSummary:f.contextShowLastSummary},V=gf(u,Q);if(f.userMemoryEnabled&&O){let J=O.getIndex(f.maxObservations),W=Pf(J,f.userMemoryMaxContextTokens);if(W)V+=`
670
668
 
671
- `;await this.write(Q)}},g5=async($,f,J)=>{try{await f($)}catch(Q){if(Q instanceof Error&&J)await J(Q,$),await $.writeSSE({event:"error",data:Q.message});else console.error(Q)}finally{$.close()}},h5=new WeakMap,E$=($,f,J)=>{let{readable:Q,writable:M}=new TransformStream,X=new W2(M,Q);if(w0())$.req.raw.signal.addEventListener("abort",()=>{if(!X.closed)X.abort()});return h5.set(X.responseReadable,$),$.header("Transfer-Encoding","chunked"),$.header("Content-Type","text/event-stream"),$.header("Cache-Control","no-cache"),$.header("Connection","keep-alive"),g5(X,f,J),$.newResponse(X.responseReadable)};class q0{eventBus;clients=new Set;cleanups=[];constructor($){this.eventBus=$;this.subscribeToAll()}addClient($){this.clients.add($)}removeClient($){this.clients.delete($)}get clientCount(){return this.clients.size}destroy(){for(let $ of this.cleanups)$();this.cleanups=[],this.clients.clear()}subscribeToAll(){let $=["observation:created","observation:updated","session:started","session:ended","summary:created","pending:enqueued","pending:processed"];for(let f of $){let J=(Q)=>{this.broadcast(f,Q)};this.eventBus.on(f,J),this.cleanups.push(()=>{this.eventBus.off(f,J)})}}broadcast($,f){let J=JSON.stringify(f);for(let Q of this.clients)try{let M=Q($,J);if(M&&typeof M.catch==="function")M.catch(()=>this.clients.delete(Q))}catch{this.clients.delete(Q)}}}var u5=30000;function L$($){return(f)=>{return E$(f,async(J)=>{let Q=(X,W)=>{J.writeSSE({event:X,data:W,id:Date.now().toString()})};$.addClient(Q);let M=setInterval(()=>{J.writeSSE({event:"heartbeat",data:"",id:Date.now().toString()})},u5);J.onAbort(()=>{$.removeClient(Q),clearInterval(M)});while(!J.aborted)await J.sleep(1000)})}}function N2($){return $}function S2($){return $}function K2($){return $}function V2($){if(!$)return null;return $}import{spawnSync as Y2}from"child_process";import{dirname as m5,resolve as U2}from"path";function l5($){try{let f=Y2("git",["rev-parse","--git-common-dir"],{cwd:$,encoding:"utf-8",timeout:5000});if(f.status!==0||!f.stdout)return null;let J=f.stdout.trim();if(J===".git")return null;let Q=Y2("git",["rev-parse","--git-dir"],{cwd:$,encoding:"utf-8",timeout:5000});if(Q.status!==0||!Q.stdout)return null;let M=Q.stdout.trim(),X=U2($,J),W=U2($,M);if(X===W)return null;let Z=m5(X);if(Z===X||Z==="/")return null;return Z}catch{return null}}function A2($){return l5($)??$}function d5(){try{let f=import.meta.url;if(f&&!f.includes("[eval]")){let J=p5(n5(f));return J.endsWith("dist")||J.endsWith("dist/")||J.endsWith("dist\\")?J:g(J,"..","dist")}}catch{}let $=[g(process.env.HOME||"",".config","opencode","node_modules","open-mem","dist"),g(process.cwd(),"node_modules","open-mem","dist")];for(let f of $)if(c5(g(f,"daemon.js")))return f;return g(process.cwd(),"node_modules","open-mem","dist")}async function i5($){let f=d5(),J=A2($.directory),Q=b(J),M=r$(Q);for(let h of M)console.warn(`[open-mem] ${h}`);await s$(Q),F0.enableExtensionSupport();let X=E0(Q.dbPath);U1(X,{hasVectorExtension:X.hasVectorExtension,embeddingDimension:Q.embeddingDimension});let W=new t0(X),Z=new a0(X),N=new e0(X),S=new o0(X),K=null,V=null;if(Q.userMemoryEnabled)try{K=new $$(Q.userMemoryDbPath),V=new f$(K.database)}catch(h){console.warn(`[open-mem] Failed to initialize user-level memory: ${h}`)}let Y=new r(Q),U=new b0(Q),G=Q.provider!=="bedrock",A=Q.compressionEnabled&&(!G||Q.apiKey)?p$({provider:Q.provider,model:Q.model,apiKey:Q.apiKey}):null,B=Q.conflictResolutionEnabled&&(!G||Q.apiKey)?new g0({provider:Q.provider,apiKey:Q.apiKey,model:Q.model,rateLimitingEnabled:Q.rateLimitingEnabled}):null,_=Q.entityExtractionEnabled&&(!G||Q.apiKey)?new h0({provider:Q.provider,apiKey:Q.apiKey,model:Q.model,rateLimitingEnabled:Q.rateLimitingEnabled}):null,D=new r0(X),x=new J$(Q,Y,U,S,Z,W,N,A,B,_,D),H=C1(x);H.start();let y0=x1(Q,Q.rerankingEnabled&&(!G||Q.apiKey)?k({provider:Q.provider,model:Q.model,apiKey:Q.apiKey}):null),M0=new Q$(Z,A,X.hasVectorExtension,y0,V,D),P=new c0({observations:N2(Z),sessions:S2(W),summaries:K2(N),searchOrchestrator:M0,projectPath:J,config:Q,userObservationRepo:V2(V)}),C=w$(P),j=null,O=null;if(Q.daemonEnabled)if(N1(Q.dbPath),j=new n0({dbPath:Q.dbPath,projectPath:J,daemonScript:g(f,"daemon.js")}),j.start())H.setEnqueueOnly(()=>j?.signal("PROCESS_NOW")),console.log("[open-mem] Background daemon started \u2014 processing delegated"),O=setInterval(()=>{if(j&&!j.isRunning()){if(console.warn("[open-mem] Daemon died, falling back to in-process processing"),H.setInProcess(),O)clearInterval(O),O=null}},30000);else console.warn("[open-mem] Daemon failed to start \u2014 using in-process processing"),j=null;let d=null,X0=null,Z0=null;if(Q.dashboardEnabled){X0=A1(),Z0=new q0(X0);let h=_$({config:Q,projectPath:J,embeddingModel:A,memoryEngine:P,sseHandler:L$(Z0),dashboardDir:g(f,"dashboard")}),W0=Q.dashboardPort,v0=W0,H$=!1;for(let i=0;i<10;i++){v0=W0+i;try{d=Bun.serve({port:v0,hostname:"127.0.0.1",fetch:h.fetch}),H$=!0;break}catch{}}if(H$)console.log(`[open-mem] Dashboard available at http://127.0.0.1:${v0}`);else console.warn(`[open-mem] Could not start dashboard \u2014 ports ${W0}-${W0+9} all busy`);let B2=X0,G2=Z.create.bind(Z);Z.create=(...i)=>{let O$=G2(...i);return B2.emit("observation:created",O$),O$}}let z2=()=>{if(O)clearInterval(O);if(j)j.stop();if(H.stop(),d)d.stop();if(Z0)Z0.destroy();if(K)K.close();X.close()};return process.on("beforeExit",z2),{"tool.execute.after":D1(Q,x,W,J),"chat.message":_1(Z,W,J,Q.sensitivePatterns),event:O1(x,W,J,Q,Z,S),"experimental.chat.system.transform":E1(Q,Z,W,N,J,V),"experimental.session.compacting":F1(Q,Z,W,N,J,V),tool:{...C}}}export{b as resolveConfig,S0 as getDefaultConfig,i5 as default};
669
+ ${W}`}M.system.push(V)}catch(_){console.error("[open-mem] Context injection error:",_)}}}function BA(f,n,A){if(f.retentionDays===0)return;try{let E=n.deleteOlderThan(f.retentionDays),N=A.deleteCompletedOlderThan(f.retentionDays);if(E>0||N>0)console.log(`[open-mem] Retention: deleted ${E} observations, ${N} pending messages`)}catch(E){console.error("[open-mem] Retention enforcement error:",E)}}async function Cf(f,n,A){let{queue:E,sessions:N,projectPath:O,config:S,observations:M,pendingMessages:_}=f;switch(n){case"session.created":{if(A)N.getOrCreate(A,O);try{BA(S,M,_)}catch($){console.error("[open-mem] Retention enforcement error:",$)}break}case"session.idle":{if(E.processBatch().catch(($)=>{console.error("[open-mem] Background processing error:",$)}),A)N.updateStatus(A,"idle"),JA(A,O,S,M).catch(($)=>{console.error("[open-mem] Folder context error:",$)});break}case"session.completed":case"session.ended":{if(A)await E.processBatch(),await E.summarizeSession(A),N.markCompleted(A),await JA(A,O,S,M);break}}}function QA(f,n,A,E,N,O){return async(S)=>{try{let{event:M}=S,_=M.properties.sessionID,$=typeof _==="string"?_:void 0;if(M.type==="session.created"||M.type==="session.idle"||M.type==="session.completed"||M.type==="session.ended")await Cf({queue:f,sessions:n,projectPath:A,config:E,observations:N,pendingMessages:O},M.type,$)}catch(M){console.error("[open-mem] Event handler error:",M)}}}async function JA(f,n,A,E){if(!A.folderContextEnabled)return;try{let N=E.getBySession(f);if(N.length>0)await vf(n,N,A.folderContextMaxDepth)}catch(N){console.error("[open-mem] Folder context update error:",N)}}function v0(f){let{config:n,queue:A,sessions:E,projectPath:N,tool:O,sessionId:S,callId:M,toolOutput:_}=f;if(n.ignoredTools.includes(O))return!1;if(!_||_.length<n.minOutputLength)return!1;let $=tf(_,n.sensitivePatterns);return $=bf($,"[PRIVATE]"),E.getOrCreate(S,N),A.enqueue(S,O,$,M),!0}function LA(f,n,A,E){return async(N,O)=>{try{let{tool:S,sessionID:M,callID:_}=N,{output:$}=O;v0({config:f,queue:n,sessions:A,projectPath:E,tool:S,sessionId:M,callId:_,toolOutput:$})}catch(S){console.error("[open-mem] Tool capture error:",S)}}}class q0{config;compressor;summarizer;pendingRepo;observationRepo;sessionRepo;summaryRepo;embeddingModel;conflictEvaluator;entityExtractor;entityRepo;observer;processing=!1;timer=null;mode="in-process";onEnqueue=null;constructor(f,n,A,E,N,O,S,M=null,_=null,$=null,R=null,D=null){this.config=f;this.compressor=n;this.summarizer=A;this.pendingRepo=E;this.observationRepo=N;this.sessionRepo=O;this.summaryRepo=S;this.embeddingModel=M;this.conflictEvaluator=_;this.entityExtractor=$;this.entityRepo=R;this.observer=D}setMode(f){if(this.mode=f,f==="enqueue-only")this.stop()}getMode(){return this.mode}setOnEnqueue(f){this.onEnqueue=f}enqueue(f,n,A,E){if(this.pendingRepo.create({sessionId:f,toolName:n,toolOutput:A,callId:E}),this.observer?.onEnqueue?.({sessionId:f,toolName:n,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 f=0,n=0,A=Date.now();try{this.pendingRepo.resetStale(5);let E=this.pendingRepo.getPending(this.config.batchSize);if(this.observer?.onBatchStart?.({pending:E.length,mode:this.mode,startedAt:new Date(A).toISOString()}),E.length===0)return 0;for(let N of E)try{this.pendingRepo.markProcessing(N.id);let S=await this.compressor.compress(N.toolName,N.toolOutput)??this.compressor.createFallbackObservation(N.toolName,N.toolOutput),M=!1,_=null;if(this.embeddingModel)try{let R=H0({title:S.title,narrative:S.narrative,concepts:S.concepts}),D=await t(this.embeddingModel,R);if(D){let l=this.config.conflictResolutionEnabled&&this.conflictEvaluator,u=this.config.conflictSimilarityBandLow??0.7,Q=this.config.conflictSimilarityBandHigh??0.92;if(l){let V=this.observationRepo.findSimilar(D,S.type,u,5),J=V.find((W)=>W.similarity>Q);if(J)console.log(`[open-mem] Dedup: skipping duplicate of ${J.id} (similarity: ${J.similarity.toFixed(3)})`),M=!0;else{let W=V.filter((F)=>F.similarity>=u&&F.similarity<=Q);if(W.length>0)try{let F=W.map((K)=>{let U=this.observationRepo.getById(K.id);return U?{id:U.id,title:U.title,narrative:U.narrative,concepts:U.concepts,type:U.type}:null}).filter((K)=>K!==null);if(F.length>0&&this.conflictEvaluator){let K=await this.conflictEvaluator.evaluate({title:S.title,narrative:S.narrative,concepts:S.concepts,type:S.type},F);if(K&&K.outcome==="duplicate")console.log(`[open-mem] Conflict eval: duplicate (${K.reason})`),M=!0;else if(K&&K.outcome==="update"&&K.supersedesId)console.log(`[open-mem] Conflict eval: update supersedes ${K.supersedesId} (${K.reason})`),_=K.supersedesId}}catch{}}}else{let V=this.observationRepo.findSimilar(D,S.type,0.92,1);if(V.length>0)console.log(`[open-mem] Dedup: skipping duplicate of ${V[0].id} (similarity: ${V[0].similarity.toFixed(3)})`),M=!0}}}catch{}if(M){this.pendingRepo.markCompleted(N.id);continue}let $=this.observationRepo.create({sessionId:N.sessionId,type:S.type,title:S.title,subtitle:S.subtitle,facts:S.facts,narrative:S.narrative,concepts:S.concepts,filesRead:S.filesRead,filesModified:S.filesModified,rawToolOutput:N.toolOutput,toolName:N.toolName,tokenCount:Y(`${S.title} ${S.narrative} ${S.facts.join(" ")}`),discoveryTokens:S.discoveryTokens??Y(N.toolOutput),importance:S.importance??3});if(this.embeddingModel)try{let R=H0({title:$.title,narrative:$.narrative,concepts:$.concepts}),D=await t(this.embeddingModel,R);if(D)this.observationRepo.setEmbedding($.id,D)}catch{}if(_)try{this.observationRepo.supersede(_,$.id),console.log(`[open-mem] Superseded observation ${_} with ${$.id}`)}catch(R){console.error(`[open-mem] Failed to supersede ${_}:`,R)}if(this.config.entityExtractionEnabled&&this.entityExtractor&&this.entityRepo)try{let R=await this.entityExtractor.extract({title:$.title,narrative:$.narrative,concepts:$.concepts,facts:$.facts,filesRead:$.filesRead,filesModified:$.filesModified,type:$.type});if(R){let D=new Map;for(let l of R.entities){let u=this.entityRepo.upsertEntity(l.name,l.entityType);D.set(l.name,u.id),this.entityRepo.linkObservation(u.id,$.id)}for(let l of R.relations){let u=D.get(l.sourceName),Q=D.get(l.targetName);if(u&&Q)this.entityRepo.createRelation(u,Q,l.relationship,$.id)}}}catch{}this.sessionRepo.incrementObservationCount(N.sessionId),this.pendingRepo.markCompleted(N.id),f++}catch(O){this.pendingRepo.markFailed(N.id,String(O)),n++,this.observer?.onItemFailed?.({pendingId:N.id,error:String(O),failedAt:new Date().toISOString()})}return f}finally{this.observer?.onBatchEnd?.({processed:f,failed:n,durationMs:Date.now()-A,finishedAt:new Date().toISOString()}),this.processing=!1}}async summarizeSession(f){let n=this.observationRepo.getBySession(f);if(!this.summarizer.shouldSummarize(n.length))return;if(this.summaryRepo.getBySessionId(f))return;let E=await this.summarizer.summarize(f,n);if(!E)return;let N=this.summaryRepo.create({sessionId:f,summary:E.summary,keyDecisions:E.keyDecisions,filesModified:E.filesModified,concepts:E.concepts,tokenCount:Y(E.summary)});this.sessionRepo.setSummary(f,N.id)}start(){if(this.mode==="enqueue-only")return;if(this.timer)return;this.timer=setInterval(async()=>{try{await this.processBatch()}catch{}},this.config.batchIntervalMs)}stop(){if(this.timer)clearInterval(this.timer),this.timer=null}get isRunning(){return this.timer!==null}get isProcessing(){return this.processing}getStats(){return{pending:this.pendingRepo.getPending(1000).length,processing:this.processing}}}class r0{startedAtMs=Date.now();enqueueCount=0;totalBatches=0;processedItems=0;failedItems=0;totalBatchDurationMs=0;lastBatchDurationMs=0;lastProcessedAt=null;lastFailedAt=null;lastError=null;createQueueObserver(){return{onEnqueue:()=>{this.enqueueCount+=1},onBatchEnd:(f)=>{if(this.totalBatches+=1,this.processedItems+=f.processed,this.failedItems+=f.failed,this.totalBatchDurationMs+=f.durationMs,this.lastBatchDurationMs=f.durationMs,f.processed>0)this.lastProcessedAt=f.finishedAt},onItemFailed:(f)=>{this.lastFailedAt=f.failedAt,this.lastError=f.error}}}snapshot(f){return{startedAt:new Date(this.startedAtMs).toISOString(),uptimeMs:Date.now()-this.startedAtMs,enqueueCount:this.enqueueCount,batches:{total:this.totalBatches,processedItems:this.processedItems,failedItems:this.failedItems,avgDurationMs:this.totalBatches>0?Math.round(this.totalBatchDurationMs/this.totalBatches):0},queue:{...f,lastBatchDurationMs:this.lastBatchDurationMs,lastProcessedAt:this.lastProcessedAt,lastFailedAt:this.lastFailedAt,lastError:this.lastError}}}}function zA(f){return{start:()=>f.start(),stop:()=>{f.setOnEnqueue(null),f.stop()},setInProcess:()=>{f.setMode("in-process"),f.start()},setEnqueueOnly:(n)=>{f.setMode("enqueue-only"),f.setOnEnqueue(n)}}}function Ef(f,n){if(n.type&&f.type!==n.type)return!1;if(n.importanceMin!==void 0&&f.importance<n.importanceMin)return!1;if(n.importanceMax!==void 0&&f.importance>n.importanceMax)return!1;if(n.createdAfter&&f.createdAt<n.createdAfter)return!1;if(n.createdBefore&&f.createdAt>n.createdBefore)return!1;if(n.concepts&&n.concepts.length>0){if(!n.concepts.some((E)=>f.concepts.some((N)=>N.toLowerCase().includes(E.toLowerCase()))))return!1}if(n.files&&n.files.length>0){let A=[...f.filesRead,...f.filesModified];if(!n.files.some((N)=>A.some((O)=>O.toLowerCase().includes(N.toLowerCase()))))return!1}return!0}async function WA(f,n,A,E,N){if(!f.trim())return n;let O=ON(f),S=new Set;for(let $ of O){let R=A.findByName($);for(let D of R){let l=A.traverseRelations(D.id,1);for(let u of l){let Q=A.getObservationsForEntity(u);for(let V of Q)S.add(V)}}}if(S.size===0)return n;let M=new Set(n.map(($)=>$.observation.id)),_=[];for(let $ of S){if(M.has($))continue;let R=E.getById($);if(!R)continue;if(R.supersededBy)continue;_.push({observation:R,rank:0,snippet:R.title,source:"project",rankingSource:"graph",explain:{strategy:"hybrid",matchedBy:["graph"]}})}return[...n,..._].slice(0,N)}function ON(f){let n=f.split(/\s+/).filter((E)=>E.length>=2),A=[];for(let E of n)A.push(E);for(let E=0;E<n.length-1;E++)A.push(`${n[E]} ${n[E+1]}`);return A}var XA=60;async function KA(f,n,A,E){let N=E.limit??10,O=MN(n,f,E,N);if(!A)return O;let S=await t(A,f);if(!S)return O;let M=O.map(($)=>$.observation.id),_=SN(n,S,E.projectPath,E,N,E.hasVectorExtension??!1,M);if(_.length===0)return O;return RN(O,_,N)}function MN(f,n,A,E){try{return f.search({query:n,type:A.type,limit:E,projectPath:A.projectPath,importanceMin:A.importanceMin,importanceMax:A.importanceMax,createdAfter:A.createdAfter,createdBefore:A.createdBefore,concepts:A.concepts,files:A.files})}catch{return[]}}function SN(f,n,A,E,N,O,S){if(O)return _N(f,n,E,N,S);return $N(f,n,A,E,N)}function _N(f,n,A,E,N){try{let O;if(N.length>0){if(O=f.searchVecSubset(n,N,E*3),O.length===0)O=f.getVecEmbeddingMatches(n,E*3)}else O=f.getVecEmbeddingMatches(n,E*3);if(O.length===0)return[];let S=[];for(let{observationId:M,distance:_}of O){if(S.length>=E)break;let $=f.getById(M);if(!$)continue;if(!Ef($,A))continue;S.push({observation:$,rank:_-1,snippet:$.title,rankingSource:"vector",explain:{strategy:"hybrid",matchedBy:["vector"],vectorDistance:_}})}return S}catch{return[]}}function $N(f,n,A,E,N){let O=f.getWithEmbeddings(A,N*10);if(O.length===0)return[];let S=O.map((_)=>({id:_.id,similarity:Af(n,_.embedding)})).filter(({similarity:_})=>_>=0.3).sort((_,$)=>$.similarity-_.similarity),M=[];for(let{id:_,similarity:$}of S){if(M.length>=N)break;let R=f.getById(_);if(!R)continue;if(!Ef(R,E))continue;M.push({observation:R,rank:-$,snippet:R.title,rankingSource:"vector",explain:{strategy:"hybrid",matchedBy:["vector"],vectorSimilarity:$}})}return M}function RN(f,n,A){let E=new Map;for(let N=0;N<f.length;N++){let O=f[N],S=1/(XA+N+1);E.set(O.observation.id,{score:S,result:{...O,rankingSource:"fts",explain:{strategy:"hybrid",matchedBy:["fts"],ftsRank:O.rank}}})}for(let N=0;N<n.length;N++){let O=n[N],S=1/(XA+N+1),M=E.get(O.observation.id);if(M)M.score+=S,M.result={...M.result,explain:{strategy:"hybrid",matchedBy:["fts","vector"],ftsRank:M.result.explain?.ftsRank??M.result.rank,vectorDistance:O.explain?.vectorDistance,vectorSimilarity:O.explain?.vectorSimilarity}};else E.set(O.observation.id,{score:S,result:{...O,explain:{strategy:"hybrid",matchedBy:["vector"],vectorDistance:O.explain?.vectorDistance,vectorSimilarity:O.explain?.vectorSimilarity}}})}return[...E.values()].sort((N,O)=>O.score-N.score).slice(0,A).map(({score:N,result:O})=>({...O,explain:{...O.explain??{strategy:"hybrid",matchedBy:[]},strategy:"hybrid",matchedBy:O.explain?.matchedBy??[],rrfScore:N,ftsRank:O.explain?.ftsRank,vectorDistance:O.explain?.vectorDistance,vectorSimilarity:O.explain?.vectorSimilarity}}))}class h0{observations;embeddingModel;hasVectorExtension;reranker;userObservationRepo;entityRepo;constructor(f,n,A,E=null,N=null,O=null){this.observations=f;this.embeddingModel=n;this.hasVectorExtension=A;this.reranker=E;this.userObservationRepo=N;this.entityRepo=O}async search(f,n){let A=n.strategy??"hybrid",E=n.limit??10,N;switch(A){case"filter-only":N=this.filterOnlySearch(f,n,E);break;case"semantic":N=await this.semanticSearch(f,n,E);break;case"hybrid":N=await this.hybridSearchStrategy(f,n,E);break}for(let O of N)O.source="project";if(this.entityRepo&&f.trim())N=await WA(f,N,this.entityRepo,this.observations,E);if(this.userObservationRepo){let O=this.searchUserMemory(f,n,E);N=this.mergeResults(N,O,E)}if(this.reranker&&N.length>1)return this.reranker.rerank(f,N,E);return N}filterOnlySearch(f,n,A){if(n.concept)return this.observations.searchByConcept(n.concept,A,n.projectPath).map((N)=>({observation:N,rank:0,snippet:N.title,rankingSource:"graph",explain:{strategy:"filter-only",matchedBy:["concept-filter"]}}));if(n.file)return this.observations.searchByFile(n.file,A,n.projectPath).map((N)=>({observation:N,rank:0,snippet:N.title,rankingSource:"graph",explain:{strategy:"filter-only",matchedBy:["file-filter"]}}));return this.observations.search({query:f,type:n.type,limit:A,projectPath:n.projectPath,importanceMin:n.importanceMin,importanceMax:n.importanceMax,createdAfter:n.createdAfter,createdBefore:n.createdBefore,concepts:n.concepts,files:n.files})}async semanticSearch(f,n,A){if(!this.embeddingModel)return this.filterOnlySearch(f,n,A);let E=await t(this.embeddingModel,f);if(!E)return this.filterOnlySearch(f,n,A);if(this.hasVectorExtension)return this.nativeVectorSearch(E,n,A);return this.jsFallbackVectorSearch(E,n,A)}async hybridSearchStrategy(f,n,A){return KA(f,this.observations,this.embeddingModel,{type:n.type,limit:A,projectPath:n.projectPath,hasVectorExtension:this.hasVectorExtension,importanceMin:n.importanceMin,importanceMax:n.importanceMax,createdAfter:n.createdAfter,createdBefore:n.createdBefore,concepts:n.concepts,files:n.files})}nativeVectorSearch(f,n,A){try{let E=this.observations.getVecEmbeddingMatches(f,A*3);if(E.length===0)return[];let N=[];for(let{observationId:O,distance:S}of E){if(N.length>=A)break;let M=this.observations.getById(O);if(!M)continue;if(!Ef(M,n))continue;N.push({observation:M,rank:S-1,snippet:M.title,rankingSource:"vector",explain:{strategy:"semantic",matchedBy:["vector"],vectorDistance:S}})}return N}catch{return[]}}jsFallbackVectorSearch(f,n,A){let E=this.observations.getWithEmbeddings(n.projectPath,A*10);if(E.length===0)return[];let N=E.map((S)=>({id:S.id,similarity:Af(f,S.embedding)})).filter(({similarity:S})=>S>=0.3).sort((S,M)=>M.similarity-S.similarity),O=[];for(let{id:S,similarity:M}of N){if(O.length>=A)break;let _=this.observations.getById(S);if(!_)continue;if(!Ef(_,n))continue;O.push({observation:_,rank:-M,snippet:_.title,rankingSource:"vector",explain:{strategy:"semantic",matchedBy:["vector"],vectorSimilarity:M}})}return O}searchUserMemory(f,n,A){if(!this.userObservationRepo)return[];try{return this.userObservationRepo.search({query:f,limit:A}).map(({observation:N,rank:O})=>({observation:DN(N),rank:O,snippet:N.title,source:"user",rankingSource:"user-memory",explain:{strategy:"filter-only",matchedBy:["user-memory"]}}))}catch{return[]}}mergeResults(f,n,A){let E=new Set(f.map((S)=>S.observation.id)),N=new Set(f.map((S)=>`${S.observation.title}::${S.observation.narrative}`)),O=n.filter((S)=>{if(E.has(S.observation.id))return!1;let M=`${S.observation.title}::${S.observation.narrative}`;if(N.has(M))return!1;return N.add(M),!0});return[...f,...O].slice(0,A)}}function DN(f){return{id:f.id,sessionId:"",type:f.type,title:f.title,subtitle:f.subtitle,facts:f.facts,narrative:f.narrative,concepts:f.concepts,filesRead:f.filesRead,filesModified:f.filesModified,rawToolOutput:"",toolName:f.toolName,createdAt:f.createdAt,tokenCount:f.tokenCount,discoveryTokens:0,importance:f.importance}}import{generateText as lN}from"ai";class ZA{languageModel;maxCandidates;provider;modelName;rateLimitingEnabled;_generate=lN;constructor(f,n){this.languageModel=f,this.maxCandidates=n.rerankingMaxCandidates,this.provider=n.provider??"",this.modelName=n.model??"",this.rateLimitingEnabled=n.rateLimitingEnabled??!0}async rerank(f,n,A){if(n.length<=1)return n;let E=n.slice(0,this.maxCandidates),N=n.slice(this.maxCandidates),O=xn(f,E.map((M)=>({title:M.observation.title,narrative:M.observation.narrative}))),S=2;for(let M=0;M<=S;M++)try{if(this.provider==="google")await k(this.modelName,this.rateLimitingEnabled);let{text:_}=await this._generate({model:this.languageModel,maxOutputTokens:512,prompt:O}),$=Hn(_);if(!$)return n.slice(0,A);let R=this.applyReranking(E,$,A);for(let D of N){if(R.length>=A)break;R.push(D)}return R}catch(_){if(uN(_)&&M<S){await yN(2**M*1000);continue}return n.slice(0,A)}return n.slice(0,A)}applyReranking(f,n,A){let E=[],N=new Set;for(let O of n)if(O>=0&&O<f.length&&!N.has(O)){if(N.add(O),E.push(f[O]),E.length>=A)break}if(E.length<A){for(let O=0;O<f.length&&E.length<A;O++)if(!N.has(O))E.push(f[O])}return E}}class UA{async rerank(f,n,A){if(n.length<=1)return n.slice(0,A);let E=p0(f),N=n.map((O)=>({result:O,score:this.scoreCandidate(O,E)}));return N.sort((O,S)=>S.score-O.score),N.slice(0,A).map((O)=>O.result)}scoreCandidate(f,n){let A=f.observation,E=p0(A.title),N=p0(A.narrative),O=new Set(A.concepts.map((W)=>W.toLowerCase())),S=0,M=0,_=0;for(let W of n){if(E.has(W))S++;if(N.has(W))M++;if(O.has(W))_++}let $=n.size||1,R=S/$*0.4,D=M/$*0.3,l=_/$*0.15,Q=(Date.now()-new Date(A.createdAt).getTime())/86400000,V=Q<1?0.1:Q<7?0.05:0,J=A.importance/5*0.05;return R+D+l+V+J}}function mA(f,n){if(!f.rerankingEnabled)return null;if(n)return new ZA(n,f);return new UA}function p0(f){return new Set(f.toLowerCase().split(/[\s\-_./\\,;:!?()[\]{}'"]+/).filter((n)=>n.length>1))}function uN(f){if(typeof f!=="object"||f===null)return!1;let n=f,A=n.status;if(A===429||A===500||A===503)return!0;let E=n.error;if(typeof E==="object"&&E!==null&&E.type==="overloaded_error")return!0;return!1}function yN(f){return new Promise((n)=>setTimeout(n,f))}function YA(f){return f}function FA(f){return f}function cA(f){return f}function GA(f){if(!f)return null;return f}import{spawnSync as jA}from"child_process";import{dirname as CN,resolve as HA}from"path";function VN(f){try{let n=jA("git",["rev-parse","--git-common-dir"],{cwd:f,encoding:"utf-8",timeout:5000});if(n.status!==0||!n.stdout)return null;let A=n.stdout.trim();if(A===".git")return null;let E=jA("git",["rev-parse","--git-dir"],{cwd:f,encoding:"utf-8",timeout:5000});if(E.status!==0||!E.stdout)return null;let N=E.stdout.trim(),O=HA(f,A),S=HA(f,N);if(O===S)return null;let M=CN(O);if(M===O||M==="/")return null;return M}catch{return null}}function gA(f){return VN(f)??f}function BN(f,n){return{id:n,command:"event",payload:f}}function JN(f,n,A){return{id:n,command:f,payload:A}}function TA(f){let n=typeof f==="string"?JSON.parse(f):f;if(!n||typeof n!=="object"||Array.isArray(n))throw Error("Invalid bridge response: expected object");let A=n;if(typeof A.ok!=="boolean")throw Error("Invalid bridge response: missing boolean 'ok'");if(typeof A.code!=="string")throw Error("Invalid bridge response: missing string 'code'");return{id:typeof A.id==="string"||typeof A.id==="number"?A.id:void 0,ok:A.ok,code:A.code,message:typeof A.message==="string"?A.message:void 0,ingested:typeof A.ingested==="boolean"?A.ingested:void 0,processed:typeof A.processed==="number"?A.processed:void 0,status:A.status&&typeof A.status==="object"&&!Array.isArray(A.status)?A.status:void 0}}function QN(f,n=["OK"]){return f.ok&&n.includes(f.code)}async function LN(f,n,A=fetch){let E=`${f.replace(/\/$/,"")}/v1/events`,N=await A(E,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)}),O=await N.text(),S;try{S=TA(O)}catch{throw Error(`Bridge HTTP response was not parseable JSON (status ${N.status})`)}if(!N.ok&&S.ok)return{...S,ok:!1,code:"HTTP_ERROR",message:`HTTP status ${N.status}`};return S}async function zN(f,n=fetch){let A=`${f.replace(/\/$/,"")}/v1/health`,E=await n(A,{method:"GET"}),N=await E.text(),O=TA(N);if(!E.ok&&O.ok)return{...O,ok:!1,code:"HTTP_ERROR",message:`HTTP status ${E.status}`};return O}var PA={name:"opencode",version:"1.0",capabilities:{nativeSessionLifecycle:!0,nativeToolCapture:!0,nativeChatCapture:!0,emulatedIdleFlush:!1}},kA={name:"claude-code",version:"0.1",capabilities:{nativeSessionLifecycle:!0,nativeToolCapture:!0,nativeChatCapture:!0,emulatedIdleFlush:!0}},IA={name:"cursor",version:"0.1",capabilities:{nativeSessionLifecycle:!1,nativeToolCapture:!0,nativeChatCapture:!0,emulatedIdleFlush:!0}};function I(){return new Date().toISOString()}function G(f){if(!f||typeof f!=="object"||Array.isArray(f))return null;return f}function m(f){return typeof f==="string"&&f.trim().length>0?f:null}function wA(f){if(f.eventType==="tool.execute.after"){let S=G(f.payload),M=G(f.output);if(!S||!M)return null;let _=m(S.sessionID),$=m(S.callID),R=m(S.tool),D=m(M.output);if(!_||!$||!R||!D)return null;return{kind:"tool.execute",platform:"opencode",sessionId:_,callId:$,toolName:R,output:D,occurredAt:I(),metadata:{title:M.title}}}if(f.eventType==="chat.message"){let S=G(f.payload),M=G(f.output);if(!S||!M)return null;let _=m(S.sessionID),$=G(M.message),R=m($?.role)??"user",D=m($?.content);if(!_||!D)return null;return{kind:"chat.message",platform:"opencode",sessionId:_,role:R==="assistant"||R==="system"?R:"user",text:D,occurredAt:I()}}let n=G(f.payload);if(!n)return null;let A=G(n.event),E=m(A?.type),N=G(A?.properties),O=m(N?.sessionID);if(!E||!O)return null;if(E==="session.idle")return{kind:"idle.flush",platform:"opencode",sessionId:O,occurredAt:I()};if(E==="session.started")return{kind:"session.start",platform:"opencode",sessionId:O,occurredAt:I(),metadata:N??void 0};if(E==="session.created")return{kind:"session.start",platform:"opencode",sessionId:O,occurredAt:I(),metadata:N??void 0};if(E==="session.ended")return{kind:"session.end",platform:"opencode",sessionId:O,occurredAt:I(),metadata:N??void 0};if(E==="session.completed")return{kind:"session.end",platform:"opencode",sessionId:O,occurredAt:I(),metadata:N??void 0};return null}function af(f,n){let A=G(n);if(!A)return null;let E=m(A.kind),N=m(A.sessionId);if(!E||!N)return null;if(E==="session.start"||E==="session.end"||E==="idle.flush")return{kind:E,platform:f,sessionId:N,occurredAt:m(A.occurredAt)??I(),metadata:G(A.metadata)??void 0};if(E==="chat.message"){let O=m(A.text);if(!O)return null;let S=m(A.role);return{kind:E,platform:f,sessionId:N,text:O,role:S==="assistant"||S==="system"?S:"user",occurredAt:m(A.occurredAt)??I(),metadata:G(A.metadata)??void 0}}if(E==="tool.execute"){let O=m(A.toolName),S=m(A.output);if(!O||!S)return null;return{kind:E,platform:f,sessionId:N,callId:m(A.callId)??`${f}-${Date.now()}`,toolName:O,output:S,occurredAt:m(A.occurredAt)??I(),metadata:G(A.metadata)??void 0}}return null}function WN(f){let n=f.type??f.event;if(!n)return null;if(n==="session.start")return"session.start";if(n==="session.end")return"session.end";if(n==="idle.flush")return"idle.flush";if(n==="tool.execute")return"tool.execute";if(n==="chat.message")return"chat.message";return null}class xA{descriptor=kA;normalize(f){if(!f||typeof f!=="object"||Array.isArray(f))return null;let n=f,A=WN(n);if(!A||!n.sessionId)return null;return af("claude-code",{kind:A,sessionId:n.sessionId,callId:n.callId,toolName:n.toolName,output:n.output,role:n.role,text:n.text,occurredAt:n.occurredAt,metadata:n.metadata})}}function XN(){return new xA}function KN(f){let n=f.eventName??f.event;if(!n)return null;if(n==="sessionStart")return"session.start";if(n==="sessionEnd")return"session.end";if(n==="idleFlush")return"idle.flush";if(n==="toolExecute")return"tool.execute";if(n==="chatMessage")return"chat.message";return null}class vA{descriptor=IA;normalize(f){if(!f||typeof f!=="object"||Array.isArray(f))return null;let n=f,A=KN(n),E=n.sessionId??n.session;if(!A||!E)return null;return af("cursor",{kind:A,sessionId:E,callId:n.callId??n.invocationId,toolName:n.toolName??n.tool,output:n.output,role:n.role,text:n.text??n.message,occurredAt:n.occurredAt??n.timestamp,metadata:n.metadata??n.meta})}}function ZN(){return new vA}class qA{descriptor=PA;normalize(f){if(!f||typeof f!=="object"||Array.isArray(f))return null;let n=f;if(!n.eventType)return null;return wA({eventType:n.eventType,payload:n.payload,output:n.output})}}function UN(){return new qA}class rA{adapter;lifecycleDeps;queue;sessions;observations;projectPath;config;constructor(f){this.adapter=f.adapter,this.queue=f.queue,this.sessions=f.sessions,this.observations=f.observations,this.projectPath=f.projectPath,this.config=f.config,this.lifecycleDeps={queue:f.queue,sessions:f.sessions,projectPath:f.projectPath,config:f.config,observations:f.observations,pendingMessages:f.pendingMessages}}platform(){return this.adapter.descriptor.name}normalize(f){return this.adapter.normalize(f)}async ingestRaw(f){let n=this.normalize(f);if(!n)return!1;return await this.ingestNormalized(n),!0}async ingestNormalized(f){switch(f.kind){case"session.start":await Cf(this.lifecycleDeps,"session.created",f.sessionId);return;case"session.end":await Cf(this.lifecycleDeps,"session.ended",f.sessionId);return;case"idle.flush":await Cf(this.lifecycleDeps,"session.idle",f.sessionId);return;case"tool.execute":v0({config:this.config,queue:this.queue,sessions:this.sessions,projectPath:this.projectPath,tool:f.toolName,sessionId:f.sessionId,callId:f.callId,toolOutput:f.output});return;case"chat.message":x0({observations:this.observations,sessions:this.sessions,projectPath:this.projectPath,sessionId:f.sessionId,text:f.text,agent:f.role==="user"?"user":f.role,sensitivePatterns:this.config.sensitivePatterns});return}}}cf();function cN(){try{let n=import.meta.url;if(n&&!n.includes("[eval]")){let A=YN(FN(n));return A.endsWith("dist")||A.endsWith("dist/")||A.endsWith("dist\\")?A:a(A,"..","dist")}}catch{}let f=[a(process.env.HOME||"",".config","opencode","node_modules","open-mem","dist"),a(process.cwd(),"node_modules","open-mem","dist")];for(let n of f)if(mN(a(n,"daemon.js")))return n;return a(process.cwd(),"node_modules","open-mem","dist")}async function GN(f){let n=cN(),A=gA(f.directory),E=d(A),N=Jn(E);for(let x of N)console.warn(`[open-mem] ${x}`);await Qn(E),rf.enableExtensionSupport();let O=hf(E.dbPath);$A(O,{hasVectorExtension:O.hasVectorExtension,embeddingDimension:E.embeddingDimension});let S=new P0(O),M=new g0(O),_=new k0(O),$=new T0(O),R=new c0(O),D=new j0(O),l=null,u=null;if(E.userMemoryEnabled)try{l=new I0(E.userMemoryDbPath),u=new w0(l.database)}catch(x){console.warn(`[open-mem] Failed to initialize user-level memory: ${x}`)}let Q=new Df(E),V=new z0(E),J=E.provider!=="bedrock",W=E.compressionEnabled&&(!J||E.apiKey)?vn({provider:E.provider,model:E.model,apiKey:E.apiKey}):null,F=new r0,K=E.conflictResolutionEnabled&&(!J||E.apiKey)?new Q0({provider:E.provider,apiKey:E.apiKey,model:E.model,rateLimitingEnabled:E.rateLimitingEnabled}):null,U=E.entityExtractionEnabled&&(!J||E.apiKey)?new L0({provider:E.provider,apiKey:E.apiKey,model:E.model,rateLimitingEnabled:E.rateLimitingEnabled}):null,Vf=new G0(O),w=new q0(E,Q,V,$,M,S,_,W,K,U,Vf,F.createQueueObserver()),j=zA(w);j.start();let c=()=>{let x=w.getStats(),g=F.snapshot({mode:w.getMode(),running:w.isRunning,processing:x.processing,pending:x.pending});return{status:g.queue.lastError?"degraded":"ok",timestamp:new Date().toISOString(),uptimeMs:g.uptimeMs,queue:g.queue,batches:g.batches,enqueueCount:g.enqueueCount}},sf=mA(E,E.rerankingEnabled&&(!J||E.apiKey)?P({provider:E.provider,model:E.model,apiKey:E.apiKey}):null),H=new h0(M,W,O.hasVectorExtension,sf,u,Vf),Bf=new Z0({observations:YA(M),sessions:FA(S),summaries:cA(_),searchOrchestrator:H,projectPath:A,config:E,userObservationRepo:GA(u),runtimeSnapshotProvider:c,configAuditStore:R,maintenanceHistoryStore:D}),b0=cn(Bf),q=null,s=null;if(E.daemonEnabled)if(NA(E.dbPath),q=new m0({dbPath:E.dbPath,projectPath:A,daemonScript:a(n,"daemon.js")}),q.start())j.setEnqueueOnly(()=>q?.signal("PROCESS_NOW")),console.log("[open-mem] Background daemon started \u2014 processing delegated"),s=setInterval(()=>{if(q&&!q.isRunning()){if(console.warn("[open-mem] Daemon died, falling back to in-process processing"),j.setInProcess(),s)clearInterval(s),s=null}},30000);else console.warn("[open-mem] Daemon failed to start \u2014 using in-process processing"),q=null;let of=null,df=null,Jf=null;if(E.dashboardEnabled){df=RA(),Jf=new J0(df);let x=mn({config:E,projectPath:A,embeddingModel:W,memoryEngine:Bf,runtimeStatusProvider:c,sseHandler:Fn(Jf),dashboardDir:a(n,"dashboard")}),g=E.dashboardPort,ef=g,i0=!1;for(let Nf=0;Nf<10;Nf++){ef=g+Nf;try{of=Bun.serve({port:ef,hostname:"127.0.0.1",idleTimeout:0,fetch:x.fetch}),i0=!0;break}catch{}}if(i0)console.log(`[open-mem] Dashboard available at http://127.0.0.1:${ef}`);else console.warn(`[open-mem] Could not start dashboard \u2014 ports ${g}-${g+9} all busy`);let pA=df,bA=M.create.bind(M);M.create=(...Nf)=>{let t0=bA(...Nf);return pA.emit("observation:created",t0),t0}}let hA=()=>{if(s)clearInterval(s);if(q)q.stop();if(j.stop(),of)of.stop();if(Jf)Jf.destroy();if(l)l.close();O.close()};return process.on("beforeExit",hA),{"tool.execute.after":LA(E,w,S,A),"chat.message":yA(M,S,A,E.sensitivePatterns),event:QA(w,S,A,E,M,$),"experimental.chat.system.transform":VA(E,M,S,_,A,u),"experimental.session.compacting":CA(E,M,S,_,A,u),tool:{...b0}}}export{LN as sendBridgeHttpEvent,d as resolveConfig,QN as isBridgeSuccess,Ff as getDefaultConfig,zN as getBridgeHealth,GN as default,UN as createOpenCodePlatformAdapter,BN as createEventEnvelope,ZN as createCursorAdapter,JN as createCommandEnvelope,XN as createClaudeCodeAdapter,rA as PlatformIngestionRuntime};