@membank/core 0.14.0 → 0.14.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.
- package/dist/index.cjs +29 -25
- package/dist/index.d.cts +4 -1
- package/dist/index.d.mts +4 -1
- package/dist/index.mjs +10 -6
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));const c=require(`./global-scope-CgOQm1jp.cjs`);let l=require(`node:crypto`),u=require(`zod`),d=require(`node:fs`),f=require(`node:os`),p=require(`node:path`),m=require(`better-sqlite3`);m=s(m,1);let h=require(`sqlite-vec`);h=s(h,1);let
|
|
2
|
-
VALUES (?, ?, ?, ?, ?, ?)`),this.#r=e.db.prepare(`DELETE FROM activity_events WHERE created_at < ?`)}insert(e){this.#n.run(e.id,e.projectHash,e.eventType,e.memoryId,JSON.stringify(e.payload),e.createdAt)}list(e){let t=[],n=[];e.scope!==void 0&&(t.push(`project_hash = ?`),n.push(e.scope)),e.type!==void 0&&(t.push(`event_type = ?`),n.push(e.type)),e.since!==void 0&&(t.push(`created_at >= ?`),n.push(e.since));let r=t.length>0?`WHERE ${t.join(` AND `)}`:``,i=e.limit===void 0?``:`LIMIT ?`;return e.limit!==void 0&&n.push(e.limit),this.#e.db.prepare(`SELECT * FROM activity_events ${r} ORDER BY created_at DESC ${i}`).all(...n).map(
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));const c=require(`./global-scope-CgOQm1jp.cjs`);let l=require(`node:crypto`),u=require(`zod`),d=require(`node:fs`),f=require(`node:os`),p=require(`node:path`),m=require(`better-sqlite3`);m=s(m,1);let h=require(`sqlite-vec`);h=s(h,1);let ee=require(`node:events`),g=require(`@huggingface/transformers`),_=require(`@anthropic-ai/claude-agent-sdk`),te=require(`node:fs/promises`),ne=require(`node:child_process`),re=require(`node:util`);function ie(e,t){return t.list(e)}const v=[`memory.created`,`memory.updated`,`memory.deleted`,`memory.flagged`,`memory.queried`],y=u.z.enum(v);function b(e,t){let n=new Date,r=n.toISOString();t.insert({id:(0,l.randomUUID)(),projectHash:e.projectHash,eventType:e.eventType,memoryId:e.memoryId??null,payload:e.payload??{},createdAt:r});let i=new Date(n);i.setDate(i.getDate()-30),t.prune(i.toISOString())}function ae(e){return{id:e.id,projectHash:e.project_hash,eventType:y.parse(e.event_type),memoryId:e.memory_id,payload:JSON.parse(e.payload),createdAt:e.created_at}}var x=class{#e;#t=0;#n;#r;constructor(e){this.#e=e,this.#n=e.db.prepare(`INSERT INTO activity_events (id, project_hash, event_type, memory_id, payload, created_at)
|
|
2
|
+
VALUES (?, ?, ?, ?, ?, ?)`),this.#r=e.db.prepare(`DELETE FROM activity_events WHERE created_at < ?`)}insert(e){this.#n.run(e.id,e.projectHash,e.eventType,e.memoryId,JSON.stringify(e.payload),e.createdAt)}list(e){let t=[],n=[];e.scope!==void 0&&(t.push(`project_hash = ?`),n.push(e.scope)),e.type!==void 0&&(t.push(`event_type = ?`),n.push(e.type)),e.since!==void 0&&(t.push(`created_at >= ?`),n.push(e.since));let r=t.length>0?`WHERE ${t.join(` AND `)}`:``,i=e.limit===void 0?``:`LIMIT ?`;return e.limit!==void 0&&n.push(e.limit),this.#e.db.prepare(`SELECT * FROM activity_events ${r} ORDER BY created_at DESC ${i}`).all(...n).map(ae)}prune(e){let t=Date.now();t-this.#t<6e4||(this.#r.run(e),this.#t=t)}};function oe(e){return new x(e)}function se(e){let t=new x(e);return{logEvent:e=>b(e,t)}}const S={logEvent(){}};function ce(){let e=(0,p.join)((0,f.homedir)(),`.membank`,`config.json`);try{let t=(0,d.readFileSync)(e,`utf8`);return JSON.parse(t)}catch{return null}}function le(){return ce()?.synthesis?.enabled===!0}const C=[`correction`,`preference`,`decision`,`learning`,`fact`],w=u.z.enum(C),T=u.z.array(u.z.string()),E=u.z.object({id:u.z.string(),name:u.z.string(),scopeHash:u.z.string(),createdAt:u.z.string(),updatedAt:u.z.string()}),D=u.z.enum([`similarity_dedup`]),O=u.z.object({id:u.z.string(),memoryId:u.z.string(),conflictingMemoryId:u.z.string().nullable(),similarity:u.z.number(),conflictContentSnapshot:u.z.string(),reason:D,createdAt:u.z.string(),resolvedAt:u.z.string().nullable()}),k=u.z.object({id:u.z.string(),memory_id:u.z.string(),conflicting_memory_id:u.z.string().nullable(),similarity:u.z.number(),conflict_content_snapshot:u.z.string(),reason:D,created_at:u.z.string(),resolved_at:u.z.string().nullable()}),A=u.z.object({id:u.z.string(),content:u.z.string(),type:w,tags:u.z.array(u.z.string()),projects:u.z.array(E),sourceHarness:u.z.string().nullable(),accessCount:u.z.number().int().nonnegative(),pinned:u.z.boolean(),reviewEvents:u.z.array(O),createdAt:u.z.string(),updatedAt:u.z.string()}),j=u.z.object({query:u.z.string().min(1),type:w.optional(),projectHash:u.z.string().optional(),limit:u.z.number().int().positive().optional(),includePinned:u.z.boolean().optional()}),M=u.z.object({content:u.z.string().min(1),type:w,tags:u.z.array(u.z.string()).optional(),projectScope:u.z.object({hash:u.z.string(),name:u.z.string()}).optional(),sourceHarness:u.z.string().optional()}),N=u.z.object({content:u.z.string().min(1).optional(),tags:u.z.array(u.z.string()).optional(),type:w.optional()}),P=u.z.object({id:u.z.string(),scope:u.z.string(),content:u.z.string(),sourceMemoryHash:u.z.string(),synthesizedAt:u.z.string(),expiresAt:u.z.string(),inFlightSince:u.z.string().nullable(),createdAt:u.z.string(),updatedAt:u.z.string()}),ue=u.z.object({stats:u.z.record(w,u.z.number()),pinnedGlobal:u.z.array(A),pinnedProject:u.z.array(A),synthesis:u.z.string().optional()}),F=u.z.object({id:u.z.string(),content:u.z.string(),type:u.z.string(),tags:u.z.string(),source:u.z.string().nullable(),access_count:u.z.number(),pinned:u.z.number(),created_at:u.z.string(),updated_at:u.z.string()}),de=u.z.object({id:u.z.number(),memory_id:u.z.string(),version:u.z.number(),content:u.z.string(),created_at:u.z.string()}),fe=u.z.object({id:u.z.number(),scope:u.z.string(),version:u.z.number(),content:u.z.string(),source_memory_hash:u.z.string(),synthesized_at:u.z.string(),created_at:u.z.string()}),I=u.z.object({id:u.z.string(),name:u.z.string(),scope_hash:u.z.string(),created_at:u.z.string(),updated_at:u.z.string()});function L(e,t,n=[]){return{id:e.id,content:e.content,type:w.parse(e.type),tags:T.parse(JSON.parse(e.tags)),projects:t,sourceHarness:e.source,accessCount:e.access_count,pinned:e.pinned!==0,reviewEvents:n,createdAt:e.created_at,updatedAt:e.updated_at}}function R(e){let t=k.parse(e);return{id:t.id,memoryId:t.memory_id,conflictingMemoryId:t.conflicting_memory_id,similarity:t.similarity,conflictContentSnapshot:t.conflict_content_snapshot,reason:t.reason,createdAt:t.created_at,resolvedAt:t.resolved_at}}function z(e){return{id:e.id,name:e.name,scopeHash:e.scope_hash,createdAt:e.created_at,updatedAt:e.updated_at}}function B(e){return{version:e.version,content:e.content,createdAt:e.created_at}}function V(e){return{version:e.version,content:e.content,sourceMemoryHash:e.source_memory_hash,synthesizedAt:e.synthesized_at,createdAt:e.created_at}}var H=class extends Error{constructor(e,t){super(e,t),this.name=`MembankError`}},U=class extends H{constructor(e,t){super(e,t),this.name=`DatabaseError`}};const pe=(0,p.join)((0,f.homedir)(),`.membank`,`memory.db`),me=[[1,`
|
|
3
3
|
CREATE TABLE IF NOT EXISTS memories (
|
|
4
4
|
id TEXT PRIMARY KEY,
|
|
5
5
|
content TEXT NOT NULL,
|
|
@@ -278,14 +278,14 @@ CREATE TABLE synthesis_versions (
|
|
|
278
278
|
);
|
|
279
279
|
|
|
280
280
|
CREATE INDEX idx_synthesis_versions_scope ON synthesis_versions(scope, version DESC);
|
|
281
|
-
`]];var
|
|
281
|
+
`]];var he=class e{#e;constructor(e){this.#e=e}static open(t){let n=t??pe;(0,d.mkdirSync)((0,p.dirname)(n),{recursive:!0});let r=new m.default(n);return e.#n(r,h.load)}static openInMemory(){return e.#t(h.load)}static _openInMemoryWithLoader(t){return e.#t(t)}static#t(t){let n=new m.default(`:memory:`);return e.#n(n,t)}static#n(t,n){try{n(t)}catch(e){throw new U(`Failed to load sqlite-vec extension`,{cause:e})}t.pragma(`journal_mode = WAL`),t.pragma(`foreign_keys = ON`);let r=new e(t);return r.#r(),r}#r(){this.#e.exec(`
|
|
282
282
|
CREATE TABLE IF NOT EXISTS meta (
|
|
283
283
|
key TEXT PRIMARY KEY,
|
|
284
284
|
value TEXT NOT NULL
|
|
285
285
|
);
|
|
286
|
-
`);let e=this.#e.prepare(`SELECT value FROM meta WHERE key = 'schema_version'`).get(),t=e?Number.parseInt(e.value,10):0;for(let[e,n]of
|
|
287
|
-
`);var
|
|
288
|
-
`),r=Object.fromEntries(Object.entries(process.env).filter(e=>e[1]!==void 0)),i=Date.now(),a=(0,
|
|
286
|
+
`);let e=this.#e.prepare(`SELECT value FROM meta WHERE key = 'schema_version'`).get(),t=e?Number.parseInt(e.value,10):0;for(let[e,n]of me)t<e&&(this.#e.exec(n),this.#e.prepare(`INSERT OR REPLACE INTO meta (key, value) VALUES ('schema_version', ?)`).run(String(e)))}get db(){return this.#e}close(){this.#e.close()}};const W=`Xenova/bge-small-en-v1.5`;var G=class extends Error{constructor(e,t){super(e,t),this.name=`ModelDownloadError`}};function ge(){return(0,p.join)((0,f.homedir)(),`.membank`,`models`)}function K(e){if(!(0,d.existsSync)(e))return!1;try{return(0,d.readdirSync)(e).length>0}catch{return!1}}var _e=class extends ee.EventEmitter{modelPath;constructor(e){super(),this.modelPath=e??ge()}isAlreadyCached(){return K(this.modelPath)}get cachePath(){return this.modelPath}async download(){if(K(this.modelPath))return{skipped:!0};let e=Date.now(),t=0,n=e;try{await(0,g.pipeline)(`feature-extraction`,W,{cache_dir:this.modelPath,progress_callback:e=>{if(e.status!==`progress`||e.total==null||e.loaded==null)return;let r=e.total,i=e.loaded,a=r>0?i/r*100:0,o=Date.now(),s=o-n,c=i-t,l=0;if(s>0&&c>0){let e=c/s;l=(r-i)/e/1e3}t=i,n=o;let u={totalBytes:r,downloadedBytes:i,percentage:a,estimatedSecondsRemaining:l};this.emit(`progress`,u)}})}catch(e){throw new G(`Failed to download model`,{cause:e})}return{skipped:!1}}},ve=class{modelCachePath;onProgress;pipelineInstance=null;constructor(e,t){this.modelCachePath=e??(0,p.join)((0,f.homedir)(),`.membank`,`models`),this.onProgress=t}async getPipeline(){return this.pipelineInstance===null&&(this.pipelineInstance=await(0,g.pipeline)(`feature-extraction`,`Xenova/bge-small-en-v1.5`,{cache_dir:this.modelCachePath,...this.onProgress!==void 0&&{progress_callback:this.onProgress}})),this.pipelineInstance}async embed(e){let t=(await(await this.getPipeline())(e,{pooling:`mean`,normalize:!0})).data;return t instanceof Float32Array?t:new Float32Array(t)}};async function ye(e,t){let n=t.now??(()=>new Date);if(!t.repo.tryClaim(e.sessionId,n(),t.config)){let n=t.repo.get(e.sessionId);return{status:`skipped`,reason:n?.status===`completed`&&n.completedAt!==null?`recently_completed`:`in_flight`}}try{let r=await t.transcripts.read(e.transcriptPath);return await t.agent.run({transcript:r,projectHash:e.projectHash,sessionId:e.sessionId}),t.repo.markCompleted(e.sessionId,n()),{status:`completed`}}catch(r){let i=r instanceof Error?r.message:String(r);return t.repo.markFailed(e.sessionId,n(),i),{status:`failed`,error:i}}}const be=[`You are a memory extractor that runs after a coding session ends. You read the session transcript and CALL save_memory for every durable fact, preference, correction, decision, or learning the user expressed, so that future sessions inherit them.`,``,`Memory types (pick the closest match):`,`- correction: the user told the assistant to stop doing something or to do it differently.`,`- preference: the user stated how they want work done (tools, style, conventions).`,`- decision: the user committed to a choice future work should respect (tech pick, architectural direction, scope cut).`,`- learning: a non-obvious fact about the codebase or tooling that future sessions would otherwise rediscover.`,`- fact: stable info about the user or their project not derivable from the code.`,``,`Bias strongly toward saving. If the user said it in plain language and it would be useful in a future session, save it. Phrasing like 'stop X', 'always Y', 'we use Z', 'don't suggest W', 'we decided', 'from now on' is a clear save signal — even when the assistant in the transcript already acknowledged it, save it so the NEXT session also knows.`,``,`Process:`,`1. Read the supplied transcript end-to-end.`,`2. Identify every distinct durable signal. List them mentally before calling tools.`,`3. Optional: call query_memory with focused search terms to avoid duplicates. If a near-duplicate exists, call update_memory instead of save_memory.`,`4. Call save_memory for each new durable signal. Phrase the content as a standalone instruction or fact — strip session framing ("in this session", "just now"). Good: "Use pnpm, not npm, for all dependency operations." Bad: "User said stop using npm."`,"5. Use `global: true` only when the fact is about the user themselves or applies across every project. Otherwise default to project scope (omit `global`).",``,`Only return without saving when the transcript truly contains no durable signal — pure greetings, time-of-day questions, abandoned tasks. Do not invent facts. If in doubt and the signal is concrete, save it.`].join(`
|
|
287
|
+
`);var xe=class{#e;constructor(e){this.#e=e}async run(e){let t=(0,_.createSdkMcpServer)({name:`membank-extraction-tools`,version:`1.0.0`,tools:[(0,_.tool)(`query_memory`,`Search memories by semantic similarity to check for existing entries before saving.`,{query:u.z.string().describe(`Search text`),limit:u.z.number().optional().describe(`Maximum results to return`),global:u.z.boolean().optional().describe(`Query global memories when true, otherwise current project scope`)},async({query:t,limit:n,global:r})=>({content:[{type:`text`,text:await this.#e.queryMemory({query:t,...n!==void 0&&{limit:n},...r!==void 0&&{global:r},...e.projectHash!==void 0&&{projectHash:e.projectHash}})}]}),{annotations:{readOnlyHint:!0}}),(0,_.tool)(`save_memory`,`Persist a new memory. The system handles dedup automatically.`,{content:u.z.string().describe(`Memory content — concise, decontextualised`),type:u.z.enum([`correction`,`preference`,`decision`,`learning`,`fact`]).describe(`Memory type`),tags:u.z.array(u.z.string()).optional().describe(`Optional tags`),global:u.z.boolean().optional().describe(`Save as global memory rather than project-scoped`)},async({content:e,type:t,tags:n,global:r})=>({content:[{type:`text`,text:await this.#e.saveMemory({content:e,type:t,...n!==void 0&&{tags:n},...r!==void 0&&{global:r}})}]})),(0,_.tool)(`update_memory`,`Refine an existing memory by id rather than creating a near-duplicate.`,{id:u.z.string().describe(`Memory id`),content:u.z.string().optional(),type:u.z.enum([`correction`,`preference`,`decision`,`learning`,`fact`]).optional(),tags:u.z.array(u.z.string()).optional()},async({id:e,content:t,type:n,tags:r})=>({content:[{type:`text`,text:await this.#e.updateMemory({id:e,...t!==void 0&&{content:t},...n!==void 0&&{type:n},...r!==void 0&&{tags:r}})}]}))]}),n=[`Session id: ${e.sessionId}`,``,`Transcript (most recent turns):`,`---`,e.transcript,`---`,``,`Extract durable memories from this transcript following the system instructions.`].join(`
|
|
288
|
+
`),r=Object.fromEntries(Object.entries(process.env).filter(e=>e[1]!==void 0)),i=Date.now(),a=(0,_.query)({prompt:n,options:{model:`claude-haiku-4-5-20251001`,systemPrompt:be,mcpServers:{"membank-extraction-tools":t},allowedTools:[`mcp__membank-extraction-tools__query_memory`,`mcp__membank-extraction-tools__save_memory`,`mcp__membank-extraction-tools__update_memory`],disallowedTools:[`mcp__membank__*`],settingSources:[],permissionMode:`bypassPermissions`,env:r}}),o=process.env.MEMBANK_EXTRACTION_DEBUG===`true`;for await(let e of a)if(o&&process.stderr.write(`[extraction debug] ${JSON.stringify(e).slice(0,600)}\n`),e.type===`result`&&e.subtype!==`success`){let t=`errors`in e&&Array.isArray(e.errors)?`: ${e.errors.join(`; `)}`:``;throw Error(`Extraction agent failed: ${e.subtype}${t}`)}let s=Date.now()-i;process.stderr.write(`membank extraction: session=${e.sessionId} duration=${s}ms\n`)}};function Se(e){return new xe(e)}function Ce(e,t,n,r){return e===void 0?{kind:`claim`}:e.status===`in_flight`?t.getTime()-e.startedAt.getTime()<n?{kind:`skip`,reason:`in_flight`}:{kind:`claim`}:e.status===`completed`&&e.completedAt!==null&&t.getTime()-e.completedAt.getTime()<r?{kind:`skip`,reason:`recently_completed`}:{kind:`claim`}}function we(e){return{sessionId:e.session_id,startedAt:e.started_at,completedAt:e.completed_at,status:e.status,error:e.error}}var Te=class{#e;constructor(e){this.#e=e}tryClaim(e,t,n){let r=this.#t(e);if(Ce(r===void 0?void 0:{startedAt:new Date(r.started_at),completedAt:r.completed_at===null?null:new Date(r.completed_at),status:r.status},t,n.inFlightTimeoutMs??6e5,n.recentCompletionMs??6e4).kind===`skip`)return!1;let i=t.toISOString();return this.#e.db.prepare(`INSERT INTO extraction_runs (session_id, started_at, completed_at, status, error)
|
|
289
289
|
VALUES (?, ?, NULL, 'in_flight', NULL)
|
|
290
290
|
ON CONFLICT(session_id) DO UPDATE SET
|
|
291
291
|
started_at = excluded.started_at,
|
|
@@ -295,11 +295,15 @@ CREATE INDEX idx_synthesis_versions_scope ON synthesis_versions(scope, version D
|
|
|
295
295
|
SET status = 'completed', completed_at = ?, error = NULL
|
|
296
296
|
WHERE session_id = ?`).run(t.toISOString(),e)}markFailed(e,t,n){this.#e.db.prepare(`UPDATE extraction_runs
|
|
297
297
|
SET status = 'failed', completed_at = ?, error = ?
|
|
298
|
-
WHERE session_id = ?`).run(t.toISOString(),n,e)}get(e){let t=this.#t(e);return t===void 0?void 0:
|
|
299
|
-
`)}var
|
|
300
|
-
`).filter(e=>e.length>0),n=[];for(let e of t){let t;try{t=JSON.parse(e)}catch{continue}let r=t.message?.role;if(r!==`user`&&r!==`assistant`)continue;let i=
|
|
298
|
+
WHERE session_id = ?`).run(t.toISOString(),n,e)}get(e){let t=this.#t(e);return t===void 0?void 0:we(t)}#t(e){return this.#e.db.prepare(`SELECT * FROM extraction_runs WHERE session_id = ?`).get(e)}};function Ee(e){return new Te(e)}function De(e){if(typeof e==`string`)return e;if(!Array.isArray(e))return``;let t=[];for(let n of e){if(typeof n!=`object`||!n)continue;let e=n;e.type===`text`&&typeof e.text==`string`?t.push(e.text):e.type===`tool_use`&&typeof e.name==`string`?t.push(`[tool_use: ${e.name}]`):e.type===`tool_result`&&t.push(`[tool_result]`)}return t.join(`
|
|
299
|
+
`)}var Oe=class{#e;#t;constructor(e={}){this.#e=e.maxTurns??80,this.#t=e.maxChars??6e4}async read(e){let t=(await(0,te.readFile)(e,`utf8`)).split(`
|
|
300
|
+
`).filter(e=>e.length>0),n=[];for(let e of t){let t;try{t=JSON.parse(e)}catch{continue}let r=t.message?.role;if(r!==`user`&&r!==`assistant`)continue;let i=De(t.message?.content).trim();i.length!==0&&n.push(`${r}: ${i}`)}let r=n.slice(-this.#e).join(`
|
|
301
301
|
|
|
302
|
-
`);return r.length<=this.#t?r:r.slice(r.length-this.#t)}};function
|
|
302
|
+
`);return r.length<=this.#t?r:r.slice(r.length-this.#t)}};function ke(e={}){return new Oe(e)}function Ae(e){let t=new Map;function n(e){t.has(e)||t.set(e,e);let r=t.get(e);if(r!==e){let i=n(r);return t.set(e,i),i}return e}function r(e,r){let i=n(e),a=n(r);i!==a&&t.set(a,i)}for(let{memoryId:t,conflictingMemoryId:n}of e)r(t,n);let i=new Map;for(let e of t.keys()){let t=n(e),r=i.get(t)??[];r.push(e),i.set(t,r)}return Array.from(i.entries()).map(([e,t])=>({clusterId:e,memoryIds:t}))}function q(e,t,n=S){let r=t.findById(e)?.projects[0]?.scopeHash??`0000000000000000`;return t.delete(e),n.logEvent({projectHash:r,eventType:`memory.deleted`,memoryId:e}),Promise.resolve()}async function je(e,t,n=S){let r=[];for(let i of e)try{await q(i,t,n),r.push({id:i,status:`ok`})}catch(e){r.push({id:i,status:`error`,error:e instanceof Error?e.message:String(e)})}return r}function J(e){return e>.92?`overwrite`:e>=.75?`flag`:`none`}async function Me(e,t){let{keepId:n,dropIds:r,mergedContent:i}=e,{repo:a,embedder:o,activityLogger:s=S}=t,c=a.findById(n);if(c===void 0)throw Error(`Memory not found: ${n}`);let l=r.map(e=>{let t=a.findById(e);if(t===void 0)throw Error(`Memory not found: ${e}`);return t});for(let e of l)if(e.type!==c.type)throw Error(`Type mismatch: keep memory has type "${c.type}" but drop memory ${e.id} has type "${e.type}"`);let u=[c,...l],d=[...new Set(u.flatMap(e=>e.tags))],f=u.some(e=>e.pinned),p=u.reduce((e,t)=>e+t.accessCount,0),m=await o.embed(i),h=a.overwrite(n,i,m),ee=new Set(c.tags);if((d.length!==c.tags.length||d.some(e=>!ee.has(e)))&&(h=a.update(n,{tags:d})),f&&!c.pinned&&(h=a.setPin(n,!0)),p>c.accessCount){let e=p-c.accessCount;for(let t=0;t<e;t++)a.incrementAccessCount(n);h=a.findById(n)??h}for(let e of l)a.delete(e.id);let[g]=a.findSimilar(m,c.type,c.projects[0]?.scopeHash);g!==void 0&&g.id!==n&&J(g.similarity)===`flag`&&a.createReviewEvent({memoryId:n,conflictingMemoryId:g.id,similarity:g.similarity,conflictContentSnapshot:i});let _=h.projects[0]?.scopeHash??`0000000000000000`;return s.logEvent({projectHash:_,eventType:`memory.updated`,memoryId:n,payload:{merged:r}}),h=a.findById(n)??h,{kept:h,dropped:r}}function Ne(e,t){t.resolveReviewEvents(e)}function Pe(e,t){return e.map(e=>{try{return t.findById(e)===void 0?{id:e,status:`error`,error:`Memory not found: ${e}`}:(t.resolveReviewEvents(e),{id:e,status:`ok`})}catch(t){return{id:e,status:`error`,error:t instanceof Error?t.message:String(t)}}})}async function Fe(e,t,n){let{repo:r,embedder:i,activityLogger:a=S}=n,o=r.getVersion(e,t);if(o===void 0)throw Error(`Version ${t} not found for memory: ${e}`);let s=await i.embed(o.content),c=r.update(e,{content:o.content},s),l=c.projects[0]?.scopeHash??`0000000000000000`;return a.logEvent({projectHash:l,eventType:`memory.updated`,memoryId:e,payload:{revertedToVersion:t}}),c}async function Ie(e,t){let{content:n,type:r,tags:i=[],projectScope:a,sourceHarness:o}=M.parse(e),{repo:s,embedder:c,activityLogger:u=S}=t,d=a?.hash??`0000000000000000`,f=await c.embed(n),[p]=s.findSimilar(f,r,a?.hash);if(p!==void 0){let e=J(p.similarity);if(e===`overwrite`){let e=s.overwrite(p.id,n,f);return u.logEvent({projectHash:d,eventType:`memory.updated`,memoryId:p.id}),e}if(e===`flag`){let e=s.create({id:(0,l.randomUUID)(),content:n,type:r,tags:i,sourceHarness:o??null,embedding:f,...a!==void 0&&{projectScope:a}});return s.createReviewEvent({memoryId:p.id,conflictingMemoryId:e.id,similarity:p.similarity,conflictContentSnapshot:n}),u.logEvent({projectHash:d,eventType:`memory.created`,memoryId:e.id}),u.logEvent({projectHash:d,eventType:`memory.flagged`,memoryId:p.id,payload:{conflictingMemoryId:e.id,similarity:p.similarity}}),e}}let m=s.create({id:(0,l.randomUUID)(),content:n,type:r,tags:i,sourceHarness:o??null,embedding:f,...a!==void 0&&{projectScope:a}});return u.logEvent({projectHash:d,eventType:`memory.created`,memoryId:m.id}),m}async function Le(e){let t=e.map((e,t)=>`Memory ${t+1}:\n${e}`).join(`
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
`),n=Object.fromEntries(Object.entries(process.env).filter(e=>e[1]!==void 0)),r=(0,_.query)({prompt:`Merge these memory entries into one concise memory:\n\n${t}`,options:{model:`claude-haiku-4-5-20251001`,systemPrompt:`You are a memory merge assistant. Given multiple memory entries identified as similar or overlapping, produce one concise merged memory that preserves all important information without redundancy. Output only the merged memory text — no preamble, no explanation, no metadata.`,allowedTools:[],settingSources:[],permissionMode:`bypassPermissions`,env:n}}),i=``;for await(let e of r)e.type===`result`&&e.subtype===`success`&&(i=e.result);if(!i)throw Error(`Merge suggestion returned empty result`);return i}async function Re(e,t,n){let{repo:r,embedder:i,activityLogger:a=S}=n,o=N.parse(t),s=o.content===void 0?void 0:await i.embed(o.content),c=r.update(e,o,s),l=c.projects[0]?.scopeHash??`0000000000000000`;return a.logEvent({projectHash:l,eventType:`memory.updated`,memoryId:e}),c}const Y=8e3;function ze(e){return e>=Y}var X=class{#e;#t;constructor(e,t){this.#e=e,this.#t=t}findSimilar(e,t,n){let r=Buffer.from(e.buffer),i;return i=n===void 0?this.#e.db.prepare(`SELECT m.rowid, m.*, (1 - vec_distance_cosine(e.embedding, ?)) AS similarity
|
|
303
307
|
FROM memories m JOIN embeddings e ON e.rowid = m.rowid
|
|
304
308
|
JOIN memory_projects mp ON mp.memory_id = m.id
|
|
305
309
|
JOIN projects p ON p.id = mp.project_id
|
|
@@ -310,10 +314,10 @@ CREATE INDEX idx_synthesis_versions_scope ON synthesis_versions(scope, version D
|
|
|
310
314
|
JOIN projects p ON p.id = mp.project_id
|
|
311
315
|
WHERE m.type = ? AND p.scope_hash = ?
|
|
312
316
|
ORDER BY similarity DESC LIMIT 1`).get(r,t,n),i===void 0?[]:[{id:i.id,similarity:i.similarity}]}create(e){let{id:t,content:n,type:r,tags:i,sourceHarness:a,embedding:o,projectScope:s}=e,c=new Date().toISOString(),l=Buffer.from(o.buffer);this.#e.db.prepare(`INSERT INTO memories (id, content, type, tags, source, access_count, pinned, created_at, updated_at)
|
|
313
|
-
VALUES (?, ?, ?, ?, ?, 0, 0, ?, ?)`).run(t,n,r,JSON.stringify(i),a,c,c),this.#e.db.prepare(`INSERT INTO embeddings (rowid, embedding) SELECT m.rowid, ? FROM memories m WHERE m.id = ?`).run(l,t);let u=s??{hash:`0000000000000000`,name:`global`},d=this.#t.upsertByHash(u.hash,u.name);return this.#t.addAssociation(t,d.id),
|
|
317
|
+
VALUES (?, ?, ?, ?, ?, 0, 0, ?, ?)`).run(t,n,r,JSON.stringify(i),a,c,c),this.#e.db.prepare(`INSERT INTO embeddings (rowid, embedding) SELECT m.rowid, ? FROM memories m WHERE m.id = ?`).run(l,t);let u=s??{hash:`0000000000000000`,name:`global`},d=this.#t.upsertByHash(u.hash,u.name);return this.#t.addAssociation(t,d.id),L(F.parse(this.#e.db.prepare(`SELECT * FROM memories WHERE id = ?`).get(t)),this.#t.getProjectsForMemories([t]).get(t)??[])}overwrite(e,t,n){let r=new Date().toISOString(),i=Buffer.from(n.buffer);this.#e.db.transaction(()=>{this.#r(e),this.#e.db.prepare(`UPDATE memories SET content = ?, updated_at = ? WHERE id = ?`).run(t,r,e)})();let a=this.#e.db.prepare(`SELECT rowid FROM memories WHERE id = ?`).get(e)?.rowid;a!==void 0&&this.#e.db.prepare(`UPDATE embeddings SET embedding = ? WHERE rowid = ?`).run(i,a);let o=F.parse(this.#e.db.prepare(`SELECT * FROM memories WHERE id = ?`).get(e)),s=this.#t.getProjectsForMemories([e]),c=this.#i([e]);return L(o,s.get(e)??[],c.get(e)??[])}findById(e){let t=this.#e.db.prepare(`SELECT * FROM memories WHERE id = ?`).get(e);if(t===void 0)return;let n=this.#t.getProjectsForMemories([e]),r=this.#i([e]);return L(t,n.get(e)??[],r.get(e)??[])}findManyById(e){if(e.length===0)return[];let t=e.map(()=>`?`).join(`, `),n=this.#e.db.prepare(`SELECT * FROM memories WHERE id IN (${t})`).all(...e);if(n.length===0)return[];let r=n.map(e=>e.id),i=this.#t.getProjectsForMemories(r),a=this.#i(r);return n.map(e=>L(e,i.get(e.id)??[],a.get(e.id)??[]))}update(e,t,n){let{content:r,tags:i,type:a}=N.parse(t),o=this.#e.db.prepare(`SELECT m.rowid, m.* FROM memories m WHERE m.id = ?`).get(e);if(o===void 0)throw Error(`Memory not found: ${e}`);let s=new Date().toISOString(),c=[`updated_at = ?`],l=[s];if(r!==void 0&&(c.push(`content = ?`),l.push(r)),i!==void 0&&(c.push(`tags = ?`),l.push(JSON.stringify(i))),a!==void 0&&(c.push(`type = ?`),l.push(a)),l.push(e),this.#e.db.transaction(()=>{r!==void 0&&this.#r(e),this.#e.db.prepare(`UPDATE memories SET ${c.join(`, `)} WHERE id = ?`).run(...l)})(),n!==void 0){let e=Buffer.from(n.buffer);this.#e.db.prepare(`UPDATE embeddings SET embedding = ? WHERE rowid = ?`).run(e,o.rowid)}let u=F.parse(this.#e.db.prepare(`SELECT * FROM memories WHERE id = ?`).get(e)),d=this.#t.getProjectsForMemories([e]),f=this.#i([e]);return L(u,d.get(e)??[],f.get(e)??[])}delete(e){let t=this.#e.db.prepare(`SELECT rowid FROM memories WHERE id = ?`).get(e);t!==void 0&&this.#e.db.prepare(`DELETE FROM embeddings WHERE rowid = ?`).run(t.rowid),this.#e.db.prepare(`DELETE FROM memory_projects WHERE memory_id = ?`).run(e),this.#e.db.prepare(`DELETE FROM memories WHERE id = ?`).run(e)}list(e){let t=[],n=[];e?.type!==void 0&&(t.push(`m.type = ?`),n.push(e.type)),e?.pinned===!0&&t.push(`m.pinned = 1`),e?.needsReview===!0&&t.push(`EXISTS (SELECT 1 FROM memory_review_events e WHERE e.memory_id = m.id AND e.resolved_at IS NULL)`),e?.projectId===`global`?(t.push(`EXISTS (SELECT 1 FROM memory_projects mp JOIN projects p ON p.id = mp.project_id WHERE mp.memory_id = m.id AND p.scope_hash = ?)`),n.push(c.r)):e?.projectId!==void 0&&(t.push(`m.id IN (SELECT memory_id FROM memory_projects WHERE project_id = ?)`),n.push(e.projectId));let r=t.length>0?`WHERE ${t.join(` AND `)}`:``,i=this.#e.db.prepare(`SELECT m.* FROM memories m ${r} ORDER BY m.created_at DESC`).all(...n);if(i.length===0)return[];let a=i.map(e=>e.id),o=this.#t.getProjectsForMemories(a),s=this.#i(a);return i.map(e=>L(e,o.get(e.id)??[],s.get(e.id)??[]))}listPinnedGlobal(){return this.listPinnedForProject(c.r)}listPinnedForProject(e){return this.#e.db.prepare(`SELECT m.* FROM memories m
|
|
314
318
|
JOIN memory_projects mp ON mp.memory_id = m.id
|
|
315
319
|
JOIN projects p ON p.id = mp.project_id
|
|
316
|
-
WHERE p.scope_hash = ? AND m.pinned = 1`).all(e).map(e=>
|
|
320
|
+
WHERE p.scope_hash = ? AND m.pinned = 1`).all(e).map(e=>L(e,[]))}listFlagged(e){let{projectHash:t,limit:n,minSimilarity:r,maxSimilarity:i}=e??{},a=[`e.resolved_at IS NULL`];r!==void 0&&a.push(`e.similarity >= ?`),i!==void 0&&a.push(`e.similarity <= ?`);let o=[r,i].filter(e=>e!==void 0),s=`EXISTS (
|
|
317
321
|
SELECT 1 FROM memory_review_events e
|
|
318
322
|
WHERE e.memory_id = memories.id AND ${a.join(` AND `)}
|
|
319
323
|
)`,c=n===void 0?``:`LIMIT ?`,l=n===void 0?[]:[n],u;if(u=t===void 0?this.#e.db.prepare(`SELECT * FROM memories
|
|
@@ -321,24 +325,24 @@ CREATE INDEX idx_synthesis_versions_scope ON synthesis_versions(scope, version D
|
|
|
321
325
|
ORDER BY created_at DESC ${c}`).all(...o,...l):this.#e.db.prepare(`SELECT * FROM memories
|
|
322
326
|
WHERE ${s}
|
|
323
327
|
AND ${this.#n()}
|
|
324
|
-
ORDER BY created_at DESC ${c}`).all(...o,t,...l),u.length===0)return[];let d=u.map(e=>e.id),f=this.#t.getProjectsForMemories(d),p=this.#i(d,{unresolvedOnly:!0});return u.map(e=>
|
|
328
|
+
ORDER BY created_at DESC ${c}`).all(...o,t,...l),u.length===0)return[];let d=u.map(e=>e.id),f=this.#t.getProjectsForMemories(d),p=this.#i(d,{unresolvedOnly:!0});return u.map(e=>L(e,f.get(e.id)??[],p.get(e.id)??[]))}listReviewEdges(e){return e===void 0?this.#e.db.prepare(`SELECT memory_id, conflicting_memory_id FROM memory_review_events
|
|
325
329
|
WHERE resolved_at IS NULL AND conflicting_memory_id IS NOT NULL`).all().map(e=>({memoryId:e.memory_id,conflictingMemoryId:e.conflicting_memory_id})):this.#e.db.prepare(`SELECT e.memory_id, e.conflicting_memory_id
|
|
326
330
|
FROM memory_review_events e
|
|
327
331
|
JOIN memories m ON m.id = e.memory_id
|
|
328
332
|
WHERE e.resolved_at IS NULL
|
|
329
333
|
AND e.conflicting_memory_id IS NOT NULL
|
|
330
|
-
AND ${this.#n(`m`)}`).all(e).map(e=>({memoryId:e.memory_id,conflictingMemoryId:e.conflicting_memory_id}))}listReviewEvents(e,t){let n=t?.unresolvedOnly===!0?`WHERE memory_id = ? AND resolved_at IS NULL`:`WHERE memory_id = ?`;return this.#e.db.prepare(`SELECT * FROM memory_review_events ${n} ORDER BY created_at DESC`).all(e).map(e=>
|
|
334
|
+
AND ${this.#n(`m`)}`).all(e).map(e=>({memoryId:e.memory_id,conflictingMemoryId:e.conflicting_memory_id}))}listReviewEvents(e,t){let n=t?.unresolvedOnly===!0?`WHERE memory_id = ? AND resolved_at IS NULL`:`WHERE memory_id = ?`;return this.#e.db.prepare(`SELECT * FROM memory_review_events ${n} ORDER BY created_at DESC`).all(e).map(e=>R(k.parse(e)))}createReviewEvent(e){let t=new Date().toISOString();this.#e.db.prepare(`INSERT INTO memory_review_events
|
|
331
335
|
(id, memory_id, conflicting_memory_id, similarity, conflict_content_snapshot, reason, created_at)
|
|
332
336
|
VALUES (?, ?, ?, ?, ?, 'similarity_dedup', ?)`).run((0,l.randomUUID)(),e.memoryId,e.conflictingMemoryId,e.similarity,e.conflictContentSnapshot,t)}resolveReviewEvents(e){let t=new Date().toISOString();this.#e.db.prepare(`UPDATE memory_review_events SET resolved_at = ? WHERE memory_id = ? AND resolved_at IS NULL`).run(t,e)}getPinnedCharCount(e){return e===void 0?(this.#e.db.prepare(`SELECT COALESCE(SUM(LENGTH(content)), 0) as total FROM memories WHERE pinned = 1`).get()??{total:0}).total:(this.#e.db.prepare(`SELECT COALESCE(SUM(LENGTH(content)), 0) as total FROM memories
|
|
333
|
-
WHERE pinned = 1 AND ${this.#n()}`).get(e)??{total:0}).total}stats(e){let t=Object.fromEntries(
|
|
337
|
+
WHERE pinned = 1 AND ${this.#n()}`).get(e)??{total:0}).total}stats(e){let t=Object.fromEntries(C.map(e=>[e,0]));if(e!==void 0){let n=this.#e.db.prepare(`SELECT type, COUNT(*) as count FROM memories
|
|
334
338
|
WHERE ${this.#n()}
|
|
335
|
-
GROUP BY type`).all(e);for(let e of n){let n=
|
|
339
|
+
GROUP BY type`).all(e);for(let e of n){let n=w.safeParse(e.type);n.success&&(t[n.data]=e.count)}let r=this.#e.db.prepare(`SELECT COUNT(*) as total, SUM(pinned) as pinned,
|
|
336
340
|
COALESCE(SUM(CASE WHEN pinned = 1 THEN LENGTH(content) ELSE 0 END), 0) as pinBudgetChars
|
|
337
341
|
FROM memories WHERE ${this.#n()}`).get(e)??{total:0,pinned:0,pinBudgetChars:0},i=this.#e.db.prepare(`SELECT COUNT(DISTINCT e.memory_id) as needsReview
|
|
338
342
|
FROM memory_review_events e
|
|
339
343
|
JOIN memories m ON m.id = e.memory_id
|
|
340
344
|
WHERE e.resolved_at IS NULL
|
|
341
|
-
AND ${this.#n(`m`)}`).get(e)??{needsReview:0};return{byType:t,total:r.total,pinned:r.pinned??0,needsReview:i.needsReview,pinBudgetChars:r.pinBudgetChars}}let n=this.#e.db.prepare(`SELECT type, COUNT(*) as count FROM memories GROUP BY type`).all();for(let e of n){let n=
|
|
345
|
+
AND ${this.#n(`m`)}`).get(e)??{needsReview:0};return{byType:t,total:r.total,pinned:r.pinned??0,needsReview:i.needsReview,pinBudgetChars:r.pinBudgetChars}}let n=this.#e.db.prepare(`SELECT type, COUNT(*) as count FROM memories GROUP BY type`).all();for(let e of n){let n=w.safeParse(e.type);n.success&&(t[n.data]=e.count)}let r=this.#e.db.prepare(`SELECT COUNT(*) as total, SUM(pinned) as pinned FROM memories`).get()??{total:0,pinned:0},i=this.#e.db.prepare(`SELECT COUNT(DISTINCT memory_id) as needsReview FROM memory_review_events WHERE resolved_at IS NULL`).get()??{needsReview:0};return{byType:t,total:r.total,pinned:r.pinned??0,needsReview:i.needsReview,pinBudgetChars:this.getPinnedCharCount()}}reviewQueueStats(e){let t=e===void 0?`JOIN memories m ON m.id = e.memory_id WHERE e.resolved_at IS NULL`:`JOIN memories m ON m.id = e.memory_id
|
|
342
346
|
WHERE e.resolved_at IS NULL AND ${this.#n(`m`)}`,n=e===void 0?[]:[e],r=this.#e.db.prepare(`SELECT
|
|
343
347
|
CASE
|
|
344
348
|
WHEN e.similarity >= 0.85 THEN 'high'
|
|
@@ -349,11 +353,11 @@ CREATE INDEX idx_synthesis_versions_scope ON synthesis_versions(scope, version D
|
|
|
349
353
|
FROM memory_review_events e ${t}
|
|
350
354
|
GROUP BY band`).all(...n),i=this.#e.db.prepare(`SELECT m.type, COUNT(DISTINCT e.memory_id) AS count
|
|
351
355
|
FROM memory_review_events e ${t}
|
|
352
|
-
GROUP BY m.type`).all(...n),a=this.#e.db.prepare(`SELECT COUNT(*) AS pairs FROM memory_review_events e ${t}`).get(...n)??{pairs:0},o={high:0,mid:0,low:0};for(let e of r)(e.band===`high`||e.band===`mid`||e.band===`low`)&&(o[e.band]=e.count);let s={};for(let e of i){let t=
|
|
356
|
+
GROUP BY m.type`).all(...n),a=this.#e.db.prepare(`SELECT COUNT(*) AS pairs FROM memory_review_events e ${t}`).get(...n)??{pairs:0},o={high:0,mid:0,low:0};for(let e of r)(e.band===`high`||e.band===`mid`||e.band===`low`)&&(o[e.band]=e.count);let s={};for(let e of i){let t=w.safeParse(e.type);t.success&&(s[t.data]=e.count)}return{pairs:a.pairs,byBand:o,byType:s}}setPin(e,t){if(this.#e.db.prepare(`SELECT * FROM memories WHERE id = ?`).get(e)===void 0)throw Error(`Memory not found: ${e}`);let n=new Date().toISOString();this.#e.db.prepare(`UPDATE memories SET pinned = ?, updated_at = ? WHERE id = ?`).run(+!!t,n,e);let r=F.parse(this.#e.db.prepare(`SELECT * FROM memories WHERE id = ?`).get(e)),i=this.#t.getProjectsForMemories([e]),a=this.#i([e]);return L(r,i.get(e)??[],a.get(e)??[])}incrementAccessCount(e){this.#e.db.prepare(`UPDATE memories SET access_count = access_count + 1 WHERE id = ?`).run(e)}exportAll(){return this.#e.db.prepare(`SELECT m.*, e.embedding FROM memories m LEFT JOIN embeddings e ON e.rowid = m.rowid ORDER BY m.created_at DESC`).all().map(e=>({id:e.id,content:e.content,type:w.parse(e.type),tags:T.parse(JSON.parse(e.tags)),sourceHarness:e.source,accessCount:e.access_count,pinned:e.pinned!==0,createdAt:e.created_at,updatedAt:e.updated_at,embedding:e.embedding===null?null:new Float32Array(e.embedding.buffer,e.embedding.byteOffset,e.embedding.byteLength/4)}))}importAll(e){let t=this.#e.db.prepare(`INSERT OR REPLACE INTO memories (id, content, type, tags, source, access_count, pinned, created_at, updated_at)
|
|
353
357
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`),n=this.#e.db.prepare(`INSERT OR REPLACE INTO embeddings (rowid, embedding) SELECT m.rowid, ? FROM memories m WHERE m.id = ?`);this.#e.db.transaction(()=>{for(let r of e)t.run(r.id,r.content,r.type,JSON.stringify(r.tags),r.sourceHarness,r.accessCount,+!!r.pinned,r.createdAt,r.updatedAt),r.embedding!==null&&n.run(Buffer.from(r.embedding.buffer,r.embedding.byteOffset,r.embedding.byteLength),r.id)})()}#n(e=`memories`){return`EXISTS (
|
|
354
358
|
SELECT 1 FROM memory_projects mp JOIN projects p ON p.id = mp.project_id
|
|
355
359
|
WHERE mp.memory_id = ${e}.id AND (p.scope_hash = ? OR p.scope_hash = '${c.r}')
|
|
356
|
-
)`}listVersions(e){return this.#e.db.prepare(`SELECT * FROM memory_versions WHERE memory_id = ? ORDER BY version DESC`).all(e).map(
|
|
360
|
+
)`}listVersions(e){return this.#e.db.prepare(`SELECT * FROM memory_versions WHERE memory_id = ? ORDER BY version DESC`).all(e).map(B)}getVersion(e,t){let n=this.#e.db.prepare(`SELECT * FROM memory_versions WHERE memory_id = ? AND version = ?`).get(e,t);return n===void 0?void 0:B(n)}#r(e){let t=this.#e.db.prepare(`SELECT m.content, COALESCE(MAX(v.version), 0) + 1 AS next_version
|
|
357
361
|
FROM memories m
|
|
358
362
|
LEFT JOIN memory_versions v ON v.memory_id = m.id
|
|
359
363
|
WHERE m.id = ?
|
|
@@ -361,30 +365,30 @@ CREATE INDEX idx_synthesis_versions_scope ON synthesis_versions(scope, version D
|
|
|
361
365
|
SELECT MAX(version) - 10 FROM memory_versions WHERE memory_id = ?
|
|
362
366
|
)`).run(e,e))}#i(e,t){if(e.length===0)return new Map;let n=e.map(()=>`?`).join(`, `),r=t?.unresolvedOnly===!0?`AND resolved_at IS NULL`:``,i=this.#e.db.prepare(`SELECT * FROM memory_review_events
|
|
363
367
|
WHERE memory_id IN (${n}) ${r}
|
|
364
|
-
ORDER BY created_at DESC`).all(...e),a=new Map;for(let e of i){let t=
|
|
368
|
+
ORDER BY created_at DESC`).all(...e),a=new Map;for(let e of i){let t=R(k.parse(e)),n=a.get(t.memoryId)??[];n.push(t),a.set(t.memoryId,n)}return a}};function Be(e,t){return new X(e,t)}const Ve=(0,re.promisify)(ne.execFile);function Z(e){return(0,l.createHash)(`sha256`).update(e).digest(`hex`).slice(0,16)}async function He(){try{let{stdout:e}=await Ve(`git`,[`remote`,`get-url`,`origin`]),t=e.trim();if(t){let e=Z(t);return{hash:e,name:t.split(`/`).pop()?.replace(/\.git$/,``)??e.slice(0,8)}}}catch{}let e=process.cwd(),t=Z(e);return{hash:t,name:e.split(/[/\\]/).filter(Boolean).pop()??t.slice(0,8)}}async function Ue(){try{let{stdout:e}=await Ve(`git`,[`remote`,`get-url`,`origin`]),t=e.trim();if(t)return Z(t)}catch{}return Z(process.cwd())}const We=[{name:`scope-to-projects`,description:`Rename the auto-migrated project for the current directory from its generic hash-derived name to the resolved repo/directory name.`}];async function Ge(e){let t=await He(),n=e.getByHash(t.hash);if(n===void 0)return null;let r=n.name,i=e.countMemories(n.id);return e.rename(n.id,t.name),{migration:`scope-to-projects`,oldName:r,newName:t.name,memoryCount:i}}var Ke=class{#e;constructor(e){this.#e=e}upsertByHash(e,t){if(!/^[0-9a-f]{16}$/.test(e))throw Error(`Invalid scope hash "${e}": expected 16 lowercase hex characters`);let n=new Date().toISOString(),r=e===`0000000000000000`?c.t:(0,l.randomUUID)(),i=e===`0000000000000000`?c.n:t;return this.#e.db.prepare(`INSERT OR IGNORE INTO projects (id, name, scope_hash, created_at, updated_at) VALUES (?, ?, ?, ?, ?)`).run(r,i,e,n,n),z(I.parse(this.#e.db.prepare(`SELECT * FROM projects WHERE scope_hash = ?`).get(e)))}rename(e,t){let n=new Date().toISOString();this.#e.db.prepare(`UPDATE projects SET name = ?, updated_at = ? WHERE id = ?`).run(t,n,e);let r=this.#e.db.prepare(`SELECT * FROM projects WHERE id = ?`).get(e);if(r===void 0)throw Error(`Project not found: ${e}`);return z(r)}list(){return this.#e.db.prepare(`SELECT * FROM projects ORDER BY name ASC`).all().map(z)}getByHash(e){let t=this.#e.db.prepare(`SELECT * FROM projects WHERE scope_hash = ?`).get(e);return t===void 0?void 0:z(t)}getByName(e){let t=this.#e.db.prepare(`SELECT * FROM projects WHERE name = ? LIMIT 1`).get(e);return t===void 0?void 0:z(t)}addAssociation(e,t){this.#e.db.prepare(`INSERT OR IGNORE INTO memory_projects (memory_id, project_id) VALUES (?, ?)`).run(e,t)}removeAssociation(e,t){this.#e.db.prepare(`DELETE FROM memory_projects WHERE memory_id = ? AND project_id = ?`).run(e,t)}countMemories(e){return this.#e.db.prepare(`SELECT COUNT(*) AS count FROM memory_projects WHERE project_id = ?`).get(e)?.count??0}getProjectsForMemories(e){if(e.length===0)return new Map;let t=e.map(()=>`?`).join(`,`),n=this.#e.db.prepare(`SELECT p.*, mp.memory_id FROM projects p
|
|
365
369
|
JOIN memory_projects mp ON mp.project_id = p.id
|
|
366
|
-
WHERE mp.memory_id IN (${t})`).all(...e),r=new Map;for(let e of n){let t=r.get(e.memory_id)??[];t.push(
|
|
370
|
+
WHERE mp.memory_id IN (${t})`).all(...e),r=new Map;for(let e of n){let t=r.get(e.memory_id)??[];t.push(z(e)),r.set(e.memory_id,t)}return r}};function qe(e){return new Ke(e)}const Je={correction:1,preference:.8,decision:.6,learning:.4,fact:.2};function Ye(e,t,n){let r=Je[e.type],i=e.accessCount/(e.accessCount+10),a=1/(1+(n-new Date(e.updatedAt).getTime())/864e5),o=+!!e.pinned;return t*.4+r*.25+i*.2+a*.1+o*.05}async function Q(e,t){let{query:n,type:r,projectHash:i,limit:a=10,includePinned:o}=j.parse(e),{activityLogger:s=S}=t,c=await t.embedder.embed(n),l=Buffer.from(c.buffer),u=t.adapter.findByEmbedding(l,{...r!==void 0&&{type:r},...i!==void 0&&{projectHash:i},...o!==void 0&&{includePinned:o}}),d=Date.now(),f=u.filter(e=>e.cosineSim>0).map(e=>{let{cosineSim:t,...n}=e;return{...n,score:Ye(n,t,d)}});f.sort((e,t)=>t.score-e.score);let p=f.slice(0,a);for(let e of p)t.repo.incrementAccessCount(e.id);return s.logEvent({projectHash:i??`0000000000000000`,eventType:`memory.queried`,payload:{resultCount:p.length,topScores:p.slice(0,3).map(e=>e.score)}}),p}var Xe=class{#e;constructor(e){this.#e=e}findByEmbedding(e,t){let{type:n,projectHash:r,includePinned:i}=t,a=[],o=[e],s=``;i||a.push(`m.pinned = 0`),n!==void 0&&(a.push(`m.type = ?`),o.push(n)),r!==void 0&&(s=`JOIN memory_projects mp ON mp.memory_id = m.id JOIN projects p ON p.id = mp.project_id`,a.push(`(p.scope_hash = ? OR p.scope_hash = ?)`),o.push(r,c.r));let l=a.length>0?`WHERE ${a.join(` AND `)}`:``,u=`
|
|
367
371
|
SELECT m.*, (1 - vec_distance_cosine(e.embedding, ?)) AS cosine_sim
|
|
368
372
|
FROM memories m JOIN embeddings e ON e.rowid = m.rowid
|
|
369
373
|
${s}
|
|
370
374
|
${l}
|
|
371
|
-
`;return this.#e.db.prepare(u).all(...o).map(e=>({...
|
|
375
|
+
`;return this.#e.db.prepare(u).all(...o).map(e=>({...L(e,[]),cosineSim:e.cosine_sim}))}},Ze=class{#e;#t;#n;#r;constructor(e,t,n,r=S){this.#e=e,this.#t=t,this.#n=n,this.#r=r}async query(e){return Q(e,{adapter:new Xe(this.#e),repo:this.#n,embedder:this.#t,activityLogger:this.#r})}};function Qe(e,t){let n=t.repo.stats(e.projectHash);return e.synthesis!==void 0&&e.synthesis.length>0?{stats:n.byType,pinnedGlobal:[],pinnedProject:[],synthesis:e.synthesis}:{stats:n.byType,pinnedGlobal:t.repo.listPinnedGlobal(),pinnedProject:t.repo.listPinnedForProject(e.projectHash)}}function $e(){return[...C]}var et=class{#e;constructor(e){this.#e=e}getSessionContext(e,t){return Qe({projectHash:e,...t!==void 0&&{synthesis:t}},{repo:this.#e})}},tt=class{#e;#t;#n;#r=new Set;#i=new Map;#a=!1;#o;#s=new Map;constructor(e,t,n){this.#e=e,this.#t=t,this.#n=n}async init(){this.#e.clearStaleInFlight(this.#t.inFlightTimeoutMs??12e4),this.#e.expireStale();let e=this.#e.getExpiredOrDirtyScopes();for(let{scope:t}of e)this.#r.add(t);this.#a=!0,await this.#l()}shutdown(){this.#a=!1,this.#o!==void 0&&(clearTimeout(this.#o),this.#o=void 0);let e=[...this.#s.values()];return e.length===0?Promise.resolve():Promise.race([Promise.allSettled(e).then(()=>void 0),new Promise(e=>setTimeout(e,5e3))])}markDirty(e){this.#r.add(e)}#c(){if(!this.#a)return;let e=this.#t.debounceMs??45e3;this.#o=setTimeout(()=>{this.#l()},e)}async#l(){let e=[...this.#r];for(let t of e){let e=this.#t.inFlightTimeoutMs??12e4,n=this.#e.getSynthesis(t);if(n?.inFlightSince!==null&&n?.inFlightSince!==void 0){if(Date.now()-new Date(n.inFlightSince).getTime()<e)continue;this.#e.clearInFlight(t)}this.#r.delete(t);let r=this.#u(t).finally(()=>{this.#s.delete(t)});this.#s.set(t,r)}this.#c()}async#u(e){this.#e.markInFlight(e);try{let t=e===`0000000000000000`?void 0:e,n=await this.#n.run(e,t),r=this.#e.computeSourceMemoryHash(e);this.#e.saveSynthesis(e,n,r),this.#i.delete(e)}catch(t){let n=(this.#i.get(e)??0)+1;this.#i.set(e,n);let r=Math.min(n,5),i=(this.#t.debounceMs??45e3)*r;process.stderr.write(`membank synthesis: error for scope=${e} failures=${n} backoff=${i}ms: ${t instanceof Error?t.message:String(t)}\n`),setTimeout(()=>{this.#r.add(e)},i),this.#e.clearInFlight(e)}}};function nt(e,t,n){let r=n.getVersion(e,t);if(r===void 0)throw Error(`Version ${t} not found for scope: ${e}`);return n.saveSynthesis(e,r.content,r.sourceMemoryHash)}async function rt(e,t){let n=e===`0000000000000000`?void 0:e;t.synthRepo.markInFlight(e);try{let[r,i]=await Promise.all([t.agentRunner.run(e,n),Promise.resolve(t.synthRepo.computeSourceMemoryHash(e))]);return t.synthRepo.saveSynthesis(e,r,i),r}catch(n){throw t.synthRepo.clearInFlight(e),n}}var it=class{#e;constructor(e,t){this.#e=e}async run(e,t){let n=(0,_.createSdkMcpServer)({name:`membank-synthesis-tools`,version:`1.0.0`,tools:[(0,_.tool)(`query_memory`,`Search memories by semantic similarity`,{query:u.z.string().describe(`Search text`),limit:u.z.number().optional().describe(`Maximum results to return`),global:u.z.boolean().optional().describe(`Query global memories only when true, otherwise current project scope`)},async({query:e,limit:n,global:r})=>({content:[{type:`text`,text:await this.#e.queryMemory({query:e,...n!==void 0&&{limit:n},...r!==void 0&&{global:r},...t!==void 0&&{projectHash:t}})}]}),{annotations:{readOnlyHint:!0}}),(0,_.tool)(`get_memory_summary`,`Returns aggregate stats: total memories, counts by type, pinned count, review queue size`,{},async()=>({content:[{type:`text`,text:await this.#e.getMemorySummary()}]}),{annotations:{readOnlyHint:!0}})]}),r=`Synthesize the memories for ${e===`0000000000000000`?`global (across all projects)`:`project scope: ${e}`}. Use get_memory_summary first to understand the overall state, then use query_memory to retrieve relevant memories (query with broad terms like "preferences", "corrections", "decisions", "key facts"). After gathering information, produce a concise synthesis of the most important things to remember about this user. Output only the synthesis text — no preamble, no metadata.`,i=Date.now(),a=Object.fromEntries(Object.entries(process.env).filter(e=>e[1]!==void 0)),o=(0,_.query)({prompt:r,options:{model:`claude-haiku-4-5-20251001`,systemPrompt:`You are a memory synthesizer. Your job is to read the user's stored memories and produce a concise, well-structured summary of what's most important to remember about this user — their preferences, corrections, decisions, and key facts. Pinned memories are higher fidelity and should be weighted more heavily. Exclude transient or ephemeral details. Output plain text suitable for injection into an LLM context window. Be concise — target 200-400 words.`,mcpServers:{"membank-synthesis-tools":n},allowedTools:[`mcp__membank-synthesis-tools__query_memory`,`mcp__membank-synthesis-tools__get_memory_summary`],disallowedTools:[`mcp__membank__*`],settingSources:[],permissionMode:`bypassPermissions`,env:a}}),s=``;for await(let e of o)if(e.type===`result`)if(e.subtype===`success`)s=e.result;else{let t=`errors`in e&&Array.isArray(e.errors)?`: ${e.errors.join(`; `)}`:``;throw Error(`Synthesis agent failed: ${e.subtype}${t}`)}let c=Date.now()-i;if(process.stderr.write(`membank synthesis: scope=${e} duration=${c}ms\n`),s===``)throw Error(`Synthesis agent returned empty result`);return s}};function at(e,t){return new it(e,t)}function ot(e){return P.parse({id:e.id,scope:e.scope,content:e.content,sourceMemoryHash:e.source_memory_hash,synthesizedAt:e.synthesized_at,expiresAt:e.expires_at,inFlightSince:e.in_flight_since,createdAt:e.created_at,updatedAt:e.updated_at})}function $(e){return e.content===`pending`&&e.source_memory_hash===``}var st=class{#e;constructor(e){this.#e=e}saveSynthesis(e,t,n){let r=new Date().toISOString(),i=new Date(Date.now()+720*60*60*1e3).toISOString(),{id:a,createdAt:o}=this.#e.db.transaction(()=>{let a=this.#e.db.prepare(`SELECT * FROM syntheses WHERE scope = ?`).get(e);if(a!==void 0)return $(a)||this.#t(e),this.#e.db.prepare(`UPDATE syntheses
|
|
372
376
|
SET content = ?, source_memory_hash = ?, synthesized_at = ?, expires_at = ?,
|
|
373
377
|
in_flight_since = NULL, updated_at = ?
|
|
374
378
|
WHERE scope = ?`).run(t,n,r,i,r,e),{id:a.id,createdAt:a.created_at};let o=(0,l.randomUUID)();return this.#e.db.prepare(`INSERT INTO syntheses
|
|
375
379
|
(id, scope, content, source_memory_hash, synthesized_at, expires_at,
|
|
376
380
|
in_flight_since, created_at, updated_at)
|
|
377
|
-
VALUES (?, ?, ?, ?, ?, ?, NULL, ?, ?)`).run(o,e,t,n,r,i,r,r),{id:o,createdAt:r}})();return
|
|
381
|
+
VALUES (?, ?, ?, ?, ?, ?, NULL, ?, ?)`).run(o,e,t,n,r,i,r,r),{id:o,createdAt:r}})();return P.parse({id:a,scope:e,content:t,sourceMemoryHash:n,synthesizedAt:r,expiresAt:i,inFlightSince:null,createdAt:o,updatedAt:r})}listVersions(e){return this.#e.db.prepare(`SELECT * FROM synthesis_versions WHERE scope = ? ORDER BY version DESC`).all(e).map(V)}getVersion(e,t){let n=this.#e.db.prepare(`SELECT * FROM synthesis_versions WHERE scope = ? AND version = ?`).get(e,t);return n===void 0?void 0:V(n)}#t(e){let t=this.#e.db.prepare(`SELECT s.content, s.source_memory_hash, s.synthesized_at,
|
|
378
382
|
COALESCE(MAX(v.version), 0) + 1 AS next_version
|
|
379
383
|
FROM syntheses s
|
|
380
384
|
LEFT JOIN synthesis_versions v ON v.scope = s.scope
|
|
381
385
|
WHERE s.scope = ?
|
|
382
386
|
GROUP BY s.scope`).get(e);t!==void 0&&(this.#e.db.prepare(`INSERT INTO synthesis_versions (scope, version, content, source_memory_hash, synthesized_at)
|
|
383
|
-
VALUES (?, ?, ?, ?, ?)`).run(e,t.next_version,t.content,t.source_memory_hash,t.synthesized_at),this.#e.db.prepare(`DELETE FROM synthesis_versions WHERE scope = ? AND version <= ?`).run(e,t.next_version-5))}getSynthesis(e){let t=this.#e.db.prepare(`SELECT * FROM syntheses WHERE scope = ?`).get(e);return t===void 0?void 0:
|
|
387
|
+
VALUES (?, ?, ?, ?, ?)`).run(e,t.next_version,t.content,t.source_memory_hash,t.synthesized_at),this.#e.db.prepare(`DELETE FROM synthesis_versions WHERE scope = ? AND version <= ?`).run(e,t.next_version-5))}getSynthesis(e){let t=this.#e.db.prepare(`SELECT * FROM syntheses WHERE scope = ?`).get(e);return t===void 0?void 0:ot(t)}listAll(){return this.#e.db.prepare(`SELECT * FROM syntheses ORDER BY scope`).all().map(ot)}markInFlight(e){let t=new Date().toISOString();if(this.#e.db.prepare(`SELECT id FROM syntheses WHERE scope = ?`).get(e)!==void 0)this.#e.db.prepare(`UPDATE syntheses SET in_flight_since = ?, updated_at = ? WHERE scope = ?`).run(t,t,e);else{let n=(0,l.randomUUID)(),r=new Date(Date.now()+720*60*60*1e3).toISOString();this.#e.db.prepare(`INSERT INTO syntheses
|
|
384
388
|
(id, scope, content, source_memory_hash, synthesized_at, expires_at,
|
|
385
389
|
in_flight_since, created_at, updated_at)
|
|
386
390
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(n,e,`pending`,``,t,r,t,t,t)}}clearInFlight(e){let t=new Date().toISOString();this.#e.db.prepare(`UPDATE syntheses SET in_flight_since = NULL, updated_at = ? WHERE scope = ?`).run(t,e)}clearStaleInFlight(e){let t=new Date(Date.now()-e).toISOString(),n=new Date().toISOString();this.#e.db.prepare(`UPDATE syntheses SET in_flight_since = NULL, updated_at = ? WHERE in_flight_since IS NOT NULL AND in_flight_since < ?`).run(n,t)}computeSourceMemoryHash(e){let t=this.#e.db.prepare(`SELECT m.content FROM memories m
|
|
387
391
|
JOIN memory_projects mp ON mp.memory_id = m.id
|
|
388
392
|
JOIN projects p ON p.id = mp.project_id
|
|
389
393
|
WHERE p.scope_hash = ?
|
|
390
|
-
ORDER BY m.id`).all(e);return(0,l.createHash)(`sha256`).update(JSON.stringify(t.map(e=>e.content))).digest(`hex`)}getExpiredOrDirtyScopes(){let e=this.getAllActiveScopes(),t=new Date().toISOString(),n=[];for(let r of e){let e=this.#e.db.prepare(`SELECT * FROM syntheses WHERE scope = ?`).get(r);if(e===void 0||$(e)){n.push({scope:r,reason:`missing`});continue}if(e.expires_at<=t){n.push({scope:r,reason:`expired`});continue}this.computeSourceMemoryHash(r)!==e.source_memory_hash&&n.push({scope:r,reason:`dirty`})}return n}getAllActiveScopes(){return this.#e.db.prepare(`SELECT DISTINCT scope_hash FROM projects`).all().map(e=>e.scope_hash)}expireStale(){let e=new Date().toISOString();this.#e.db.prepare(`DELETE FROM syntheses WHERE expires_at < ?`).run(e)}};function
|
|
394
|
+
ORDER BY m.id`).all(e);return(0,l.createHash)(`sha256`).update(JSON.stringify(t.map(e=>e.content))).digest(`hex`)}getExpiredOrDirtyScopes(){let e=this.getAllActiveScopes(),t=new Date().toISOString(),n=[];for(let r of e){let e=this.#e.db.prepare(`SELECT * FROM syntheses WHERE scope = ?`).get(r);if(e===void 0||$(e)){n.push({scope:r,reason:`missing`});continue}if(e.expires_at<=t){n.push({scope:r,reason:`expired`});continue}this.computeSourceMemoryHash(r)!==e.source_memory_hash&&n.push({scope:r,reason:`dirty`})}return n}getAllActiveScopes(){return this.#e.db.prepare(`SELECT DISTINCT scope_hash FROM projects`).all().map(e=>e.scope_hash)}expireStale(){let e=new Date().toISOString();this.#e.db.prepare(`DELETE FROM syntheses WHERE expires_at < ?`).run(e)}};function ct(e){return new st(e)}exports.ACTIVITY_EVENT_TYPE_VALUES=v,exports.ActivityEventTypeSchema=y,exports.DatabaseError=U,exports.DatabaseManager=he,exports.EmbeddingService=ve,exports.GLOBAL_PROJECT_ID=c.t,exports.GLOBAL_PROJECT_NAME=c.n,exports.GLOBAL_SCOPE_HASH=c.r,exports.MEMORY_TYPE_VALUES=C,exports.MIGRATIONS=We,exports.MODEL_NAME=W,exports.MembankError=H,exports.MemoryPatchSchema=N,exports.MemoryRowSchema=F,exports.MemorySchema=A,exports.MemoryTypeSchema=w,exports.MemoryVersionRowSchema=de,exports.ModelDownloadError=G,exports.ModelDownloader=_e,exports.PIN_BUDGET_THRESHOLD=Y,exports.ProjectRowSchema=I,exports.ProjectSchema=E,exports.QueryEngine=Ze,exports.QueryOptionsSchema=j,exports.RETENTION_DAYS=30,exports.ReviewEventRowSchema=k,exports.ReviewEventSchema=O,exports.ReviewReasonSchema=D,exports.SaveOptionsSchema=M,exports.SessionContextBuilder=et,exports.SessionContextSchema=ue,exports.SqliteMemoryRepository=X,exports.SynthesisEngine=tt,exports.SynthesisSchema=P,exports.SynthesisVersionRowSchema=fe,exports.TagsJsonSchema=T,exports.clusterFlagged=Ae,exports.createActivityLogger=se,exports.createActivityRepository=oe,exports.createClaudeCodeTranscriptReader=ke,exports.createExtractionAgentRunner=Se,exports.createExtractionRunRepository=Ee,exports.createMemoryRepository=Be,exports.createProjectRepository=qe,exports.createSynthesisAgentRunner=at,exports.createSynthesisRepository=ct,exports.deleteManyMemories=je,exports.deleteMemory=q,exports.getSessionContext=Qe,exports.isOverBudget=ze,exports.isSynthesisEnabled=le,exports.listEvents=ie,exports.listMemoryTypes=$e,exports.logEvent=b,exports.mergeMemories=Me,exports.noopActivityLogger=S,exports.queryMemories=Q,exports.resolveProject=He,exports.resolveReview=Ne,exports.resolveReviewMany=Pe,exports.resolveScope=Ue,exports.revertMemory=Fe,exports.revertSynthesis=nt,exports.rowToMemory=L,exports.rowToProject=z,exports.runExtraction=ye,exports.runScopeToProjectsMigration=Ge,exports.runSynthesis=rt,exports.saveMemory=Ie,exports.suggestMerge=Le,exports.updateMemory=Re;
|
package/dist/index.d.cts
CHANGED
|
@@ -674,6 +674,9 @@ declare function saveMemory(opts: SaveOptions, deps: {
|
|
|
674
674
|
activityLogger?: ActivityLogger;
|
|
675
675
|
}): Promise<Memory>;
|
|
676
676
|
//#endregion
|
|
677
|
+
//#region src/memory/application/suggest-merge.d.ts
|
|
678
|
+
declare function suggestMerge(contents: readonly string[]): Promise<string>;
|
|
679
|
+
//#endregion
|
|
677
680
|
//#region src/memory/application/update-memory.d.ts
|
|
678
681
|
declare function updateMemory(id: string, patch: MemoryPatch, deps: {
|
|
679
682
|
repo: MemoryRepository;
|
|
@@ -882,5 +885,5 @@ declare function createSynthesisAgentRunner(tools: SynthesisTools, config: Synth
|
|
|
882
885
|
//#region src/synthesis/infrastructure/sqlite-synthesis-repository.d.ts
|
|
883
886
|
declare function createSynthesisRepository(db: DatabaseManager): SynthesisRepository;
|
|
884
887
|
//#endregion
|
|
885
|
-
export { ACTIVITY_EVENT_TYPE_VALUES, type ActivityEvent, type ActivityEventInput, type ActivityEventType, ActivityEventTypeSchema, type ActivityLogger, type ActivityRepository, type AgentRunner, type BulkOpResult, type CreateMemoryOpts, type CreateReviewEventOpts, DatabaseError, DatabaseManager, type DownloadProgress, type DownloadResult, type Embedder, EmbeddingService, type ExtractionAgentRunner, type ExtractionConfig, type ExtractionRunRecord, type ExtractionRunRepository, type ExtractionTools, type FlagCluster, GLOBAL_PROJECT_ID, GLOBAL_PROJECT_NAME, GLOBAL_SCOPE_HASH, type ListEventsFilter, MEMORY_TYPE_VALUES, MIGRATIONS, MODEL_NAME, MembankError, type Memory, type MemoryExportRecord, type MemoryPatch, MemoryPatchSchema, type MemoryRepository, type MemoryRow, MemoryRowSchema, MemorySchema, type MemoryType, MemoryTypeSchema, type MemoryVersion, MemoryVersionRow, MemoryVersionRowSchema, type MergeMemoriesOpts, type MergeMemoriesResult, MigrationMeta, ModelDownloadError, ModelDownloader, PIN_BUDGET_THRESHOLD, type ProgressCallback, Project, type ProjectRepository, ProjectRow, ProjectRowSchema, ProjectSchema, type Querier, type QueryAdapter, QueryEngine, QueryOptions, QueryOptionsSchema, RETENTION_DAYS, type ReviewEvent, type ReviewEventRow, ReviewEventRowSchema, ReviewEventSchema, type ReviewQueueStats, ReviewReason, ReviewReasonSchema, type RunExtractionInput, type RunExtractionResult, type SaveOptions, SaveOptionsSchema, ScopeToProjectsResult, type ScoredMemory, SessionContext, SessionContextBuilder, SessionContextSchema, type SimilarMemoryResult, SqliteMemoryRepository, type StatsResult, Synthesis, type SynthesisConfig, SynthesisEngine, type SynthesisRepository, SynthesisSchema, type SynthesisTools, type SynthesisVersion, SynthesisVersionRow, SynthesisVersionRowSchema, TagsJsonSchema, type TranscriptReader, clusterFlagged, createActivityLogger, createActivityRepository, createClaudeCodeTranscriptReader, createExtractionAgentRunner, createExtractionRunRepository, createMemoryRepository, createProjectRepository, createSynthesisAgentRunner, createSynthesisRepository, deleteManyMemories, deleteMemory, getSessionContext, isOverBudget, isSynthesisEnabled, listEvents, listMemoryTypes, logEvent, mergeMemories, noopActivityLogger, queryMemories, resolveProject, resolveReview, resolveReviewMany, resolveScope, revertMemory, revertSynthesis, rowToMemory, rowToProject, runExtraction, runScopeToProjectsMigration, runSynthesis, saveMemory, updateMemory };
|
|
888
|
+
export { ACTIVITY_EVENT_TYPE_VALUES, type ActivityEvent, type ActivityEventInput, type ActivityEventType, ActivityEventTypeSchema, type ActivityLogger, type ActivityRepository, type AgentRunner, type BulkOpResult, type CreateMemoryOpts, type CreateReviewEventOpts, DatabaseError, DatabaseManager, type DownloadProgress, type DownloadResult, type Embedder, EmbeddingService, type ExtractionAgentRunner, type ExtractionConfig, type ExtractionRunRecord, type ExtractionRunRepository, type ExtractionTools, type FlagCluster, GLOBAL_PROJECT_ID, GLOBAL_PROJECT_NAME, GLOBAL_SCOPE_HASH, type ListEventsFilter, MEMORY_TYPE_VALUES, MIGRATIONS, MODEL_NAME, MembankError, type Memory, type MemoryExportRecord, type MemoryPatch, MemoryPatchSchema, type MemoryRepository, type MemoryRow, MemoryRowSchema, MemorySchema, type MemoryType, MemoryTypeSchema, type MemoryVersion, MemoryVersionRow, MemoryVersionRowSchema, type MergeMemoriesOpts, type MergeMemoriesResult, MigrationMeta, ModelDownloadError, ModelDownloader, PIN_BUDGET_THRESHOLD, type ProgressCallback, Project, type ProjectRepository, ProjectRow, ProjectRowSchema, ProjectSchema, type Querier, type QueryAdapter, QueryEngine, QueryOptions, QueryOptionsSchema, RETENTION_DAYS, type ReviewEvent, type ReviewEventRow, ReviewEventRowSchema, ReviewEventSchema, type ReviewQueueStats, ReviewReason, ReviewReasonSchema, type RunExtractionInput, type RunExtractionResult, type SaveOptions, SaveOptionsSchema, ScopeToProjectsResult, type ScoredMemory, SessionContext, SessionContextBuilder, SessionContextSchema, type SimilarMemoryResult, SqliteMemoryRepository, type StatsResult, Synthesis, type SynthesisConfig, SynthesisEngine, type SynthesisRepository, SynthesisSchema, type SynthesisTools, type SynthesisVersion, SynthesisVersionRow, SynthesisVersionRowSchema, TagsJsonSchema, type TranscriptReader, clusterFlagged, createActivityLogger, createActivityRepository, createClaudeCodeTranscriptReader, createExtractionAgentRunner, createExtractionRunRepository, createMemoryRepository, createProjectRepository, createSynthesisAgentRunner, createSynthesisRepository, deleteManyMemories, deleteMemory, getSessionContext, isOverBudget, isSynthesisEnabled, listEvents, listMemoryTypes, logEvent, mergeMemories, noopActivityLogger, queryMemories, resolveProject, resolveReview, resolveReviewMany, resolveScope, revertMemory, revertSynthesis, rowToMemory, rowToProject, runExtraction, runScopeToProjectsMigration, runSynthesis, saveMemory, suggestMerge, updateMemory };
|
|
886
889
|
//# sourceMappingURL=index.d.cts.map
|
package/dist/index.d.mts
CHANGED
|
@@ -674,6 +674,9 @@ declare function saveMemory(opts: SaveOptions, deps: {
|
|
|
674
674
|
activityLogger?: ActivityLogger;
|
|
675
675
|
}): Promise<Memory>;
|
|
676
676
|
//#endregion
|
|
677
|
+
//#region src/memory/application/suggest-merge.d.ts
|
|
678
|
+
declare function suggestMerge(contents: readonly string[]): Promise<string>;
|
|
679
|
+
//#endregion
|
|
677
680
|
//#region src/memory/application/update-memory.d.ts
|
|
678
681
|
declare function updateMemory(id: string, patch: MemoryPatch, deps: {
|
|
679
682
|
repo: MemoryRepository;
|
|
@@ -882,5 +885,5 @@ declare function createSynthesisAgentRunner(tools: SynthesisTools, config: Synth
|
|
|
882
885
|
//#region src/synthesis/infrastructure/sqlite-synthesis-repository.d.ts
|
|
883
886
|
declare function createSynthesisRepository(db: DatabaseManager): SynthesisRepository;
|
|
884
887
|
//#endregion
|
|
885
|
-
export { ACTIVITY_EVENT_TYPE_VALUES, type ActivityEvent, type ActivityEventInput, type ActivityEventType, ActivityEventTypeSchema, type ActivityLogger, type ActivityRepository, type AgentRunner, type BulkOpResult, type CreateMemoryOpts, type CreateReviewEventOpts, DatabaseError, DatabaseManager, type DownloadProgress, type DownloadResult, type Embedder, EmbeddingService, type ExtractionAgentRunner, type ExtractionConfig, type ExtractionRunRecord, type ExtractionRunRepository, type ExtractionTools, type FlagCluster, GLOBAL_PROJECT_ID, GLOBAL_PROJECT_NAME, GLOBAL_SCOPE_HASH, type ListEventsFilter, MEMORY_TYPE_VALUES, MIGRATIONS, MODEL_NAME, MembankError, type Memory, type MemoryExportRecord, type MemoryPatch, MemoryPatchSchema, type MemoryRepository, type MemoryRow, MemoryRowSchema, MemorySchema, type MemoryType, MemoryTypeSchema, type MemoryVersion, MemoryVersionRow, MemoryVersionRowSchema, type MergeMemoriesOpts, type MergeMemoriesResult, MigrationMeta, ModelDownloadError, ModelDownloader, PIN_BUDGET_THRESHOLD, type ProgressCallback, Project, type ProjectRepository, ProjectRow, ProjectRowSchema, ProjectSchema, type Querier, type QueryAdapter, QueryEngine, QueryOptions, QueryOptionsSchema, RETENTION_DAYS, type ReviewEvent, type ReviewEventRow, ReviewEventRowSchema, ReviewEventSchema, type ReviewQueueStats, ReviewReason, ReviewReasonSchema, type RunExtractionInput, type RunExtractionResult, type SaveOptions, SaveOptionsSchema, ScopeToProjectsResult, type ScoredMemory, SessionContext, SessionContextBuilder, SessionContextSchema, type SimilarMemoryResult, SqliteMemoryRepository, type StatsResult, Synthesis, type SynthesisConfig, SynthesisEngine, type SynthesisRepository, SynthesisSchema, type SynthesisTools, type SynthesisVersion, SynthesisVersionRow, SynthesisVersionRowSchema, TagsJsonSchema, type TranscriptReader, clusterFlagged, createActivityLogger, createActivityRepository, createClaudeCodeTranscriptReader, createExtractionAgentRunner, createExtractionRunRepository, createMemoryRepository, createProjectRepository, createSynthesisAgentRunner, createSynthesisRepository, deleteManyMemories, deleteMemory, getSessionContext, isOverBudget, isSynthesisEnabled, listEvents, listMemoryTypes, logEvent, mergeMemories, noopActivityLogger, queryMemories, resolveProject, resolveReview, resolveReviewMany, resolveScope, revertMemory, revertSynthesis, rowToMemory, rowToProject, runExtraction, runScopeToProjectsMigration, runSynthesis, saveMemory, updateMemory };
|
|
888
|
+
export { ACTIVITY_EVENT_TYPE_VALUES, type ActivityEvent, type ActivityEventInput, type ActivityEventType, ActivityEventTypeSchema, type ActivityLogger, type ActivityRepository, type AgentRunner, type BulkOpResult, type CreateMemoryOpts, type CreateReviewEventOpts, DatabaseError, DatabaseManager, type DownloadProgress, type DownloadResult, type Embedder, EmbeddingService, type ExtractionAgentRunner, type ExtractionConfig, type ExtractionRunRecord, type ExtractionRunRepository, type ExtractionTools, type FlagCluster, GLOBAL_PROJECT_ID, GLOBAL_PROJECT_NAME, GLOBAL_SCOPE_HASH, type ListEventsFilter, MEMORY_TYPE_VALUES, MIGRATIONS, MODEL_NAME, MembankError, type Memory, type MemoryExportRecord, type MemoryPatch, MemoryPatchSchema, type MemoryRepository, type MemoryRow, MemoryRowSchema, MemorySchema, type MemoryType, MemoryTypeSchema, type MemoryVersion, MemoryVersionRow, MemoryVersionRowSchema, type MergeMemoriesOpts, type MergeMemoriesResult, MigrationMeta, ModelDownloadError, ModelDownloader, PIN_BUDGET_THRESHOLD, type ProgressCallback, Project, type ProjectRepository, ProjectRow, ProjectRowSchema, ProjectSchema, type Querier, type QueryAdapter, QueryEngine, QueryOptions, QueryOptionsSchema, RETENTION_DAYS, type ReviewEvent, type ReviewEventRow, ReviewEventRowSchema, ReviewEventSchema, type ReviewQueueStats, ReviewReason, ReviewReasonSchema, type RunExtractionInput, type RunExtractionResult, type SaveOptions, SaveOptionsSchema, ScopeToProjectsResult, type ScoredMemory, SessionContext, SessionContextBuilder, SessionContextSchema, type SimilarMemoryResult, SqliteMemoryRepository, type StatsResult, Synthesis, type SynthesisConfig, SynthesisEngine, type SynthesisRepository, SynthesisSchema, type SynthesisTools, type SynthesisVersion, SynthesisVersionRow, SynthesisVersionRowSchema, TagsJsonSchema, type TranscriptReader, clusterFlagged, createActivityLogger, createActivityRepository, createClaudeCodeTranscriptReader, createExtractionAgentRunner, createExtractionRunRepository, createMemoryRepository, createProjectRepository, createSynthesisAgentRunner, createSynthesisRepository, deleteManyMemories, deleteMemory, getSessionContext, isOverBudget, isSynthesisEnabled, listEvents, listMemoryTypes, logEvent, mergeMemories, noopActivityLogger, queryMemories, resolveProject, resolveReview, resolveReviewMany, resolveScope, revertMemory, revertSynthesis, rowToMemory, rowToProject, runExtraction, runScopeToProjectsMigration, runSynthesis, saveMemory, suggestMerge, updateMemory };
|
|
886
889
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.mjs
CHANGED
|
@@ -299,7 +299,11 @@ CREATE INDEX idx_synthesis_versions_scope ON synthesis_versions(scope, version D
|
|
|
299
299
|
`)}var Oe=class{#e;#t;constructor(e={}){this.#e=e.maxTurns??80,this.#t=e.maxChars??6e4}async read(e){let t=(await ee(e,`utf8`)).split(`
|
|
300
300
|
`).filter(e=>e.length>0),n=[];for(let e of t){let t;try{t=JSON.parse(e)}catch{continue}let r=t.message?.role;if(r!==`user`&&r!==`assistant`)continue;let i=De(t.message?.content).trim();i.length!==0&&n.push(`${r}: ${i}`)}let r=n.slice(-this.#e).join(`
|
|
301
301
|
|
|
302
|
-
`);return r.length<=this.#t?r:r.slice(r.length-this.#t)}};function ke(e={}){return new Oe(e)}function Ae(e){let t=new Map;function n(e){t.has(e)||t.set(e,e);let r=t.get(e);if(r!==e){let i=n(r);return t.set(e,i),i}return e}function r(e,r){let i=n(e),a=n(r);i!==a&&t.set(a,i)}for(let{memoryId:t,conflictingMemoryId:n}of e)r(t,n);let i=new Map;for(let e of t.keys()){let t=n(e),r=i.get(t)??[];r.push(e),i.set(t,r)}return Array.from(i.entries()).map(([e,t])=>({clusterId:e,memoryIds:t}))}function Y(e,t,n=w){let r=t.findById(e)?.projects[0]?.scopeHash??`0000000000000000`;return t.delete(e),n.logEvent({projectHash:r,eventType:`memory.deleted`,memoryId:e}),Promise.resolve()}async function je(e,t,n=w){let r=[];for(let i of e)try{await Y(i,t,n),r.push({id:i,status:`ok`})}catch(e){r.push({id:i,status:`error`,error:e instanceof Error?e.message:String(e)})}return r}function X(e){return e>.92?`overwrite`:e>=.75?`flag`:`none`}async function Me(e,t){let{keepId:n,dropIds:r,mergedContent:i}=e,{repo:a,embedder:o,activityLogger:s=w}=t,c=a.findById(n);if(c===void 0)throw Error(`Memory not found: ${n}`);let l=r.map(e=>{let t=a.findById(e);if(t===void 0)throw Error(`Memory not found: ${e}`);return t});for(let e of l)if(e.type!==c.type)throw Error(`Type mismatch: keep memory has type "${c.type}" but drop memory ${e.id} has type "${e.type}"`);let u=[c,...l],d=[...new Set(u.flatMap(e=>e.tags))],f=u.some(e=>e.pinned),p=u.reduce((e,t)=>e+t.accessCount,0),m=await o.embed(i),h=a.overwrite(n,i,m),g=new Set(c.tags);if((d.length!==c.tags.length||d.some(e=>!g.has(e)))&&(h=a.update(n,{tags:d})),f&&!c.pinned&&(h=a.setPin(n,!0)),p>c.accessCount){let e=p-c.accessCount;for(let t=0;t<e;t++)a.incrementAccessCount(n);h=a.findById(n)??h}for(let e of l)a.delete(e.id);let[_]=a.findSimilar(m,c.type,c.projects[0]?.scopeHash);_!==void 0&&_.id!==n&&X(_.similarity)===`flag`&&a.createReviewEvent({memoryId:n,conflictingMemoryId:_.id,similarity:_.similarity,conflictContentSnapshot:i});let v=h.projects[0]?.scopeHash??`0000000000000000`;return s.logEvent({projectHash:v,eventType:`memory.updated`,memoryId:n,payload:{merged:r}}),h=a.findById(n)??h,{kept:h,dropped:r}}function Ne(e,t){t.resolveReviewEvents(e)}function Pe(e,t){return e.map(e=>{try{return t.findById(e)===void 0?{id:e,status:`error`,error:`Memory not found: ${e}`}:(t.resolveReviewEvents(e),{id:e,status:`ok`})}catch(t){return{id:e,status:`error`,error:t instanceof Error?t.message:String(t)}}})}async function Fe(e,t,n){let{repo:r,embedder:i,activityLogger:a=w}=n,o=r.getVersion(e,t);if(o===void 0)throw Error(`Version ${t} not found for memory: ${e}`);let s=await i.embed(o.content),c=r.update(e,{content:o.content},s),l=c.projects[0]?.scopeHash??`0000000000000000`;return a.logEvent({projectHash:l,eventType:`memory.updated`,memoryId:e,payload:{revertedToVersion:t}}),c}async function Ie(e,t){let{content:n,type:r,tags:a=[],projectScope:o,sourceHarness:s}=P.parse(e),{repo:c,embedder:l,activityLogger:u=w}=t,d=o?.hash??`0000000000000000`,f=await l.embed(n),[p]=c.findSimilar(f,r,o?.hash);if(p!==void 0){let e=X(p.similarity);if(e===`overwrite`){let e=c.overwrite(p.id,n,f);return u.logEvent({projectHash:d,eventType:`memory.updated`,memoryId:p.id}),e}if(e===`flag`){let e=c.create({id:i(),content:n,type:r,tags:a,sourceHarness:s??null,embedding:f,...o!==void 0&&{projectScope:o}});return c.createReviewEvent({memoryId:p.id,conflictingMemoryId:e.id,similarity:p.similarity,conflictContentSnapshot:n}),u.logEvent({projectHash:d,eventType:`memory.created`,memoryId:e.id}),u.logEvent({projectHash:d,eventType:`memory.flagged`,memoryId:p.id,payload:{conflictingMemoryId:e.id,similarity:p.similarity}}),e}}let m=c.create({id:i(),content:n,type:r,tags:a,sourceHarness:s??null,embedding:f,...o!==void 0&&{projectScope:o}});return u.logEvent({projectHash:d,eventType:`memory.created`,memoryId:m.id}),m}async function Le(e
|
|
302
|
+
`);return r.length<=this.#t?r:r.slice(r.length-this.#t)}};function ke(e={}){return new Oe(e)}function Ae(e){let t=new Map;function n(e){t.has(e)||t.set(e,e);let r=t.get(e);if(r!==e){let i=n(r);return t.set(e,i),i}return e}function r(e,r){let i=n(e),a=n(r);i!==a&&t.set(a,i)}for(let{memoryId:t,conflictingMemoryId:n}of e)r(t,n);let i=new Map;for(let e of t.keys()){let t=n(e),r=i.get(t)??[];r.push(e),i.set(t,r)}return Array.from(i.entries()).map(([e,t])=>({clusterId:e,memoryIds:t}))}function Y(e,t,n=w){let r=t.findById(e)?.projects[0]?.scopeHash??`0000000000000000`;return t.delete(e),n.logEvent({projectHash:r,eventType:`memory.deleted`,memoryId:e}),Promise.resolve()}async function je(e,t,n=w){let r=[];for(let i of e)try{await Y(i,t,n),r.push({id:i,status:`ok`})}catch(e){r.push({id:i,status:`error`,error:e instanceof Error?e.message:String(e)})}return r}function X(e){return e>.92?`overwrite`:e>=.75?`flag`:`none`}async function Me(e,t){let{keepId:n,dropIds:r,mergedContent:i}=e,{repo:a,embedder:o,activityLogger:s=w}=t,c=a.findById(n);if(c===void 0)throw Error(`Memory not found: ${n}`);let l=r.map(e=>{let t=a.findById(e);if(t===void 0)throw Error(`Memory not found: ${e}`);return t});for(let e of l)if(e.type!==c.type)throw Error(`Type mismatch: keep memory has type "${c.type}" but drop memory ${e.id} has type "${e.type}"`);let u=[c,...l],d=[...new Set(u.flatMap(e=>e.tags))],f=u.some(e=>e.pinned),p=u.reduce((e,t)=>e+t.accessCount,0),m=await o.embed(i),h=a.overwrite(n,i,m),g=new Set(c.tags);if((d.length!==c.tags.length||d.some(e=>!g.has(e)))&&(h=a.update(n,{tags:d})),f&&!c.pinned&&(h=a.setPin(n,!0)),p>c.accessCount){let e=p-c.accessCount;for(let t=0;t<e;t++)a.incrementAccessCount(n);h=a.findById(n)??h}for(let e of l)a.delete(e.id);let[_]=a.findSimilar(m,c.type,c.projects[0]?.scopeHash);_!==void 0&&_.id!==n&&X(_.similarity)===`flag`&&a.createReviewEvent({memoryId:n,conflictingMemoryId:_.id,similarity:_.similarity,conflictContentSnapshot:i});let v=h.projects[0]?.scopeHash??`0000000000000000`;return s.logEvent({projectHash:v,eventType:`memory.updated`,memoryId:n,payload:{merged:r}}),h=a.findById(n)??h,{kept:h,dropped:r}}function Ne(e,t){t.resolveReviewEvents(e)}function Pe(e,t){return e.map(e=>{try{return t.findById(e)===void 0?{id:e,status:`error`,error:`Memory not found: ${e}`}:(t.resolveReviewEvents(e),{id:e,status:`ok`})}catch(t){return{id:e,status:`error`,error:t instanceof Error?t.message:String(t)}}})}async function Fe(e,t,n){let{repo:r,embedder:i,activityLogger:a=w}=n,o=r.getVersion(e,t);if(o===void 0)throw Error(`Version ${t} not found for memory: ${e}`);let s=await i.embed(o.content),c=r.update(e,{content:o.content},s),l=c.projects[0]?.scopeHash??`0000000000000000`;return a.logEvent({projectHash:l,eventType:`memory.updated`,memoryId:e,payload:{revertedToVersion:t}}),c}async function Ie(e,t){let{content:n,type:r,tags:a=[],projectScope:o,sourceHarness:s}=P.parse(e),{repo:c,embedder:l,activityLogger:u=w}=t,d=o?.hash??`0000000000000000`,f=await l.embed(n),[p]=c.findSimilar(f,r,o?.hash);if(p!==void 0){let e=X(p.similarity);if(e===`overwrite`){let e=c.overwrite(p.id,n,f);return u.logEvent({projectHash:d,eventType:`memory.updated`,memoryId:p.id}),e}if(e===`flag`){let e=c.create({id:i(),content:n,type:r,tags:a,sourceHarness:s??null,embedding:f,...o!==void 0&&{projectScope:o}});return c.createReviewEvent({memoryId:p.id,conflictingMemoryId:e.id,similarity:p.similarity,conflictContentSnapshot:n}),u.logEvent({projectHash:d,eventType:`memory.created`,memoryId:e.id}),u.logEvent({projectHash:d,eventType:`memory.flagged`,memoryId:p.id,payload:{conflictingMemoryId:e.id,similarity:p.similarity}}),e}}let m=c.create({id:i(),content:n,type:r,tags:a,sourceHarness:s??null,embedding:f,...o!==void 0&&{projectScope:o}});return u.logEvent({projectHash:d,eventType:`memory.created`,memoryId:m.id}),m}async function Le(e){let t=e.map((e,t)=>`Memory ${t+1}:\n${e}`).join(`
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
`),n=Object.fromEntries(Object.entries(process.env).filter(e=>e[1]!==void 0)),r=v({prompt:`Merge these memory entries into one concise memory:\n\n${t}`,options:{model:`claude-haiku-4-5-20251001`,systemPrompt:`You are a memory merge assistant. Given multiple memory entries identified as similar or overlapping, produce one concise merged memory that preserves all important information without redundancy. Output only the merged memory text — no preamble, no explanation, no metadata.`,allowedTools:[],settingSources:[],permissionMode:`bypassPermissions`,env:n}}),i=``;for await(let e of r)e.type===`result`&&e.subtype===`success`&&(i=e.result);if(!i)throw Error(`Merge suggestion returned empty result`);return i}async function Re(e,t,n){let{repo:r,embedder:i,activityLogger:a=w}=n,o=F.parse(t),s=o.content===void 0?void 0:await i.embed(o.content),c=r.update(e,o,s),l=c.projects[0]?.scopeHash??`0000000000000000`;return a.logEvent({projectHash:l,eventType:`memory.updated`,memoryId:e}),c}const Z=8e3;function ze(e){return e>=Z}var Be=class{#e;#t;constructor(e,t){this.#e=e,this.#t=t}findSimilar(e,n,r){let i=Buffer.from(e.buffer),a;return a=r===void 0?this.#e.db.prepare(`SELECT m.rowid, m.*, (1 - vec_distance_cosine(e.embedding, ?)) AS similarity
|
|
303
307
|
FROM memories m JOIN embeddings e ON e.rowid = m.rowid
|
|
304
308
|
JOIN memory_projects mp ON mp.memory_id = m.id
|
|
305
309
|
JOIN projects p ON p.id = mp.project_id
|
|
@@ -361,14 +365,14 @@ CREATE INDEX idx_synthesis_versions_scope ON synthesis_versions(scope, version D
|
|
|
361
365
|
SELECT MAX(version) - 10 FROM memory_versions WHERE memory_id = ?
|
|
362
366
|
)`).run(e,e))}#i(e,t){if(e.length===0)return new Map;let n=e.map(()=>`?`).join(`, `),r=t?.unresolvedOnly===!0?`AND resolved_at IS NULL`:``,i=this.#e.db.prepare(`SELECT * FROM memory_review_events
|
|
363
367
|
WHERE memory_id IN (${n}) ${r}
|
|
364
|
-
ORDER BY created_at DESC`).all(...e),a=new Map;for(let e of i){let t=B(j.parse(e)),n=a.get(t.memoryId)??[];n.push(t),a.set(t.memoryId,n)}return a}};function
|
|
368
|
+
ORDER BY created_at DESC`).all(...e),a=new Map;for(let e of i){let t=B(j.parse(e)),n=a.get(t.memoryId)??[];n.push(t),a.set(t.memoryId,n)}return a}};function Ve(e,t){return new Be(e,t)}const He=ne(te);function Q(e){return r(`sha256`).update(e).digest(`hex`).slice(0,16)}async function Ue(){try{let{stdout:e}=await He(`git`,[`remote`,`get-url`,`origin`]),t=e.trim();if(t){let e=Q(t);return{hash:e,name:t.split(`/`).pop()?.replace(/\.git$/,``)??e.slice(0,8)}}}catch{}let e=process.cwd(),t=Q(e);return{hash:t,name:e.split(/[/\\]/).filter(Boolean).pop()??t.slice(0,8)}}async function We(){try{let{stdout:e}=await He(`git`,[`remote`,`get-url`,`origin`]),t=e.trim();if(t)return Q(t)}catch{}return Q(process.cwd())}const Ge=[{name:`scope-to-projects`,description:`Rename the auto-migrated project for the current directory from its generic hash-derived name to the resolved repo/directory name.`}];async function Ke(e){let t=await Ue(),n=e.getByHash(t.hash);if(n===void 0)return null;let r=n.name,i=e.countMemories(n.id);return e.rename(n.id,t.name),{migration:`scope-to-projects`,oldName:r,newName:t.name,memoryCount:i}}var qe=class{#e;constructor(e){this.#e=e}upsertByHash(t,r){if(!/^[0-9a-f]{16}$/.test(t))throw Error(`Invalid scope hash "${t}": expected 16 lowercase hex characters`);let a=new Date().toISOString(),o=t===`0000000000000000`?n:i(),s=t===`0000000000000000`?e:r;return this.#e.db.prepare(`INSERT OR IGNORE INTO projects (id, name, scope_hash, created_at, updated_at) VALUES (?, ?, ?, ?, ?)`).run(o,s,t,a,a),V(R.parse(this.#e.db.prepare(`SELECT * FROM projects WHERE scope_hash = ?`).get(t)))}rename(e,t){let n=new Date().toISOString();this.#e.db.prepare(`UPDATE projects SET name = ?, updated_at = ? WHERE id = ?`).run(t,n,e);let r=this.#e.db.prepare(`SELECT * FROM projects WHERE id = ?`).get(e);if(r===void 0)throw Error(`Project not found: ${e}`);return V(r)}list(){return this.#e.db.prepare(`SELECT * FROM projects ORDER BY name ASC`).all().map(V)}getByHash(e){let t=this.#e.db.prepare(`SELECT * FROM projects WHERE scope_hash = ?`).get(e);return t===void 0?void 0:V(t)}getByName(e){let t=this.#e.db.prepare(`SELECT * FROM projects WHERE name = ? LIMIT 1`).get(e);return t===void 0?void 0:V(t)}addAssociation(e,t){this.#e.db.prepare(`INSERT OR IGNORE INTO memory_projects (memory_id, project_id) VALUES (?, ?)`).run(e,t)}removeAssociation(e,t){this.#e.db.prepare(`DELETE FROM memory_projects WHERE memory_id = ? AND project_id = ?`).run(e,t)}countMemories(e){return this.#e.db.prepare(`SELECT COUNT(*) AS count FROM memory_projects WHERE project_id = ?`).get(e)?.count??0}getProjectsForMemories(e){if(e.length===0)return new Map;let t=e.map(()=>`?`).join(`,`),n=this.#e.db.prepare(`SELECT p.*, mp.memory_id FROM projects p
|
|
365
369
|
JOIN memory_projects mp ON mp.project_id = p.id
|
|
366
|
-
WHERE mp.memory_id IN (${t})`).all(...e),r=new Map;for(let e of n){let t=r.get(e.memory_id)??[];t.push(V(e)),r.set(e.memory_id,t)}return r}};function
|
|
370
|
+
WHERE mp.memory_id IN (${t})`).all(...e),r=new Map;for(let e of n){let t=r.get(e.memory_id)??[];t.push(V(e)),r.set(e.memory_id,t)}return r}};function Je(e){return new qe(e)}const Ye={correction:1,preference:.8,decision:.6,learning:.4,fact:.2};function Xe(e,t,n){let r=Ye[e.type],i=e.accessCount/(e.accessCount+10),a=1/(1+(n-new Date(e.updatedAt).getTime())/864e5),o=+!!e.pinned;return t*.4+r*.25+i*.2+a*.1+o*.05}async function Ze(e,t){let{query:n,type:r,projectHash:i,limit:a=10,includePinned:o}=N.parse(e),{activityLogger:s=w}=t,c=await t.embedder.embed(n),l=Buffer.from(c.buffer),u=t.adapter.findByEmbedding(l,{...r!==void 0&&{type:r},...i!==void 0&&{projectHash:i},...o!==void 0&&{includePinned:o}}),d=Date.now(),f=u.filter(e=>e.cosineSim>0).map(e=>{let{cosineSim:t,...n}=e;return{...n,score:Xe(n,t,d)}});f.sort((e,t)=>t.score-e.score);let p=f.slice(0,a);for(let e of p)t.repo.incrementAccessCount(e.id);return s.logEvent({projectHash:i??`0000000000000000`,eventType:`memory.queried`,payload:{resultCount:p.length,topScores:p.slice(0,3).map(e=>e.score)}}),p}var Qe=class{#e;constructor(e){this.#e=e}findByEmbedding(e,n){let{type:r,projectHash:i,includePinned:a}=n,o=[],s=[e],c=``;a||o.push(`m.pinned = 0`),r!==void 0&&(o.push(`m.type = ?`),s.push(r)),i!==void 0&&(c=`JOIN memory_projects mp ON mp.memory_id = m.id JOIN projects p ON p.id = mp.project_id`,o.push(`(p.scope_hash = ? OR p.scope_hash = ?)`),s.push(i,t));let l=o.length>0?`WHERE ${o.join(` AND `)}`:``,u=`
|
|
367
371
|
SELECT m.*, (1 - vec_distance_cosine(e.embedding, ?)) AS cosine_sim
|
|
368
372
|
FROM memories m JOIN embeddings e ON e.rowid = m.rowid
|
|
369
373
|
${c}
|
|
370
374
|
${l}
|
|
371
|
-
`;return this.#e.db.prepare(u).all(...s).map(e=>({...z(e,[]),cosineSim:e.cosine_sim}))}}
|
|
375
|
+
`;return this.#e.db.prepare(u).all(...s).map(e=>({...z(e,[]),cosineSim:e.cosine_sim}))}},$e=class{#e;#t;#n;#r;constructor(e,t,n,r=w){this.#e=e,this.#t=t,this.#n=n,this.#r=r}async query(e){return Ze(e,{adapter:new Qe(this.#e),repo:this.#n,embedder:this.#t,activityLogger:this.#r})}};function et(e,t){let n=t.repo.stats(e.projectHash);return e.synthesis!==void 0&&e.synthesis.length>0?{stats:n.byType,pinnedGlobal:[],pinnedProject:[],synthesis:e.synthesis}:{stats:n.byType,pinnedGlobal:t.repo.listPinnedGlobal(),pinnedProject:t.repo.listPinnedForProject(e.projectHash)}}function tt(){return[...T]}var nt=class{#e;constructor(e){this.#e=e}getSessionContext(e,t){return et({projectHash:e,...t!==void 0&&{synthesis:t}},{repo:this.#e})}},rt=class{#e;#t;#n;#r=new Set;#i=new Map;#a=!1;#o;#s=new Map;constructor(e,t,n){this.#e=e,this.#t=t,this.#n=n}async init(){this.#e.clearStaleInFlight(this.#t.inFlightTimeoutMs??12e4),this.#e.expireStale();let e=this.#e.getExpiredOrDirtyScopes();for(let{scope:t}of e)this.#r.add(t);this.#a=!0,await this.#l()}shutdown(){this.#a=!1,this.#o!==void 0&&(clearTimeout(this.#o),this.#o=void 0);let e=[...this.#s.values()];return e.length===0?Promise.resolve():Promise.race([Promise.allSettled(e).then(()=>void 0),new Promise(e=>setTimeout(e,5e3))])}markDirty(e){this.#r.add(e)}#c(){if(!this.#a)return;let e=this.#t.debounceMs??45e3;this.#o=setTimeout(()=>{this.#l()},e)}async#l(){let e=[...this.#r];for(let t of e){let e=this.#t.inFlightTimeoutMs??12e4,n=this.#e.getSynthesis(t);if(n?.inFlightSince!==null&&n?.inFlightSince!==void 0){if(Date.now()-new Date(n.inFlightSince).getTime()<e)continue;this.#e.clearInFlight(t)}this.#r.delete(t);let r=this.#u(t).finally(()=>{this.#s.delete(t)});this.#s.set(t,r)}this.#c()}async#u(e){this.#e.markInFlight(e);try{let t=e===`0000000000000000`?void 0:e,n=await this.#n.run(e,t),r=this.#e.computeSourceMemoryHash(e);this.#e.saveSynthesis(e,n,r),this.#i.delete(e)}catch(t){let n=(this.#i.get(e)??0)+1;this.#i.set(e,n);let r=Math.min(n,5),i=(this.#t.debounceMs??45e3)*r;process.stderr.write(`membank synthesis: error for scope=${e} failures=${n} backoff=${i}ms: ${t instanceof Error?t.message:String(t)}\n`),setTimeout(()=>{this.#r.add(e)},i),this.#e.clearInFlight(e)}}};function it(e,t,n){let r=n.getVersion(e,t);if(r===void 0)throw Error(`Version ${t} not found for scope: ${e}`);return n.saveSynthesis(e,r.content,r.sourceMemoryHash)}async function at(e,t){let n=e===`0000000000000000`?void 0:e;t.synthRepo.markInFlight(e);try{let[r,i]=await Promise.all([t.agentRunner.run(e,n),Promise.resolve(t.synthRepo.computeSourceMemoryHash(e))]);return t.synthRepo.saveSynthesis(e,r,i),r}catch(n){throw t.synthRepo.clearInFlight(e),n}}var ot=class{#e;constructor(e,t){this.#e=e}async run(e,t){let n=_({name:`membank-synthesis-tools`,version:`1.0.0`,tools:[y(`query_memory`,`Search memories by semantic similarity`,{query:a.string().describe(`Search text`),limit:a.number().optional().describe(`Maximum results to return`),global:a.boolean().optional().describe(`Query global memories only when true, otherwise current project scope`)},async({query:e,limit:n,global:r})=>({content:[{type:`text`,text:await this.#e.queryMemory({query:e,...n!==void 0&&{limit:n},...r!==void 0&&{global:r},...t!==void 0&&{projectHash:t}})}]}),{annotations:{readOnlyHint:!0}}),y(`get_memory_summary`,`Returns aggregate stats: total memories, counts by type, pinned count, review queue size`,{},async()=>({content:[{type:`text`,text:await this.#e.getMemorySummary()}]}),{annotations:{readOnlyHint:!0}})]}),r=`Synthesize the memories for ${e===`0000000000000000`?`global (across all projects)`:`project scope: ${e}`}. Use get_memory_summary first to understand the overall state, then use query_memory to retrieve relevant memories (query with broad terms like "preferences", "corrections", "decisions", "key facts"). After gathering information, produce a concise synthesis of the most important things to remember about this user. Output only the synthesis text — no preamble, no metadata.`,i=Date.now(),o=Object.fromEntries(Object.entries(process.env).filter(e=>e[1]!==void 0)),s=v({prompt:r,options:{model:`claude-haiku-4-5-20251001`,systemPrompt:`You are a memory synthesizer. Your job is to read the user's stored memories and produce a concise, well-structured summary of what's most important to remember about this user — their preferences, corrections, decisions, and key facts. Pinned memories are higher fidelity and should be weighted more heavily. Exclude transient or ephemeral details. Output plain text suitable for injection into an LLM context window. Be concise — target 200-400 words.`,mcpServers:{"membank-synthesis-tools":n},allowedTools:[`mcp__membank-synthesis-tools__query_memory`,`mcp__membank-synthesis-tools__get_memory_summary`],disallowedTools:[`mcp__membank__*`],settingSources:[],permissionMode:`bypassPermissions`,env:o}}),c=``;for await(let e of s)if(e.type===`result`)if(e.subtype===`success`)c=e.result;else{let t=`errors`in e&&Array.isArray(e.errors)?`: ${e.errors.join(`; `)}`:``;throw Error(`Synthesis agent failed: ${e.subtype}${t}`)}let l=Date.now()-i;if(process.stderr.write(`membank synthesis: scope=${e} duration=${l}ms\n`),c===``)throw Error(`Synthesis agent returned empty result`);return c}};function st(e,t){return new ot(e,t)}function ct(e){return I.parse({id:e.id,scope:e.scope,content:e.content,sourceMemoryHash:e.source_memory_hash,synthesizedAt:e.synthesized_at,expiresAt:e.expires_at,inFlightSince:e.in_flight_since,createdAt:e.created_at,updatedAt:e.updated_at})}function $(e){return e.content===`pending`&&e.source_memory_hash===``}var lt=class{#e;constructor(e){this.#e=e}saveSynthesis(e,t,n){let r=new Date().toISOString(),a=new Date(Date.now()+720*60*60*1e3).toISOString(),{id:o,createdAt:s}=this.#e.db.transaction(()=>{let o=this.#e.db.prepare(`SELECT * FROM syntheses WHERE scope = ?`).get(e);if(o!==void 0)return $(o)||this.#t(e),this.#e.db.prepare(`UPDATE syntheses
|
|
372
376
|
SET content = ?, source_memory_hash = ?, synthesized_at = ?, expires_at = ?,
|
|
373
377
|
in_flight_since = NULL, updated_at = ?
|
|
374
378
|
WHERE scope = ?`).run(t,n,r,a,r,e),{id:o.id,createdAt:o.created_at};let s=i();return this.#e.db.prepare(`INSERT INTO syntheses
|
|
@@ -380,12 +384,12 @@ CREATE INDEX idx_synthesis_versions_scope ON synthesis_versions(scope, version D
|
|
|
380
384
|
LEFT JOIN synthesis_versions v ON v.scope = s.scope
|
|
381
385
|
WHERE s.scope = ?
|
|
382
386
|
GROUP BY s.scope`).get(e);t!==void 0&&(this.#e.db.prepare(`INSERT INTO synthesis_versions (scope, version, content, source_memory_hash, synthesized_at)
|
|
383
|
-
VALUES (?, ?, ?, ?, ?)`).run(e,t.next_version,t.content,t.source_memory_hash,t.synthesized_at),this.#e.db.prepare(`DELETE FROM synthesis_versions WHERE scope = ? AND version <= ?`).run(e,t.next_version-5))}getSynthesis(e){let t=this.#e.db.prepare(`SELECT * FROM syntheses WHERE scope = ?`).get(e);return t===void 0?void 0:
|
|
387
|
+
VALUES (?, ?, ?, ?, ?)`).run(e,t.next_version,t.content,t.source_memory_hash,t.synthesized_at),this.#e.db.prepare(`DELETE FROM synthesis_versions WHERE scope = ? AND version <= ?`).run(e,t.next_version-5))}getSynthesis(e){let t=this.#e.db.prepare(`SELECT * FROM syntheses WHERE scope = ?`).get(e);return t===void 0?void 0:ct(t)}listAll(){return this.#e.db.prepare(`SELECT * FROM syntheses ORDER BY scope`).all().map(ct)}markInFlight(e){let t=new Date().toISOString();if(this.#e.db.prepare(`SELECT id FROM syntheses WHERE scope = ?`).get(e)!==void 0)this.#e.db.prepare(`UPDATE syntheses SET in_flight_since = ?, updated_at = ? WHERE scope = ?`).run(t,t,e);else{let n=i(),r=new Date(Date.now()+720*60*60*1e3).toISOString();this.#e.db.prepare(`INSERT INTO syntheses
|
|
384
388
|
(id, scope, content, source_memory_hash, synthesized_at, expires_at,
|
|
385
389
|
in_flight_since, created_at, updated_at)
|
|
386
390
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(n,e,`pending`,``,t,r,t,t,t)}}clearInFlight(e){let t=new Date().toISOString();this.#e.db.prepare(`UPDATE syntheses SET in_flight_since = NULL, updated_at = ? WHERE scope = ?`).run(t,e)}clearStaleInFlight(e){let t=new Date(Date.now()-e).toISOString(),n=new Date().toISOString();this.#e.db.prepare(`UPDATE syntheses SET in_flight_since = NULL, updated_at = ? WHERE in_flight_since IS NOT NULL AND in_flight_since < ?`).run(n,t)}computeSourceMemoryHash(e){let t=this.#e.db.prepare(`SELECT m.content FROM memories m
|
|
387
391
|
JOIN memory_projects mp ON mp.memory_id = m.id
|
|
388
392
|
JOIN projects p ON p.id = mp.project_id
|
|
389
393
|
WHERE p.scope_hash = ?
|
|
390
|
-
ORDER BY m.id`).all(e);return r(`sha256`).update(JSON.stringify(t.map(e=>e.content))).digest(`hex`)}getExpiredOrDirtyScopes(){let e=this.getAllActiveScopes(),t=new Date().toISOString(),n=[];for(let r of e){let e=this.#e.db.prepare(`SELECT * FROM syntheses WHERE scope = ?`).get(r);if(e===void 0||$(e)){n.push({scope:r,reason:`missing`});continue}if(e.expires_at<=t){n.push({scope:r,reason:`expired`});continue}this.computeSourceMemoryHash(r)!==e.source_memory_hash&&n.push({scope:r,reason:`dirty`})}return n}getAllActiveScopes(){return this.#e.db.prepare(`SELECT DISTINCT scope_hash FROM projects`).all().map(e=>e.scope_hash)}expireStale(){let e=new Date().toISOString();this.#e.db.prepare(`DELETE FROM syntheses WHERE expires_at < ?`).run(e)}};function
|
|
394
|
+
ORDER BY m.id`).all(e);return r(`sha256`).update(JSON.stringify(t.map(e=>e.content))).digest(`hex`)}getExpiredOrDirtyScopes(){let e=this.getAllActiveScopes(),t=new Date().toISOString(),n=[];for(let r of e){let e=this.#e.db.prepare(`SELECT * FROM syntheses WHERE scope = ?`).get(r);if(e===void 0||$(e)){n.push({scope:r,reason:`missing`});continue}if(e.expires_at<=t){n.push({scope:r,reason:`expired`});continue}this.computeSourceMemoryHash(r)!==e.source_memory_hash&&n.push({scope:r,reason:`dirty`})}return n}getAllActiveScopes(){return this.#e.db.prepare(`SELECT DISTINCT scope_hash FROM projects`).all().map(e=>e.scope_hash)}expireStale(){let e=new Date().toISOString();this.#e.db.prepare(`DELETE FROM syntheses WHERE expires_at < ?`).run(e)}};function ut(e){return new lt(e)}export{b as ACTIVITY_EVENT_TYPE_VALUES,x as ActivityEventTypeSchema,G as DatabaseError,he as DatabaseManager,ve as EmbeddingService,n as GLOBAL_PROJECT_ID,e as GLOBAL_PROJECT_NAME,t as GLOBAL_SCOPE_HASH,T as MEMORY_TYPE_VALUES,Ge as MIGRATIONS,K as MODEL_NAME,W as MembankError,F as MemoryPatchSchema,L as MemoryRowSchema,M as MemorySchema,E as MemoryTypeSchema,de as MemoryVersionRowSchema,q as ModelDownloadError,_e as ModelDownloader,Z as PIN_BUDGET_THRESHOLD,R as ProjectRowSchema,O as ProjectSchema,$e as QueryEngine,N as QueryOptionsSchema,ie as RETENTION_DAYS,j as ReviewEventRowSchema,A as ReviewEventSchema,k as ReviewReasonSchema,P as SaveOptionsSchema,nt as SessionContextBuilder,ue as SessionContextSchema,Be as SqliteMemoryRepository,rt as SynthesisEngine,I as SynthesisSchema,fe as SynthesisVersionRowSchema,D as TagsJsonSchema,Ae as clusterFlagged,se as createActivityLogger,oe as createActivityRepository,ke as createClaudeCodeTranscriptReader,Se as createExtractionAgentRunner,Ee as createExtractionRunRepository,Ve as createMemoryRepository,Je as createProjectRepository,st as createSynthesisAgentRunner,ut as createSynthesisRepository,je as deleteManyMemories,Y as deleteMemory,et as getSessionContext,ze as isOverBudget,le as isSynthesisEnabled,re as listEvents,tt as listMemoryTypes,S as logEvent,Me as mergeMemories,w as noopActivityLogger,Ze as queryMemories,Ue as resolveProject,Ne as resolveReview,Pe as resolveReviewMany,We as resolveScope,Fe as revertMemory,it as revertSynthesis,z as rowToMemory,V as rowToProject,ye as runExtraction,Ke as runScopeToProjectsMigration,at as runSynthesis,Ie as saveMemory,Le as suggestMerge,Re as updateMemory};
|
|
391
395
|
//# sourceMappingURL=index.mjs.map
|