claude-mem 13.9.2 → 13.9.3

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.
@@ -1,17 +1,17 @@
1
- "use strict";var $t=Object.create;var j=Object.defineProperty;var Ht=Object.getOwnPropertyDescriptor;var Xt=Object.getOwnPropertyNames;var Gt=Object.getPrototypeOf,jt=Object.prototype.hasOwnProperty;var Bt=(n,e)=>{for(var t in e)j(n,t,{get:e[t],enumerable:!0})},fe=(n,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of Xt(e))!jt.call(n,r)&&r!==t&&j(n,r,{get:()=>e[r],enumerable:!(s=Ht(e,r))||s.enumerable});return n};var k=(n,e,t)=>(t=n!=null?$t(Gt(n)):{},fe(e||!n||!n.__esModule?j(t,"default",{value:n,enumerable:!0}):t,n)),Wt=n=>fe(j({},"__esModule",{value:!0}),n);var Is={};Bt(Is,{generateContext:()=>Pt,generateContextWithStats:()=>Se});module.exports=Wt(Is);var kt=k(require("path"),1),Ft=require("os"),wt=require("fs");var ue=require("bun:sqlite");var T=require("path"),oe=require("os"),U=require("fs");var be=require("url");var v=require("fs"),Re=require("path");var Vt=null;function Yt(n){return(Vt??process.stderr.write.bind(process.stderr))(n)}function te(n){Yt(n)}var re=(o=>(o[o.DEBUG=0]="DEBUG",o[o.INFO=1]="INFO",o[o.WARN=2]="WARN",o[o.ERROR=3]="ERROR",o[o.SILENT=4]="SILENT",o))(re||{}),se=null,ne=class{level=null;useColor;logFilePath=null;logFileInitialized=!1;constructor(){this.useColor=process.stdout.isTTY??!1}ensureLogFileInitialized(){if(!this.logFileInitialized){this.logFileInitialized=!0;try{let e=F.logsDir();(0,v.existsSync)(e)||(0,v.mkdirSync)(e,{recursive:!0});let t=new Date().toISOString().split("T")[0];this.logFilePath=(0,Re.join)(e,`claude-mem-${t}.log`)}catch(e){console.error("[LOGGER] Failed to initialize log file:",e instanceof Error?e.message:String(e)),this.logFilePath=null}}}getLevel(){if(this.level===null)try{let e=F.settings();if((0,v.existsSync)(e)){let t=(0,v.readFileSync)(e,"utf-8"),r=(JSON.parse(t).CLAUDE_MEM_LOG_LEVEL||"INFO").toUpperCase();this.level=re[r]??1}else this.level=1}catch(e){console.error("[LOGGER] Failed to load log level from settings:",e instanceof Error?e.message:String(e)),this.level=1}return this.level}formatData(e){if(e==null)return"";if(typeof e=="string")return e;if(typeof e=="number"||typeof e=="boolean")return e.toString();if(typeof e=="object"){if(e instanceof Error)return this.getLevel()===0?`${e.message}
2
- ${e.stack}`:e.message;if(Array.isArray(e))return`[${e.length} items]`;let t=Object.keys(e);return t.length===0?"{}":t.length<=3?JSON.stringify(e):`{${t.length} keys: ${t.slice(0,3).join(", ")}...}`}return String(e)}formatTool(e,t){if(!t)return e;let s=t;if(typeof t=="string")try{s=JSON.parse(t)}catch{s=t}if(e==="Bash"&&s.command)return`${e}(${s.command})`;if(s.file_path)return`${e}(${s.file_path})`;if(s.notebook_path)return`${e}(${s.notebook_path})`;if(e==="Glob"&&s.pattern)return`${e}(${s.pattern})`;if(e==="Grep"&&s.pattern)return`${e}(${s.pattern})`;if(s.url)return`${e}(${s.url})`;if(s.query)return`${e}(${s.query})`;if(e==="Task"){if(s.subagent_type)return`${e}(${s.subagent_type})`;if(s.description)return`${e}(${s.description})`}return e==="Skill"&&s.skill?`${e}(${s.skill})`:e==="LSP"&&s.operation?`${e}(${s.operation})`:e}formatTimestamp(e){let t=e.getFullYear(),s=String(e.getMonth()+1).padStart(2,"0"),r=String(e.getDate()).padStart(2,"0"),o=String(e.getHours()).padStart(2,"0"),i=String(e.getMinutes()).padStart(2,"0"),a=String(e.getSeconds()).padStart(2,"0"),d=String(e.getMilliseconds()).padStart(3,"0");return`${t}-${s}-${r} ${o}:${i}:${a}.${d}`}log(e,t,s,r,o){if(e<this.getLevel())return;this.ensureLogFileInitialized();let i=this.formatTimestamp(new Date),a=re[e].padEnd(5),d=t.padEnd(6),_="";r?.correlationId?_=`[${r.correlationId}] `:r?.sessionId&&(_=`[session-${r.sessionId}] `);let m="";if(o!=null)if(o instanceof Error)m=this.getLevel()===0?`
1
+ "use strict";var ks=Object.create;var G=Object.defineProperty;var ws=Object.getOwnPropertyDescriptor;var Fs=Object.getOwnPropertyNames;var Ps=Object.getPrototypeOf,$s=Object.prototype.hasOwnProperty;var Xs=(n,e)=>{for(var s in e)G(n,s,{get:e[s],enumerable:!0})},Te=(n,e,s,t)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of Fs(e))!$s.call(n,r)&&r!==s&&G(n,r,{get:()=>e[r],enumerable:!(t=ws(e,r))||t.enumerable});return n};var x=(n,e,s)=>(s=n!=null?ks(Ps(n)):{},Te(e||!n||!n.__esModule?G(s,"default",{value:n,enumerable:!0}):s,n)),Hs=n=>Te(G({},"__esModule",{value:!0}),n);var Tt={};Xs(Tt,{generateContext:()=>xs,generateContextWithStats:()=>le});module.exports=Hs(Tt);var vs=x(require("path"),1),ys=require("os"),Us=require("fs");var de=require("bun:sqlite");var f=require("path"),ee=require("os"),U=require("fs"),ge=require("url"),Ks={};function Gs(){return typeof __dirname<"u"?__dirname:(0,f.dirname)((0,ge.fileURLToPath)(Ks.url))}var Bs=Gs();function js(){if(process.env.CLAUDE_MEM_DATA_DIR)return process.env.CLAUDE_MEM_DATA_DIR;let n=(0,f.join)((0,ee.homedir)(),".claude-mem"),e=(0,f.join)(n,"settings.json");try{if((0,U.existsSync)(e)){let s=JSON.parse((0,U.readFileSync)(e,"utf-8")),t=s.env??s;if(t.CLAUDE_MEM_DATA_DIR)return t.CLAUDE_MEM_DATA_DIR}}catch{}return n}var I=js(),se=process.env.CLAUDE_CONFIG_DIR||(0,f.join)((0,ee.homedir)(),".claude"),ft=(0,f.join)(se,"plugins","marketplaces","thedotmack"),Ws=(0,f.join)(I,"logs"),Rt=(0,f.join)(I,"settings.json"),Se=(0,f.join)(I,"claude-mem.db"),Vs=(0,f.join)(I,"observer-sessions"),te=(0,f.basename)(Vs);function fe(n){(0,U.mkdirSync)(n,{recursive:!0})}function Re(){return(0,f.join)(Bs,"..")}var k={dataDir:()=>I,workerPid:()=>(0,f.join)(I,"worker.pid"),serverPid:()=>(0,f.join)(I,".server-beta.pid"),serverPort:()=>(0,f.join)(I,".server-beta.port"),serverRuntime:()=>(0,f.join)(I,".server-beta.runtime.json"),settings:()=>(0,f.join)(I,"settings.json"),database:()=>(0,f.join)(I,"claude-mem.db"),chroma:()=>(0,f.join)(I,"chroma"),combinedCerts:()=>(0,f.join)(I,"combined_certs.pem"),transcriptsConfig:()=>(0,f.join)(I,"transcript-watch.json"),transcriptsState:()=>(0,f.join)(I,"transcript-watch-state.json"),corpora:()=>(0,f.join)(I,"corpora"),supervisorRegistry:()=>(0,f.join)(I,"supervisor.json"),envFile:()=>(0,f.join)(I,".env"),logsDir:()=>Ws};var v=require("fs"),Oe=require("path");var Ys=null;function qs(n){return(Ys??process.stderr.write.bind(process.stderr))(n)}function re(n){qs(n)}var oe=(o=>(o[o.DEBUG=0]="DEBUG",o[o.INFO=1]="INFO",o[o.WARN=2]="WARN",o[o.ERROR=3]="ERROR",o[o.SILENT=4]="SILENT",o))(oe||{}),ne=null,ie=class{level=null;useColor;logFilePath=null;logFileInitialized=!1;constructor(){this.useColor=process.stdout.isTTY??!1}ensureLogFileInitialized(){if(!this.logFileInitialized){this.logFileInitialized=!0;try{let e=k.logsDir();(0,v.existsSync)(e)||(0,v.mkdirSync)(e,{recursive:!0});let s=new Date().toISOString().split("T")[0];this.logFilePath=(0,Oe.join)(e,`claude-mem-${s}.log`)}catch(e){console.error("[LOGGER] Failed to initialize log file:",e instanceof Error?e.message:String(e)),this.logFilePath=null}}}getLevel(){if(this.level===null)try{let e=k.settings();if((0,v.existsSync)(e)){let s=(0,v.readFileSync)(e,"utf-8"),r=(JSON.parse(s).CLAUDE_MEM_LOG_LEVEL||"INFO").toUpperCase();this.level=oe[r]??1}else this.level=1}catch(e){console.error("[LOGGER] Failed to load log level from settings:",e instanceof Error?e.message:String(e)),this.level=1}return this.level}formatData(e){if(e==null)return"";if(typeof e=="string")return e;if(typeof e=="number"||typeof e=="boolean")return e.toString();if(typeof e=="object"){if(e instanceof Error)return this.getLevel()===0?`${e.message}
2
+ ${e.stack}`:e.message;if(Array.isArray(e))return`[${e.length} items]`;let s=Object.keys(e);return s.length===0?"{}":s.length<=3?JSON.stringify(e):`{${s.length} keys: ${s.slice(0,3).join(", ")}...}`}return String(e)}formatTool(e,s){if(!s)return e;let t=s;if(typeof s=="string")try{t=JSON.parse(s)}catch{t=s}if(e==="Bash"&&t.command)return`${e}(${t.command})`;if(t.file_path)return`${e}(${t.file_path})`;if(t.notebook_path)return`${e}(${t.notebook_path})`;if(e==="Glob"&&t.pattern)return`${e}(${t.pattern})`;if(e==="Grep"&&t.pattern)return`${e}(${t.pattern})`;if(t.url)return`${e}(${t.url})`;if(t.query)return`${e}(${t.query})`;if(e==="Task"){if(t.subagent_type)return`${e}(${t.subagent_type})`;if(t.description)return`${e}(${t.description})`}return e==="Skill"&&t.skill?`${e}(${t.skill})`:e==="LSP"&&t.operation?`${e}(${t.operation})`:e}formatTimestamp(e){let s=e.getFullYear(),t=String(e.getMonth()+1).padStart(2,"0"),r=String(e.getDate()).padStart(2,"0"),o=String(e.getHours()).padStart(2,"0"),i=String(e.getMinutes()).padStart(2,"0"),a=String(e.getSeconds()).padStart(2,"0"),d=String(e.getMilliseconds()).padStart(3,"0");return`${s}-${t}-${r} ${o}:${i}:${a}.${d}`}log(e,s,t,r,o){if(e<this.getLevel())return;this.ensureLogFileInitialized();let i=this.formatTimestamp(new Date),a=oe[e].padEnd(5),d=s.padEnd(6),u="";r?.correlationId?u=`[${r.correlationId}] `:r?.sessionId&&(u=`[session-${r.sessionId}] `);let m="";if(o!=null)if(o instanceof Error)m=this.getLevel()===0?`
3
3
  ${o.message}
4
4
  ${o.stack}`:` ${o.message}`;else if(this.getLevel()===0&&typeof o=="object")try{m=`
5
- `+JSON.stringify(o,null,2)}catch{m=" "+this.formatData(o)}else m=" "+this.formatData(o);let l="";if(r){let{sessionId:g,memorySessionId:A,correlationId:h,...f}=r;Object.keys(f).length>0&&(l=` {${Object.entries(f).map(([C,y])=>`${C}=${y}`).join(", ")}}`)}let p=`[${i}] [${a}] [${d}] ${_}${s}${l}${m}`;if(this.logFilePath)try{(0,v.appendFileSync)(this.logFilePath,p+`
6
- `,"utf8")}catch(g){te(`[LOGGER] Failed to write to log file: ${g instanceof Error?g.message:String(g)}
7
- `)}else te(p+`
8
- `)}debug(e,t,s,r){this.log(0,e,t,s,r)}info(e,t,s,r){this.log(1,e,t,s,r)}warn(e,t,s,r){this.log(2,e,t,s,r)}setErrorSink(e){se=e}error(e,t,s,r){this.log(3,e,t,s,r),this.routeErrorToSink(t,s,r)}routeErrorToSink(e,t,s){try{if(!se||!(s instanceof Error))return;se(s)}catch{}}dataIn(e,t,s,r){this.info(e,`\u2192 ${t}`,s,r)}dataOut(e,t,s,r){this.info(e,`\u2190 ${t}`,s,r)}success(e,t,s,r){this.info(e,`\u2713 ${t}`,s,r)}failure(e,t,s,r){this.error(e,`\u2717 ${t}`,s,r)}happyPathError(e,t,s,r,o=""){let _=((new Error().stack||"").split(`
9
- `)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),m=_?`${_[1].split("/").pop()}:${_[2]}`:"unknown",l={...s,location:m};return this.warn(e,`[HAPPY-PATH] ${t}`,l,r),o}},E=new ne;var rs={};function qt(){return typeof __dirname<"u"?__dirname:(0,T.dirname)((0,be.fileURLToPath)(rs.url))}var Kt=qt();function Jt(){if(process.env.CLAUDE_MEM_DATA_DIR)return process.env.CLAUDE_MEM_DATA_DIR;let n=(0,T.join)((0,oe.homedir)(),".claude-mem"),e=(0,T.join)(n,"settings.json");try{if((0,U.existsSync)(e)){let t=JSON.parse((0,U.readFileSync)(e,"utf-8")),s=t.env??t;if(s.CLAUDE_MEM_DATA_DIR)return s.CLAUDE_MEM_DATA_DIR}}catch{}return n}var O=Jt(),x=process.env.CLAUDE_CONFIG_DIR||(0,T.join)((0,oe.homedir)(),".claude"),Us=(0,T.join)(x,"plugins","marketplaces","thedotmack"),Qt=(0,T.join)(O,"archives"),zt=(0,T.join)(O,"logs"),Zt=(0,T.join)(O,"trash"),es=(0,T.join)(O,"backups"),ts=(0,T.join)(O,"modes"),xs=(0,T.join)(O,"settings.json"),Oe=(0,T.join)(O,"claude-mem.db"),ss=(0,T.join)(O,"vector-db"),he=(0,T.join)(O,"observer-sessions"),ie=(0,T.basename)(he),ks=(0,T.join)(x,"settings.json"),Fs=(0,T.join)(x,"commands"),ws=(0,T.join)(x,"CLAUDE.md");function Ae(n){(0,U.mkdirSync)(n,{recursive:!0})}function Ie(){return(0,T.join)(Kt,"..")}var F={dataDir:()=>O,workerPid:()=>(0,T.join)(O,"worker.pid"),serverPid:()=>(0,T.join)(O,".server-beta.pid"),serverPort:()=>(0,T.join)(O,".server-beta.port"),serverRuntime:()=>(0,T.join)(O,".server-beta.runtime.json"),settings:()=>(0,T.join)(O,"settings.json"),database:()=>(0,T.join)(O,"claude-mem.db"),chroma:()=>(0,T.join)(O,"chroma"),combinedCerts:()=>(0,T.join)(O,"combined_certs.pem"),transcriptsConfig:()=>(0,T.join)(O,"transcript-watch.json"),transcriptsState:()=>(0,T.join)(O,"transcript-watch-state.json"),corpora:()=>(0,T.join)(O,"corpora"),supervisorRegistry:()=>(0,T.join)(O,"supervisor.json"),envFile:()=>(0,T.join)(O,".env"),logsDir:()=>zt,archives:()=>Qt,trash:()=>Zt,backups:()=>es,modes:()=>ts,vectorDb:()=>ss,observerSessions:()=>he};var Ne=require("crypto");function ae(n,e,t){return(0,Ne.createHash)("sha256").update([n||"",e||"",t||""].join("\0")).digest("hex").slice(0,16)}function de(n){if(!n)return[];try{let e=JSON.parse(n);return Array.isArray(e)?e:[String(e)]}catch{return[n]}}var c="claude";function ns(n){return n.trim().toLowerCase().replace(/\s+/g,"-")}function N(n){if(!n)return c;let e=ns(n);return e?e==="transcript"||e.includes("codex")?"codex":e.includes("cursor")?"cursor":e.includes("claude")?"claude":e:c}function Ce(n){let e=["claude","codex","cursor"];return[...n].sort((t,s)=>{let r=e.indexOf(t),o=e.indexOf(s);return r!==-1||o!==-1?r===-1?1:o===-1?-1:r-o:t.localeCompare(s)})}function Le(n,e,t,s,r){let o=Date.now()-s,i=r!==void 0?"up.session_db_id = ?":"up.content_session_id = ?",a=r??e;return n.prepare(`
5
+ `+JSON.stringify(o,null,2)}catch{m=" "+this.formatData(o)}else m=" "+this.formatData(o);let l="";if(r){let{sessionId:T,memorySessionId:h,correlationId:b,...g}=r;Object.keys(g).length>0&&(l=` {${Object.entries(g).map(([C,y])=>`${C}=${y}`).join(", ")}}`)}let c=`[${i}] [${a}] [${d}] ${u}${t}${l}${m}`;if(this.logFilePath)try{(0,v.appendFileSync)(this.logFilePath,c+`
6
+ `,"utf8")}catch(T){let h=T instanceof Error?T:new Error(String(T));re(`[LOGGER] Failed to write to log file: ${h.message}
7
+ ${h.stack??""}
8
+ `)}else re(c+`
9
+ `)}debug(e,s,t,r){this.log(0,e,s,t,r)}info(e,s,t,r){this.log(1,e,s,t,r)}warn(e,s,t,r){this.log(2,e,s,t,r)}setErrorSink(e){ne=e}error(e,s,t,r){this.log(3,e,s,t,r),this.routeErrorToSink(s,t,r)}routeErrorToSink(e,s,t){try{if(!ne||!(t instanceof Error))return;ne(t)}catch{}}dataIn(e,s,t,r){this.info(e,`\u2192 ${s}`,t,r)}dataOut(e,s,t,r){this.info(e,`\u2190 ${s}`,t,r)}success(e,s,t,r){this.info(e,`\u2713 ${s}`,t,r)}failure(e,s,t,r){this.error(e,`\u2717 ${s}`,t,r)}},_=new ie;var be=require("crypto");function he(n,e,s){return(0,be.createHash)("sha256").update([n||"",e||"",s||""].join("\0")).digest("hex").slice(0,16)}var p="claude";function Js(n){return n.trim().toLowerCase().replace(/\s+/g,"-")}function A(n){if(!n)return p;let e=Js(n);return e?e==="transcript"||e.includes("codex")?"codex":e.includes("cursor")?"cursor":e.includes("claude")?"claude":e:p}function Ne(n){let e=["claude","codex","cursor"];return[...n].sort((s,t)=>{let r=e.indexOf(s),o=e.indexOf(t);return r!==-1||o!==-1?r===-1?1:o===-1?-1:r-o:s.localeCompare(t)})}function Ie(n,e,s,t,r){let o=Date.now()-t,i=r!==void 0?"up.session_db_id = ?":"up.content_session_id = ?",a=r??e;return n.prepare(`
10
10
  SELECT
11
11
  up.*,
12
12
  s.memory_session_id,
13
13
  s.project,
14
- COALESCE(s.platform_source, '${c}') as platform_source
14
+ COALESCE(s.platform_source, '${p}') as platform_source
15
15
  FROM user_prompts up
16
16
  JOIN sdk_sessions s ON up.session_db_id = s.id
17
17
  WHERE ${i}
@@ -19,136 +19,136 @@ ${o.stack}`:` ${o.message}`;else if(this.getLevel()===0&&typeof o=="object")try{
19
19
  AND up.created_at_epoch >= ?
20
20
  ORDER BY up.created_at_epoch DESC
21
21
  LIMIT 1
22
- `).get(a,t,o)??void 0}var ve=["private","claude-mem-context","system_instruction","system-instruction","persisted-output","system-reminder"],De=new RegExp(`<(${ve.join("|")})\\b[^>]*>[\\s\\S]*?</\\1>`,"g"),ye=/<system-reminder>[\s\S]*?<\/system-reminder>/g,Me=100;function os(n){let e=Object.fromEntries(ve.map(r=>[r,0]));De.lastIndex=0;let t=0,s=n.replace(De,(r,o)=>(e[o]=(e[o]??0)+1,t+=1,""));return t>Me&&E.warn("SYSTEM","tag count exceeds limit",void 0,{tagCount:t,maxAllowed:Me,contentLength:n.length}),{stripped:s.trim(),counts:e}}function Ue(n){return os(n).stripped}var is=["task-notification"],Ws=new RegExp(`^\\s*<(${is.join("|")})\\b[^>]*>(?:(?!<\\1\\b|</\\1\\b)[\\s\\S])*</\\1>\\s*$`),Vs=256*1024;var _e=4e3;function B(n){let e=n.trim(),s=Ue(n).trim()||e;return s.length<=_e?s:(E.debug("DB","Truncated stored prompt text to the configured cap",{originalLength:s.length,storedLength:_e}),`${s.slice(0,_e-1)}\u2026`)}function as(n,e){return{customTitle:n,platformSource:e?N(e):void 0}}var W=class{db;constructor(e=Oe){e instanceof ue.Database?this.db=e:(e!==":memory:"&&Ae(O),this.db=new ue.Database(e),this.db.run("PRAGMA journal_mode = WAL"),this.db.run("PRAGMA synchronous = NORMAL"),this.db.run("PRAGMA foreign_keys = ON"),this.db.run("PRAGMA journal_size_limit = 4194304")),this.initializeSchema(),this.ensureWorkerPortColumn(),this.ensurePromptTrackingColumns(),this.removeSessionSummariesUniqueConstraint(),this.addObservationHierarchicalFields(),this.makeObservationsTextNullable(),this.createUserPromptsTable(),this.ensureDiscoveryTokensColumn(),this.createPendingMessagesTable(),this.renameSessionIdColumns(),this.repairSessionIdColumnRename(),this.addFailedAtEpochColumn(),this.addOnUpdateCascadeToForeignKeys(),this.addObservationContentHashColumn(),this.addSessionCustomTitleColumn(),this.addSessionPlatformSourceColumn(),this.addObservationModelColumns(),this.ensureMergedIntoProjectColumns(),this.addObservationSubagentColumns(),this.addObservationsUniqueContentHashIndex(),this.addObservationsMetadataColumn(),this.dropDeadPendingMessagesColumns(),this.ensurePendingMessagesToolUseIdColumn(),this.dropWorkerPidColumn(),this.ensureSDKSessionsPlatformContentIdentity(),this.ensureUserPromptsSessionDbId(),this.ensurePendingMessagesSessionToolUniqueIndex()}getIndexColumns(e){return this.db.query(`PRAGMA index_info(${JSON.stringify(e)})`).all().map(t=>t.name)}hasUniqueIndexOnColumns(e,t){return this.db.query(`PRAGMA index_list(${e})`).all().some(r=>{if(r.unique!==1)return!1;let o=this.getIndexColumns(r.name);return o.length===t.length&&o.every((i,a)=>i===t[a])})}resolvePromptSessionDbId(e,t,s){if(t!==void 0)return t;let r=s?N(s):void 0;return r?this.db.prepare(`
22
+ `).get(a,s,o)??void 0}var Le=["private","claude-mem-context","system_instruction","system-instruction","persisted-output","system-reminder"],Ae=new RegExp(`<(${Le.join("|")})\\b[^>]*>[\\s\\S]*?</\\1>`,"g"),De=/<system-reminder>[\s\S]*?<\/system-reminder>/g,Ce=100;function Qs(n){let e=Object.fromEntries(Le.map(r=>[r,0]));Ae.lastIndex=0;let s=0,t=n.replace(Ae,(r,o)=>(e[o]=(e[o]??0)+1,s+=1,""));return s>Ce&&_.warn("SYSTEM","tag count exceeds limit",void 0,{tagCount:s,maxAllowed:Ce,contentLength:n.length}),{stripped:t.trim(),counts:e}}function Me(n){return Qs(n).stripped}var zs=["task-notification"],vt=new RegExp(`^\\s*<(${zs.join("|")})\\b[^>]*>(?:(?!<\\1\\b|</\\1\\b)[\\s\\S])*</\\1>\\s*$`),yt=256*1024;var ae=4e3;function B(n){let e=n.trim(),t=Me(n).trim()||e;return t.length<=ae?t:(_.debug("DB","Truncated stored prompt text to the configured cap",{originalLength:t.length,storedLength:ae}),`${t.slice(0,ae-1)}\u2026`)}var j=class{db;constructor(e=Se){e instanceof de.Database?this.db=e:(e!==":memory:"&&fe(I),this.db=new de.Database(e),this.db.run("PRAGMA journal_mode = WAL"),this.db.run("PRAGMA synchronous = NORMAL"),this.db.run("PRAGMA foreign_keys = ON"),this.db.run("PRAGMA journal_size_limit = 4194304")),this.initializeSchema(),this.ensureWorkerPortColumn(),this.ensurePromptTrackingColumns(),this.removeSessionSummariesUniqueConstraint(),this.addObservationHierarchicalFields(),this.makeObservationsTextNullable(),this.createUserPromptsTable(),this.ensureDiscoveryTokensColumn(),this.createPendingMessagesTable(),this.renameSessionIdColumns(),this.addFailedAtEpochColumn(),this.addOnUpdateCascadeToForeignKeys(),this.addObservationContentHashColumn(),this.addSessionCustomTitleColumn(),this.addSessionPlatformSourceColumn(),this.addObservationModelColumns(),this.ensureMergedIntoProjectColumns(),this.addObservationSubagentColumns(),this.addObservationsUniqueContentHashIndex(),this.addObservationsMetadataColumn(),this.dropDeadPendingMessagesColumns(),this.ensurePendingMessagesToolUseIdColumn(),this.dropWorkerPidColumn(),this.ensureSDKSessionsPlatformContentIdentity(),this.ensureUserPromptsSessionDbId(),this.ensurePendingMessagesSessionToolUniqueIndex()}getIndexColumns(e){return this.db.query(`PRAGMA index_info(${JSON.stringify(e)})`).all().map(s=>s.name)}hasUniqueIndexOnColumns(e,s){return this.db.query(`PRAGMA index_list(${e})`).all().some(r=>{if(r.unique!==1)return!1;let o=this.getIndexColumns(r.name);return o.length===s.length&&o.every((i,a)=>i===s[a])})}resolvePromptSessionDbId(e,s,t){if(s!==void 0)return s;let r=t?A(t):void 0;return r?this.db.prepare(`
23
23
  SELECT id
24
24
  FROM sdk_sessions
25
25
  WHERE COALESCE(NULLIF(platform_source, ''), ?) = ?
26
26
  AND content_session_id = ?
27
27
  LIMIT 1
28
- `).get(c,r,e)?.id??null:this.db.prepare(`
28
+ `).get(p,r,e)?.id??null:this.db.prepare(`
29
29
  SELECT id
30
30
  FROM sdk_sessions
31
31
  WHERE content_session_id = ?
32
- ORDER BY CASE COALESCE(NULLIF(platform_source, ''), '${c}')
33
- WHEN '${c}' THEN 0
32
+ ORDER BY CASE COALESCE(NULLIF(platform_source, ''), '${p}')
33
+ WHEN '${p}' THEN 0
34
34
  ELSE 1
35
35
  END, id
36
36
  LIMIT 1
37
- `).get(e)?.id??null}dropWorkerPidColumn(){let e=this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(32),s=this.db.query("PRAGMA table_info(pending_messages)").all().some(r=>r.name==="worker_pid");if(!(e&&!s)){if(s)try{this.db.run("DROP INDEX IF EXISTS idx_pending_messages_worker_pid"),this.db.run("ALTER TABLE pending_messages DROP COLUMN worker_pid"),E.debug("DB","Dropped worker_pid column and its index from pending_messages")}catch(r){E.warn("DB","Failed to drop worker_pid column from pending_messages",{},r instanceof Error?r:new Error(String(r)));return}e||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(32,new Date().toISOString())}}ensureSDKSessionsPlatformContentIdentity(){let e=this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(33),t=this.hasUniqueIndexOnColumns("sdk_sessions",["content_session_id"]),s=this.hasUniqueIndexOnColumns("sdk_sessions",["platform_source","content_session_id"]),o=this.db.query("PRAGMA table_info(sdk_sessions)").all().some(i=>i.name==="platform_source");if(!(e&&!t&&s&&o)){if(o||this.db.run(`ALTER TABLE sdk_sessions ADD COLUMN platform_source TEXT NOT NULL DEFAULT '${c}'`),this.db.run(`
37
+ `).get(e)?.id??null}dropWorkerPidColumn(){let e=this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(32),t=this.db.query("PRAGMA table_info(pending_messages)").all().some(r=>r.name==="worker_pid");if(!(e&&!t)){if(t)try{this.db.run("DROP INDEX IF EXISTS idx_pending_messages_worker_pid"),this.db.run("ALTER TABLE pending_messages DROP COLUMN worker_pid"),_.debug("DB","Dropped worker_pid column and its index from pending_messages")}catch(r){_.warn("DB","Failed to drop worker_pid column from pending_messages",{},r instanceof Error?r:new Error(String(r)));return}e||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(32,new Date().toISOString())}}ensureSDKSessionsPlatformContentIdentity(){let e=this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(33),s=this.hasUniqueIndexOnColumns("sdk_sessions",["content_session_id"]),t=this.hasUniqueIndexOnColumns("sdk_sessions",["platform_source","content_session_id"]),o=this.db.query("PRAGMA table_info(sdk_sessions)").all().some(i=>i.name==="platform_source");if(!(e&&!s&&t&&o)){if(o||this.db.run(`ALTER TABLE sdk_sessions ADD COLUMN platform_source TEXT NOT NULL DEFAULT '${p}'`),this.db.run(`
38
38
  UPDATE sdk_sessions
39
- SET platform_source = '${c}'
39
+ SET platform_source = '${p}'
40
40
  WHERE platform_source IS NULL OR platform_source = ''
41
- `),t){this.db.run("PRAGMA foreign_keys = OFF"),this.db.run("BEGIN TRANSACTION");try{this.db.run("DROP TABLE IF EXISTS sdk_sessions_new"),this.db.run(`
42
- CREATE TABLE sdk_sessions_new (
43
- id INTEGER PRIMARY KEY AUTOINCREMENT,
44
- content_session_id TEXT NOT NULL,
45
- memory_session_id TEXT UNIQUE,
46
- project TEXT NOT NULL,
47
- platform_source TEXT NOT NULL DEFAULT '${c}',
48
- user_prompt TEXT,
49
- started_at TEXT NOT NULL,
50
- started_at_epoch INTEGER NOT NULL,
51
- completed_at TEXT,
52
- completed_at_epoch INTEGER,
53
- status TEXT NOT NULL DEFAULT 'active' CHECK(status IN ('active', 'completed', 'failed')),
54
- worker_port INTEGER,
55
- prompt_counter INTEGER DEFAULT 0,
56
- custom_title TEXT
57
- )
58
- `),this.db.run(`
59
- INSERT INTO sdk_sessions_new (
60
- id, content_session_id, memory_session_id, project, platform_source,
61
- user_prompt, started_at, started_at_epoch, completed_at, completed_at_epoch,
62
- status, worker_port, prompt_counter, custom_title
63
- )
64
- SELECT
65
- id, content_session_id, memory_session_id, project,
66
- COALESCE(NULLIF(platform_source, ''), '${c}'),
67
- user_prompt, started_at, started_at_epoch, completed_at, completed_at_epoch,
68
- status, worker_port, prompt_counter, custom_title
69
- FROM sdk_sessions
70
- `),this.db.run("DROP TABLE sdk_sessions"),this.db.run("ALTER TABLE sdk_sessions_new RENAME TO sdk_sessions"),this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_claude_id ON sdk_sessions(content_session_id)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_sdk_id ON sdk_sessions(memory_session_id)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_project ON sdk_sessions(project)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_status ON sdk_sessions(status)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_started ON sdk_sessions(started_at_epoch DESC)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_platform_source ON sdk_sessions(platform_source)"),this.db.run("CREATE UNIQUE INDEX IF NOT EXISTS ux_sdk_sessions_platform_content ON sdk_sessions(platform_source, content_session_id)"),e||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(33,new Date().toISOString()),this.db.run("COMMIT")}catch(i){throw this.db.run("ROLLBACK"),i}finally{this.db.run("PRAGMA foreign_keys = ON")}return}this.db.run("CREATE UNIQUE INDEX IF NOT EXISTS ux_sdk_sessions_platform_content ON sdk_sessions(platform_source, content_session_id)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_platform_source ON sdk_sessions(platform_source)"),e||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(33,new Date().toISOString())}}ensureUserPromptsSessionDbId(){let e=this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(34);if(this.db.query("SELECT name FROM sqlite_master WHERE type='table' AND name='user_prompts'").all().length===0){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(34,new Date().toISOString());return}let r=this.db.query("PRAGMA table_info(user_prompts)").all().some(_=>_.name==="session_db_id"),i=this.db.query("PRAGMA foreign_key_list(user_prompts)").all().some(_=>_.table==="sdk_sessions"&&_.from==="content_session_id");if(e&&r&&!i)return;let a=this.db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='user_prompts_fts'").all().length>0,d=r?`COALESCE(up.session_db_id, (
41
+ `),s){this.db.run("PRAGMA foreign_keys = OFF"),this.db.run("BEGIN TRANSACTION");try{this.rebuildSdkSessionsWithCompositeIdentity(e),this.db.run("COMMIT")}catch(i){this.db.run("ROLLBACK");let a=i instanceof Error?i:new Error(String(i));throw _.error("DB","Failed to rebuild sdk_sessions with composite identity, rolled back",{},a),i}finally{this.db.run("PRAGMA foreign_keys = ON")}return}this.db.run("CREATE UNIQUE INDEX IF NOT EXISTS ux_sdk_sessions_platform_content ON sdk_sessions(platform_source, content_session_id)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_platform_source ON sdk_sessions(platform_source)"),e||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(33,new Date().toISOString())}}rebuildSdkSessionsWithCompositeIdentity(e){this.db.run("DROP TABLE IF EXISTS sdk_sessions_new"),this.db.run(`
42
+ CREATE TABLE sdk_sessions_new (
43
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
44
+ content_session_id TEXT NOT NULL,
45
+ memory_session_id TEXT UNIQUE,
46
+ project TEXT NOT NULL,
47
+ platform_source TEXT NOT NULL DEFAULT '${p}',
48
+ user_prompt TEXT,
49
+ started_at TEXT NOT NULL,
50
+ started_at_epoch INTEGER NOT NULL,
51
+ completed_at TEXT,
52
+ completed_at_epoch INTEGER,
53
+ status TEXT NOT NULL DEFAULT 'active' CHECK(status IN ('active', 'completed', 'failed')),
54
+ worker_port INTEGER,
55
+ prompt_counter INTEGER DEFAULT 0,
56
+ custom_title TEXT
57
+ )
58
+ `),this.db.run(`
59
+ INSERT INTO sdk_sessions_new (
60
+ id, content_session_id, memory_session_id, project, platform_source,
61
+ user_prompt, started_at, started_at_epoch, completed_at, completed_at_epoch,
62
+ status, worker_port, prompt_counter, custom_title
63
+ )
64
+ SELECT
65
+ id, content_session_id, memory_session_id, project,
66
+ COALESCE(NULLIF(platform_source, ''), '${p}'),
67
+ user_prompt, started_at, started_at_epoch, completed_at, completed_at_epoch,
68
+ status, worker_port, prompt_counter, custom_title
69
+ FROM sdk_sessions
70
+ `),this.db.run("DROP TABLE sdk_sessions"),this.db.run("ALTER TABLE sdk_sessions_new RENAME TO sdk_sessions"),this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_claude_id ON sdk_sessions(content_session_id)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_sdk_id ON sdk_sessions(memory_session_id)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_project ON sdk_sessions(project)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_status ON sdk_sessions(status)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_started ON sdk_sessions(started_at_epoch DESC)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_platform_source ON sdk_sessions(platform_source)"),this.db.run("CREATE UNIQUE INDEX IF NOT EXISTS ux_sdk_sessions_platform_content ON sdk_sessions(platform_source, content_session_id)"),e||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(33,new Date().toISOString())}ensureUserPromptsSessionDbId(){let e=this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(34);if(this.db.query("SELECT name FROM sqlite_master WHERE type='table' AND name='user_prompts'").all().length===0){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(34,new Date().toISOString());return}let r=this.db.query("PRAGMA table_info(user_prompts)").all().some(u=>u.name==="session_db_id"),i=this.db.query("PRAGMA foreign_key_list(user_prompts)").all().some(u=>u.table==="sdk_sessions"&&u.from==="content_session_id");if(e&&r&&!i)return;let a=this.db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='user_prompts_fts'").all().length>0,d=r?`COALESCE(up.session_db_id, (
71
71
  SELECT s.id FROM sdk_sessions s
72
72
  WHERE s.content_session_id = up.content_session_id
73
- ORDER BY CASE COALESCE(NULLIF(s.platform_source, ''), '${c}')
74
- WHEN '${c}' THEN 0
73
+ ORDER BY CASE COALESCE(NULLIF(s.platform_source, ''), '${p}')
74
+ WHEN '${p}' THEN 0
75
75
  ELSE 1
76
76
  END, s.id
77
77
  LIMIT 1
78
78
  ))`:`(
79
79
  SELECT s.id FROM sdk_sessions s
80
80
  WHERE s.content_session_id = up.content_session_id
81
- ORDER BY CASE COALESCE(NULLIF(s.platform_source, ''), '${c}')
82
- WHEN '${c}' THEN 0
81
+ ORDER BY CASE COALESCE(NULLIF(s.platform_source, ''), '${p}')
82
+ WHEN '${p}' THEN 0
83
83
  ELSE 1
84
84
  END, s.id
85
85
  LIMIT 1
86
- )`;this.db.run("PRAGMA foreign_keys = OFF"),this.db.run("BEGIN TRANSACTION");try{this.db.run("DROP TRIGGER IF EXISTS user_prompts_ai"),this.db.run("DROP TRIGGER IF EXISTS user_prompts_ad"),this.db.run("DROP TRIGGER IF EXISTS user_prompts_au"),this.db.run("DROP TABLE IF EXISTS user_prompts_new"),this.db.run(`
87
- CREATE TABLE user_prompts_new (
88
- id INTEGER PRIMARY KEY AUTOINCREMENT,
89
- session_db_id INTEGER,
90
- content_session_id TEXT NOT NULL,
91
- prompt_number INTEGER NOT NULL,
92
- prompt_text TEXT NOT NULL,
93
- created_at TEXT NOT NULL,
94
- created_at_epoch INTEGER NOT NULL,
95
- FOREIGN KEY(session_db_id) REFERENCES sdk_sessions(id) ON DELETE CASCADE
96
- )
97
- `),this.db.run(`
98
- INSERT INTO user_prompts_new (
99
- id, session_db_id, content_session_id, prompt_number,
100
- prompt_text, created_at, created_at_epoch
101
- )
102
- SELECT
103
- up.id,
104
- ${d},
105
- up.content_session_id,
106
- up.prompt_number,
107
- up.prompt_text,
108
- up.created_at,
109
- up.created_at_epoch
110
- FROM user_prompts up
111
- `),this.db.run("DROP TABLE user_prompts"),this.db.run("ALTER TABLE user_prompts_new RENAME TO user_prompts"),this.db.run("CREATE INDEX IF NOT EXISTS idx_user_prompts_session ON user_prompts(session_db_id)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_user_prompts_claude_session ON user_prompts(content_session_id)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_user_prompts_created ON user_prompts(created_at_epoch DESC)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_user_prompts_prompt_number ON user_prompts(prompt_number)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_user_prompts_lookup ON user_prompts(session_db_id, prompt_number)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_user_prompts_content_lookup ON user_prompts(content_session_id, prompt_number)"),a&&(this.db.run(`
112
- CREATE TRIGGER user_prompts_ai AFTER INSERT ON user_prompts BEGIN
113
- INSERT INTO user_prompts_fts(rowid, prompt_text)
114
- VALUES (new.id, new.prompt_text);
115
- END;
86
+ )`;this.db.run("PRAGMA foreign_keys = OFF"),this.db.run("BEGIN TRANSACTION");try{this.rebuildUserPromptsWithSessionDbId(e,d,a),this.db.run("COMMIT")}catch(u){this.db.run("ROLLBACK");let m=u instanceof Error?u:new Error(String(u));throw _.error("DB","Failed to rebuild user_prompts with session_db_id, rolled back",{},m),u}finally{this.db.run("PRAGMA foreign_keys = ON")}}rebuildUserPromptsWithSessionDbId(e,s,t){this.db.run("DROP TRIGGER IF EXISTS user_prompts_ai"),this.db.run("DROP TRIGGER IF EXISTS user_prompts_ad"),this.db.run("DROP TRIGGER IF EXISTS user_prompts_au"),this.db.run("DROP TABLE IF EXISTS user_prompts_new"),this.db.run(`
87
+ CREATE TABLE user_prompts_new (
88
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
89
+ session_db_id INTEGER,
90
+ content_session_id TEXT NOT NULL,
91
+ prompt_number INTEGER NOT NULL,
92
+ prompt_text TEXT NOT NULL,
93
+ created_at TEXT NOT NULL,
94
+ created_at_epoch INTEGER NOT NULL,
95
+ FOREIGN KEY(session_db_id) REFERENCES sdk_sessions(id) ON DELETE CASCADE
96
+ )
97
+ `),this.db.run(`
98
+ INSERT INTO user_prompts_new (
99
+ id, session_db_id, content_session_id, prompt_number,
100
+ prompt_text, created_at, created_at_epoch
101
+ )
102
+ SELECT
103
+ up.id,
104
+ ${s},
105
+ up.content_session_id,
106
+ up.prompt_number,
107
+ up.prompt_text,
108
+ up.created_at,
109
+ up.created_at_epoch
110
+ FROM user_prompts up
111
+ `),this.db.run("DROP TABLE user_prompts"),this.db.run("ALTER TABLE user_prompts_new RENAME TO user_prompts"),this.db.run("CREATE INDEX IF NOT EXISTS idx_user_prompts_session ON user_prompts(session_db_id)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_user_prompts_claude_session ON user_prompts(content_session_id)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_user_prompts_created ON user_prompts(created_at_epoch DESC)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_user_prompts_prompt_number ON user_prompts(prompt_number)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_user_prompts_lookup ON user_prompts(session_db_id, prompt_number)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_user_prompts_content_lookup ON user_prompts(content_session_id, prompt_number)"),t&&(this.db.run(`
112
+ CREATE TRIGGER user_prompts_ai AFTER INSERT ON user_prompts BEGIN
113
+ INSERT INTO user_prompts_fts(rowid, prompt_text)
114
+ VALUES (new.id, new.prompt_text);
115
+ END;
116
116
 
117
- CREATE TRIGGER user_prompts_ad AFTER DELETE ON user_prompts BEGIN
118
- INSERT INTO user_prompts_fts(user_prompts_fts, rowid, prompt_text)
119
- VALUES('delete', old.id, old.prompt_text);
120
- END;
117
+ CREATE TRIGGER user_prompts_ad AFTER DELETE ON user_prompts BEGIN
118
+ INSERT INTO user_prompts_fts(user_prompts_fts, rowid, prompt_text)
119
+ VALUES('delete', old.id, old.prompt_text);
120
+ END;
121
121
 
122
- CREATE TRIGGER user_prompts_au AFTER UPDATE ON user_prompts BEGIN
123
- INSERT INTO user_prompts_fts(user_prompts_fts, rowid, prompt_text)
124
- VALUES('delete', old.id, old.prompt_text);
125
- INSERT INTO user_prompts_fts(rowid, prompt_text)
126
- VALUES (new.id, new.prompt_text);
127
- END;
128
- `),this.db.run("INSERT INTO user_prompts_fts(user_prompts_fts) VALUES('rebuild')")),e||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(34,new Date().toISOString()),this.db.run("COMMIT")}catch(_){throw this.db.run("ROLLBACK"),_}finally{this.db.run("PRAGMA foreign_keys = ON")}}ensurePendingMessagesSessionToolUniqueIndex(){let e=this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(35);if(this.db.query("SELECT name FROM sqlite_master WHERE type='table' AND name='pending_messages'").all().length===0){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(35,new Date().toISOString());return}let s=this.hasUniqueIndexOnColumns("pending_messages",["session_db_id","tool_use_id"]);if(!(e&&s)){this.db.run("BEGIN TRANSACTION");try{this.db.run("DROP INDEX IF EXISTS ux_pending_session_tool"),this.db.run(`
129
- DELETE FROM pending_messages
130
- WHERE id IN (
131
- SELECT id
132
- FROM (
133
- SELECT id,
134
- ROW_NUMBER() OVER (
135
- PARTITION BY session_db_id, tool_use_id
136
- ORDER BY CASE status
137
- WHEN 'processing' THEN 0
138
- WHEN 'pending' THEN 1
139
- ELSE 2
140
- END, id
141
- ) AS duplicate_rank
142
- FROM pending_messages
143
- WHERE tool_use_id IS NOT NULL
144
- )
145
- WHERE duplicate_rank > 1
122
+ CREATE TRIGGER user_prompts_au AFTER UPDATE ON user_prompts BEGIN
123
+ INSERT INTO user_prompts_fts(user_prompts_fts, rowid, prompt_text)
124
+ VALUES('delete', old.id, old.prompt_text);
125
+ INSERT INTO user_prompts_fts(rowid, prompt_text)
126
+ VALUES (new.id, new.prompt_text);
127
+ END;
128
+ `),this.db.run("INSERT INTO user_prompts_fts(user_prompts_fts) VALUES('rebuild')")),e||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(34,new Date().toISOString())}ensurePendingMessagesSessionToolUniqueIndex(){let e=this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(35);if(this.db.query("SELECT name FROM sqlite_master WHERE type='table' AND name='pending_messages'").all().length===0){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(35,new Date().toISOString());return}let t=this.hasUniqueIndexOnColumns("pending_messages",["session_db_id","tool_use_id"]);if(!(e&&t)){this.db.run("BEGIN TRANSACTION");try{this.recreatePendingSessionToolUniqueIndex(e),this.db.run("COMMIT")}catch(r){this.db.run("ROLLBACK");let o=r instanceof Error?r:new Error(String(r));throw _.error("DB","Failed to recreate ux_pending_session_tool index, rolled back",{},o),r}}}recreatePendingSessionToolUniqueIndex(e){this.db.run("DROP INDEX IF EXISTS ux_pending_session_tool"),this.db.run(`
129
+ DELETE FROM pending_messages
130
+ WHERE id IN (
131
+ SELECT id
132
+ FROM (
133
+ SELECT id,
134
+ ROW_NUMBER() OVER (
135
+ PARTITION BY session_db_id, tool_use_id
136
+ ORDER BY CASE status
137
+ WHEN 'processing' THEN 0
138
+ WHEN 'pending' THEN 1
139
+ ELSE 2
140
+ END, id
141
+ ) AS duplicate_rank
142
+ FROM pending_messages
143
+ WHERE tool_use_id IS NOT NULL
146
144
  )
147
- `),this.db.run(`
148
- CREATE UNIQUE INDEX IF NOT EXISTS ux_pending_session_tool
149
- ON pending_messages(session_db_id, tool_use_id)
150
- WHERE tool_use_id IS NOT NULL
151
- `),e||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(35,new Date().toISOString()),this.db.run("COMMIT")}catch(r){throw this.db.run("ROLLBACK"),r}}}dropDeadPendingMessagesColumns(){let e=this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(31),t=this.db.query("PRAGMA table_info(pending_messages)").all(),s=new Set(t.map(i=>i.name)),o=["retry_count","failed_at_epoch","completed_at_epoch"].filter(i=>s.has(i));if(!(e&&o.length===0)){if(o.length>0){this.db.run("BEGIN TRANSACTION");try{this.db.run("DELETE FROM pending_messages WHERE status NOT IN ('pending', 'processing')");for(let i of o)this.db.run(`ALTER TABLE pending_messages DROP COLUMN ${i}`),E.debug("DB",`Dropped dead column ${i} from pending_messages`);e||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(31,new Date().toISOString()),this.db.run("COMMIT")}catch(i){this.db.run("ROLLBACK"),E.warn("DB","Failed to drop dead columns from pending_messages",{},i instanceof Error?i:new Error(String(i)));return}return}e||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(31,new Date().toISOString())}}initializeSchema(){this.db.run(`
145
+ WHERE duplicate_rank > 1
146
+ )
147
+ `),this.db.run(`
148
+ CREATE UNIQUE INDEX IF NOT EXISTS ux_pending_session_tool
149
+ ON pending_messages(session_db_id, tool_use_id)
150
+ WHERE tool_use_id IS NOT NULL
151
+ `),e||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(35,new Date().toISOString())}dropDeadPendingMessagesColumns(){let e=this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(31),s=this.db.query("PRAGMA table_info(pending_messages)").all(),t=new Set(s.map(i=>i.name)),o=["retry_count","failed_at_epoch","completed_at_epoch"].filter(i=>t.has(i));if(!(e&&o.length===0)){if(o.length>0){this.db.run("BEGIN TRANSACTION");try{this.db.run("DELETE FROM pending_messages WHERE status NOT IN ('pending', 'processing')");for(let i of o)this.db.run(`ALTER TABLE pending_messages DROP COLUMN ${i}`),_.debug("DB",`Dropped dead column ${i} from pending_messages`);e||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(31,new Date().toISOString()),this.db.run("COMMIT")}catch(i){this.db.run("ROLLBACK"),_.warn("DB","Failed to drop dead columns from pending_messages",{},i instanceof Error?i:new Error(String(i)));return}return}e||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(31,new Date().toISOString())}}initializeSchema(){this.db.run(`
152
152
  CREATE TABLE IF NOT EXISTS schema_versions (
153
153
  id INTEGER PRIMARY KEY,
154
154
  version INTEGER UNIQUE NOT NULL,
@@ -213,7 +213,7 @@ ${o.stack}`:` ${o.message}`;else if(this.getLevel()===0&&typeof o=="object")try{
213
213
  CREATE INDEX IF NOT EXISTS idx_session_summaries_sdk_session ON session_summaries(memory_session_id);
214
214
  CREATE INDEX IF NOT EXISTS idx_session_summaries_project ON session_summaries(project);
215
215
  CREATE INDEX IF NOT EXISTS idx_session_summaries_created ON session_summaries(created_at_epoch DESC);
216
- `),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(4,new Date().toISOString())}ensureWorkerPortColumn(){this.db.query("PRAGMA table_info(sdk_sessions)").all().some(s=>s.name==="worker_port")||(this.db.run("ALTER TABLE sdk_sessions ADD COLUMN worker_port INTEGER"),E.debug("DB","Added worker_port column to sdk_sessions table")),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(5,new Date().toISOString())}ensurePromptTrackingColumns(){this.db.query("PRAGMA table_info(sdk_sessions)").all().some(a=>a.name==="prompt_counter")||(this.db.run("ALTER TABLE sdk_sessions ADD COLUMN prompt_counter INTEGER DEFAULT 0"),E.debug("DB","Added prompt_counter column to sdk_sessions table")),this.db.query("PRAGMA table_info(observations)").all().some(a=>a.name==="prompt_number")||(this.db.run("ALTER TABLE observations ADD COLUMN prompt_number INTEGER"),E.debug("DB","Added prompt_number column to observations table")),this.db.query("PRAGMA table_info(session_summaries)").all().some(a=>a.name==="prompt_number")||(this.db.run("ALTER TABLE session_summaries ADD COLUMN prompt_number INTEGER"),E.debug("DB","Added prompt_number column to session_summaries table")),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(6,new Date().toISOString())}removeSessionSummariesUniqueConstraint(){if(!this.db.query("PRAGMA index_list(session_summaries)").all().some(s=>s.unique===1&&s.origin!=="pk")){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(7,new Date().toISOString());return}E.debug("DB","Removing UNIQUE constraint from session_summaries.memory_session_id"),this.db.run("BEGIN TRANSACTION"),this.db.run("DROP TABLE IF EXISTS session_summaries_new"),this.db.run(`
216
+ `),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(4,new Date().toISOString())}ensureWorkerPortColumn(){this.db.query("PRAGMA table_info(sdk_sessions)").all().some(t=>t.name==="worker_port")||(this.db.run("ALTER TABLE sdk_sessions ADD COLUMN worker_port INTEGER"),_.debug("DB","Added worker_port column to sdk_sessions table")),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(5,new Date().toISOString())}ensurePromptTrackingColumns(){this.db.query("PRAGMA table_info(sdk_sessions)").all().some(a=>a.name==="prompt_counter")||(this.db.run("ALTER TABLE sdk_sessions ADD COLUMN prompt_counter INTEGER DEFAULT 0"),_.debug("DB","Added prompt_counter column to sdk_sessions table")),this.db.query("PRAGMA table_info(observations)").all().some(a=>a.name==="prompt_number")||(this.db.run("ALTER TABLE observations ADD COLUMN prompt_number INTEGER"),_.debug("DB","Added prompt_number column to observations table")),this.db.query("PRAGMA table_info(session_summaries)").all().some(a=>a.name==="prompt_number")||(this.db.run("ALTER TABLE session_summaries ADD COLUMN prompt_number INTEGER"),_.debug("DB","Added prompt_number column to session_summaries table")),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(6,new Date().toISOString())}removeSessionSummariesUniqueConstraint(){if(!this.db.query("PRAGMA index_list(session_summaries)").all().some(t=>t.unique===1&&t.origin!=="pk")){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(7,new Date().toISOString());return}_.debug("DB","Removing UNIQUE constraint from session_summaries.memory_session_id"),this.db.run("BEGIN TRANSACTION"),this.db.run("DROP TABLE IF EXISTS session_summaries_new"),this.db.run(`
217
217
  CREATE TABLE session_summaries_new (
218
218
  id INTEGER PRIMARY KEY AUTOINCREMENT,
219
219
  memory_session_id TEXT NOT NULL,
@@ -241,7 +241,7 @@ ${o.stack}`:` ${o.message}`;else if(this.getLevel()===0&&typeof o=="object")try{
241
241
  CREATE INDEX idx_session_summaries_sdk_session ON session_summaries(memory_session_id);
242
242
  CREATE INDEX idx_session_summaries_project ON session_summaries(project);
243
243
  CREATE INDEX idx_session_summaries_created ON session_summaries(created_at_epoch DESC);
244
- `),this.db.run("COMMIT"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(7,new Date().toISOString()),E.debug("DB","Successfully removed UNIQUE constraint from session_summaries.memory_session_id")}addObservationHierarchicalFields(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(8))return;if(this.db.query("PRAGMA table_info(observations)").all().some(r=>r.name==="title")){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(8,new Date().toISOString());return}E.debug("DB","Adding hierarchical fields to observations table"),this.db.run(`
244
+ `),this.db.run("COMMIT"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(7,new Date().toISOString()),_.debug("DB","Successfully removed UNIQUE constraint from session_summaries.memory_session_id")}addObservationHierarchicalFields(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(8))return;if(this.db.query("PRAGMA table_info(observations)").all().some(r=>r.name==="title")){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(8,new Date().toISOString());return}_.debug("DB","Adding hierarchical fields to observations table"),this.db.run(`
245
245
  ALTER TABLE observations ADD COLUMN title TEXT;
246
246
  ALTER TABLE observations ADD COLUMN subtitle TEXT;
247
247
  ALTER TABLE observations ADD COLUMN facts TEXT;
@@ -249,7 +249,7 @@ ${o.stack}`:` ${o.message}`;else if(this.getLevel()===0&&typeof o=="object")try{
249
249
  ALTER TABLE observations ADD COLUMN concepts TEXT;
250
250
  ALTER TABLE observations ADD COLUMN files_read TEXT;
251
251
  ALTER TABLE observations ADD COLUMN files_modified TEXT;
252
- `),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(8,new Date().toISOString()),E.debug("DB","Successfully added hierarchical fields to observations table")}makeObservationsTextNullable(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(9))return;let s=this.db.query("PRAGMA table_info(observations)").all().find(r=>r.name==="text");if(!s||s.notnull===0){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(9,new Date().toISOString());return}E.debug("DB","Making observations.text nullable"),this.db.run("BEGIN TRANSACTION"),this.db.run("DROP TABLE IF EXISTS observations_new"),this.db.run(`
252
+ `),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(8,new Date().toISOString()),_.debug("DB","Successfully added hierarchical fields to observations table")}makeObservationsTextNullable(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(9))return;let t=this.db.query("PRAGMA table_info(observations)").all().find(r=>r.name==="text");if(!t||t.notnull===0){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(9,new Date().toISOString());return}_.debug("DB","Making observations.text nullable"),this.db.run("BEGIN TRANSACTION"),this.db.run("DROP TABLE IF EXISTS observations_new"),this.db.run(`
253
253
  CREATE TABLE observations_new (
254
254
  id INTEGER PRIMARY KEY AUTOINCREMENT,
255
255
  memory_session_id TEXT NOT NULL,
@@ -279,7 +279,7 @@ ${o.stack}`:` ${o.message}`;else if(this.getLevel()===0&&typeof o=="object")try{
279
279
  CREATE INDEX idx_observations_project ON observations(project);
280
280
  CREATE INDEX idx_observations_type ON observations(type);
281
281
  CREATE INDEX idx_observations_created ON observations(created_at_epoch DESC);
282
- `),this.db.run("COMMIT"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(9,new Date().toISOString()),E.debug("DB","Successfully made observations.text nullable")}createUserPromptsTable(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(10))return;if(this.db.query("PRAGMA table_info(user_prompts)").all().length>0){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(10,new Date().toISOString());return}E.debug("DB","Creating user_prompts table with FTS5 support"),this.db.run("BEGIN TRANSACTION"),this.db.run(`
282
+ `),this.db.run("COMMIT"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(9,new Date().toISOString()),_.debug("DB","Successfully made observations.text nullable")}createUserPromptsTable(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(10))return;if(this.db.query("PRAGMA table_info(user_prompts)").all().length>0){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(10,new Date().toISOString());return}_.debug("DB","Creating user_prompts table with FTS5 support"),this.db.run("BEGIN TRANSACTION"),this.db.run(`
283
283
  CREATE TABLE user_prompts (
284
284
  id INTEGER PRIMARY KEY AUTOINCREMENT,
285
285
  session_db_id INTEGER,
@@ -297,7 +297,7 @@ ${o.stack}`:` ${o.message}`;else if(this.getLevel()===0&&typeof o=="object")try{
297
297
  CREATE INDEX idx_user_prompts_prompt_number ON user_prompts(prompt_number);
298
298
  CREATE INDEX idx_user_prompts_lookup ON user_prompts(session_db_id, prompt_number);
299
299
  CREATE INDEX idx_user_prompts_content_lookup ON user_prompts(content_session_id, prompt_number);
300
- `);let s=`
300
+ `);let t=`
301
301
  CREATE VIRTUAL TABLE user_prompts_fts USING fts5(
302
302
  prompt_text,
303
303
  content='user_prompts',
@@ -320,7 +320,7 @@ ${o.stack}`:` ${o.message}`;else if(this.getLevel()===0&&typeof o=="object")try{
320
320
  INSERT INTO user_prompts_fts(rowid, prompt_text)
321
321
  VALUES (new.id, new.prompt_text);
322
322
  END;
323
- `;try{this.db.run(s),this.db.run(r)}catch(o){o instanceof Error?E.warn("DB","FTS5 not available \u2014 user_prompts_fts skipped (search uses ChromaDB)",{},o):E.warn("DB","FTS5 not available \u2014 user_prompts_fts skipped (search uses ChromaDB)",{},new Error(String(o))),this.db.run("COMMIT"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(10,new Date().toISOString()),E.debug("DB","Created user_prompts table (without FTS5)");return}this.db.run("COMMIT"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(10,new Date().toISOString()),E.debug("DB","Successfully created user_prompts table")}ensureDiscoveryTokensColumn(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(11))return;this.db.query("PRAGMA table_info(observations)").all().some(i=>i.name==="discovery_tokens")||(this.db.run("ALTER TABLE observations ADD COLUMN discovery_tokens INTEGER DEFAULT 0"),E.debug("DB","Added discovery_tokens column to observations table")),this.db.query("PRAGMA table_info(session_summaries)").all().some(i=>i.name==="discovery_tokens")||(this.db.run("ALTER TABLE session_summaries ADD COLUMN discovery_tokens INTEGER DEFAULT 0"),E.debug("DB","Added discovery_tokens column to session_summaries table")),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(11,new Date().toISOString())}createPendingMessagesTable(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(16))return;if(this.db.query("SELECT name FROM sqlite_master WHERE type='table' AND name='pending_messages'").all().length>0){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(16,new Date().toISOString());return}E.debug("DB","Creating pending_messages table"),this.db.run(`
323
+ `;try{this.db.run(t),this.db.run(r)}catch(o){o instanceof Error?_.warn("DB","FTS5 not available \u2014 user_prompts_fts skipped (search uses ChromaDB)",{},o):_.warn("DB","FTS5 not available \u2014 user_prompts_fts skipped (search uses ChromaDB)",{},new Error(String(o))),this.db.run("COMMIT"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(10,new Date().toISOString()),_.debug("DB","Created user_prompts table (without FTS5)");return}this.db.run("COMMIT"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(10,new Date().toISOString()),_.debug("DB","Successfully created user_prompts table")}ensureDiscoveryTokensColumn(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(11))return;this.db.query("PRAGMA table_info(observations)").all().some(i=>i.name==="discovery_tokens")||(this.db.run("ALTER TABLE observations ADD COLUMN discovery_tokens INTEGER DEFAULT 0"),_.debug("DB","Added discovery_tokens column to observations table")),this.db.query("PRAGMA table_info(session_summaries)").all().some(i=>i.name==="discovery_tokens")||(this.db.run("ALTER TABLE session_summaries ADD COLUMN discovery_tokens INTEGER DEFAULT 0"),_.debug("DB","Added discovery_tokens column to session_summaries table")),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(11,new Date().toISOString())}createPendingMessagesTable(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(16))return;if(this.db.query("SELECT name FROM sqlite_master WHERE type='table' AND name='pending_messages'").all().length>0){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(16,new Date().toISOString());return}_.debug("DB","Creating pending_messages table"),this.db.run(`
324
324
  CREATE TABLE pending_messages (
325
325
  id INTEGER PRIMARY KEY AUTOINCREMENT,
326
326
  session_db_id INTEGER NOT NULL,
@@ -337,9 +337,9 @@ ${o.stack}`:` ${o.message}`;else if(this.getLevel()===0&&typeof o=="object")try{
337
337
  created_at_epoch INTEGER NOT NULL,
338
338
  FOREIGN KEY (session_db_id) REFERENCES sdk_sessions(id) ON DELETE CASCADE
339
339
  )
340
- `),this.db.run("CREATE INDEX IF NOT EXISTS idx_pending_messages_session ON pending_messages(session_db_id)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_pending_messages_status ON pending_messages(status)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_pending_messages_claude_session ON pending_messages(content_session_id)"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(16,new Date().toISOString()),E.debug("DB","pending_messages table created successfully")}renameSessionIdColumns(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(17))return;E.debug("DB","Checking session ID columns for semantic clarity rename");let t=0,s=(r,o,i)=>{let a=this.db.query(`PRAGMA table_info(${r})`).all(),d=a.some(m=>m.name===o);return a.some(m=>m.name===i)?!1:d?(this.db.run(`ALTER TABLE ${r} RENAME COLUMN ${o} TO ${i}`),E.debug("DB",`Renamed ${r}.${o} to ${i}`),!0):(E.warn("DB",`Column ${o} not found in ${r}, skipping rename`),!1)};s("sdk_sessions","claude_session_id","content_session_id")&&t++,s("sdk_sessions","sdk_session_id","memory_session_id")&&t++,s("pending_messages","claude_session_id","content_session_id")&&t++,s("observations","sdk_session_id","memory_session_id")&&t++,s("session_summaries","sdk_session_id","memory_session_id")&&t++,s("user_prompts","claude_session_id","content_session_id")&&t++,this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(17,new Date().toISOString()),t>0?E.debug("DB",`Successfully renamed ${t} session ID columns`):E.debug("DB","No session ID column renames needed (already up to date)")}repairSessionIdColumnRename(){this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(19)||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(19,new Date().toISOString())}addFailedAtEpochColumn(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(20))return;this.db.query("PRAGMA table_info(pending_messages)").all().some(r=>r.name==="failed_at_epoch")||(this.db.run("ALTER TABLE pending_messages ADD COLUMN failed_at_epoch INTEGER"),E.debug("DB","Added failed_at_epoch column to pending_messages table")),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(20,new Date().toISOString())}addOnUpdateCascadeToForeignKeys(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(21))return;E.debug("DB","Adding ON UPDATE CASCADE to FK constraints on observations and session_summaries"),this.db.run("PRAGMA foreign_keys = OFF"),this.db.run("BEGIN TRANSACTION"),this.db.run("DROP TRIGGER IF EXISTS observations_ai"),this.db.run("DROP TRIGGER IF EXISTS observations_ad"),this.db.run("DROP TRIGGER IF EXISTS observations_au"),this.db.run("DROP TABLE IF EXISTS observations_new");let t=this.db.query("PRAGMA table_info(observations)").all(),s=t.some(S=>S.name==="metadata"),r=t.some(S=>S.name==="content_hash"),o=s?`,
341
- metadata TEXT`:"",i=s?", metadata":"",a=r?`,
342
- content_hash TEXT`:"",d=r?", content_hash":"",_=`
340
+ `),this.db.run("CREATE INDEX IF NOT EXISTS idx_pending_messages_session ON pending_messages(session_db_id)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_pending_messages_status ON pending_messages(status)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_pending_messages_claude_session ON pending_messages(content_session_id)"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(16,new Date().toISOString()),_.debug("DB","pending_messages table created successfully")}renameSessionIdColumns(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(17))return;_.debug("DB","Checking session ID columns for semantic clarity rename");let s=0,t=(r,o,i)=>{let a=this.db.query(`PRAGMA table_info(${r})`).all(),d=a.some(m=>m.name===o);return a.some(m=>m.name===i)?!1:d?(this.db.run(`ALTER TABLE ${r} RENAME COLUMN ${o} TO ${i}`),_.debug("DB",`Renamed ${r}.${o} to ${i}`),!0):(_.warn("DB",`Column ${o} not found in ${r}, skipping rename`),!1)};t("sdk_sessions","claude_session_id","content_session_id")&&s++,t("sdk_sessions","sdk_session_id","memory_session_id")&&s++,t("pending_messages","claude_session_id","content_session_id")&&s++,t("observations","sdk_session_id","memory_session_id")&&s++,t("session_summaries","sdk_session_id","memory_session_id")&&s++,t("user_prompts","claude_session_id","content_session_id")&&s++,this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(17,new Date().toISOString()),s>0?_.debug("DB",`Successfully renamed ${s} session ID columns`):_.debug("DB","No session ID column renames needed (already up to date)")}addFailedAtEpochColumn(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(20))return;this.db.query("PRAGMA table_info(pending_messages)").all().some(r=>r.name==="failed_at_epoch")||(this.db.run("ALTER TABLE pending_messages ADD COLUMN failed_at_epoch INTEGER"),_.debug("DB","Added failed_at_epoch column to pending_messages table")),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(20,new Date().toISOString())}addOnUpdateCascadeToForeignKeys(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(21))return;_.debug("DB","Adding ON UPDATE CASCADE to FK constraints on observations and session_summaries"),this.db.run("PRAGMA foreign_keys = OFF"),this.db.run("BEGIN TRANSACTION"),this.db.run("DROP TRIGGER IF EXISTS observations_ai"),this.db.run("DROP TRIGGER IF EXISTS observations_ad"),this.db.run("DROP TRIGGER IF EXISTS observations_au"),this.db.run("DROP TABLE IF EXISTS observations_new");let s=this.db.query("PRAGMA table_info(observations)").all(),t=s.some(S=>S.name==="metadata"),r=s.some(S=>S.name==="content_hash"),o=t?`,
341
+ metadata TEXT`:"",i=t?", metadata":"",a=r?`,
342
+ content_hash TEXT`:"",d=r?", content_hash":"",u=`
343
343
  CREATE TABLE observations_new (
344
344
  id INTEGER PRIMARY KEY AUTOINCREMENT,
345
345
  memory_session_id TEXT NOT NULL,
@@ -370,7 +370,7 @@ ${o.stack}`:` ${o.message}`;else if(this.getLevel()===0&&typeof o=="object")try{
370
370
  CREATE INDEX idx_observations_project ON observations(project);
371
371
  CREATE INDEX idx_observations_type ON observations(type);
372
372
  CREATE INDEX idx_observations_created ON observations(created_at_epoch DESC);
373
- `,p=`
373
+ `,c=`
374
374
  CREATE TRIGGER IF NOT EXISTS observations_ai AFTER INSERT ON observations BEGIN
375
375
  INSERT INTO observations_fts(rowid, title, subtitle, narrative, text, facts, concepts)
376
376
  VALUES (new.id, new.title, new.subtitle, new.narrative, new.text, new.facts, new.concepts);
@@ -387,7 +387,7 @@ ${o.stack}`:` ${o.message}`;else if(this.getLevel()===0&&typeof o=="object")try{
387
387
  INSERT INTO observations_fts(rowid, title, subtitle, narrative, text, facts, concepts)
388
388
  VALUES (new.id, new.title, new.subtitle, new.narrative, new.text, new.facts, new.concepts);
389
389
  END;
390
- `;this.db.run("DROP TRIGGER IF EXISTS session_summaries_ai"),this.db.run("DROP TRIGGER IF EXISTS session_summaries_ad"),this.db.run("DROP TRIGGER IF EXISTS session_summaries_au"),this.db.run("DROP TABLE IF EXISTS session_summaries_new");let g=`
390
+ `;this.db.run("DROP TRIGGER IF EXISTS session_summaries_ai"),this.db.run("DROP TRIGGER IF EXISTS session_summaries_ad"),this.db.run("DROP TRIGGER IF EXISTS session_summaries_au"),this.db.run("DROP TABLE IF EXISTS session_summaries_new");let T=`
391
391
  CREATE TABLE session_summaries_new (
392
392
  id INTEGER PRIMARY KEY AUTOINCREMENT,
393
393
  memory_session_id TEXT NOT NULL,
@@ -406,17 +406,17 @@ ${o.stack}`:` ${o.message}`;else if(this.getLevel()===0&&typeof o=="object")try{
406
406
  created_at_epoch INTEGER NOT NULL,
407
407
  FOREIGN KEY(memory_session_id) REFERENCES sdk_sessions(memory_session_id) ON DELETE CASCADE ON UPDATE CASCADE
408
408
  )
409
- `,A=`
409
+ `,h=`
410
410
  INSERT INTO session_summaries_new
411
411
  SELECT id, memory_session_id, project, request, investigated, learned,
412
412
  completed, next_steps, files_read, files_edited, notes,
413
413
  prompt_number, discovery_tokens, created_at, created_at_epoch
414
414
  FROM session_summaries
415
- `,h=`
415
+ `,b=`
416
416
  CREATE INDEX idx_session_summaries_sdk_session ON session_summaries(memory_session_id);
417
417
  CREATE INDEX idx_session_summaries_project ON session_summaries(project);
418
418
  CREATE INDEX idx_session_summaries_created ON session_summaries(created_at_epoch DESC);
419
- `,f=`
419
+ `,g=`
420
420
  CREATE TRIGGER IF NOT EXISTS session_summaries_ai AFTER INSERT ON session_summaries BEGIN
421
421
  INSERT INTO session_summaries_fts(rowid, request, investigated, learned, completed, next_steps, notes)
422
422
  VALUES (new.id, new.request, new.investigated, new.learned, new.completed, new.next_steps, new.notes);
@@ -433,169 +433,97 @@ ${o.stack}`:` ${o.message}`;else if(this.getLevel()===0&&typeof o=="object")try{
433
433
  INSERT INTO session_summaries_fts(rowid, request, investigated, learned, completed, next_steps, notes)
434
434
  VALUES (new.id, new.request, new.investigated, new.learned, new.completed, new.next_steps, new.notes);
435
435
  END;
436
- `;try{this.recreateObservationsWithCascade(_,m,l,p),this.recreateSessionSummariesWithCascade(g,A,h,f),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(21,new Date().toISOString()),this.db.run("COMMIT"),this.db.run("PRAGMA foreign_keys = ON"),E.debug("DB","Successfully added ON UPDATE CASCADE to FK constraints")}catch(S){throw this.db.run("ROLLBACK"),this.db.run("PRAGMA foreign_keys = ON"),S instanceof Error?S:new Error(String(S))}}recreateObservationsWithCascade(e,t,s,r){this.db.run(e),this.db.run(t),this.db.run("DROP TABLE observations"),this.db.run("ALTER TABLE observations_new RENAME TO observations"),this.db.run(s),this.db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='observations_fts'").all().length>0&&this.db.run(r)}recreateSessionSummariesWithCascade(e,t,s,r){this.db.run(e),this.db.run(t),this.db.run("DROP TABLE session_summaries"),this.db.run("ALTER TABLE session_summaries_new RENAME TO session_summaries"),this.db.run(s),this.db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='session_summaries_fts'").all().length>0&&this.db.run(r)}addObservationContentHashColumn(){if(this.db.query("PRAGMA table_info(observations)").all().some(s=>s.name==="content_hash")){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(22,new Date().toISOString());return}this.db.run("ALTER TABLE observations ADD COLUMN content_hash TEXT"),this.db.run("UPDATE observations SET content_hash = substr(hex(randomblob(8)), 1, 16) WHERE content_hash IS NULL"),this.db.run("CREATE INDEX IF NOT EXISTS idx_observations_content_hash ON observations(content_hash, created_at_epoch)"),E.debug("DB","Added content_hash column to observations table with backfill and index"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(22,new Date().toISOString())}addSessionCustomTitleColumn(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(23))return;this.db.query("PRAGMA table_info(sdk_sessions)").all().some(r=>r.name==="custom_title")||(this.db.run("ALTER TABLE sdk_sessions ADD COLUMN custom_title TEXT"),E.debug("DB","Added custom_title column to sdk_sessions table")),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(23,new Date().toISOString())}addSessionPlatformSourceColumn(){let t=this.db.query("PRAGMA table_info(sdk_sessions)").all().some(i=>i.name==="platform_source"),r=this.db.query("PRAGMA index_list(sdk_sessions)").all().some(i=>i.name==="idx_sdk_sessions_platform_source");this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(24)&&t&&r||(t||(this.db.run(`ALTER TABLE sdk_sessions ADD COLUMN platform_source TEXT NOT NULL DEFAULT '${c}'`),E.debug("DB","Added platform_source column to sdk_sessions table")),this.db.run(`
436
+ `;try{this.recreateObservationsWithCascade(u,m,l,c),this.recreateSessionSummariesWithCascade(T,h,b,g),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(21,new Date().toISOString()),this.db.run("COMMIT"),this.db.run("PRAGMA foreign_keys = ON"),_.debug("DB","Successfully added ON UPDATE CASCADE to FK constraints")}catch(S){throw this.db.run("ROLLBACK"),this.db.run("PRAGMA foreign_keys = ON"),S instanceof Error?S:new Error(String(S))}}recreateObservationsWithCascade(e,s,t,r){this.db.run(e),this.db.run(s),this.db.run("DROP TABLE observations"),this.db.run("ALTER TABLE observations_new RENAME TO observations"),this.db.run(t),this.db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='observations_fts'").all().length>0&&this.db.run(r)}recreateSessionSummariesWithCascade(e,s,t,r){this.db.run(e),this.db.run(s),this.db.run("DROP TABLE session_summaries"),this.db.run("ALTER TABLE session_summaries_new RENAME TO session_summaries"),this.db.run(t),this.db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='session_summaries_fts'").all().length>0&&this.db.run(r)}addObservationContentHashColumn(){if(this.db.query("PRAGMA table_info(observations)").all().some(t=>t.name==="content_hash")){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(22,new Date().toISOString());return}this.db.run("ALTER TABLE observations ADD COLUMN content_hash TEXT"),this.db.run("UPDATE observations SET content_hash = substr(hex(randomblob(8)), 1, 16) WHERE content_hash IS NULL"),this.db.run("CREATE INDEX IF NOT EXISTS idx_observations_content_hash ON observations(content_hash, created_at_epoch)"),_.debug("DB","Added content_hash column to observations table with backfill and index"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(22,new Date().toISOString())}addSessionCustomTitleColumn(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(23))return;this.db.query("PRAGMA table_info(sdk_sessions)").all().some(r=>r.name==="custom_title")||(this.db.run("ALTER TABLE sdk_sessions ADD COLUMN custom_title TEXT"),_.debug("DB","Added custom_title column to sdk_sessions table")),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(23,new Date().toISOString())}addSessionPlatformSourceColumn(){let s=this.db.query("PRAGMA table_info(sdk_sessions)").all().some(i=>i.name==="platform_source"),r=this.db.query("PRAGMA index_list(sdk_sessions)").all().some(i=>i.name==="idx_sdk_sessions_platform_source");this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(24)&&s&&r||(s||(this.db.run(`ALTER TABLE sdk_sessions ADD COLUMN platform_source TEXT NOT NULL DEFAULT '${p}'`),_.debug("DB","Added platform_source column to sdk_sessions table")),this.db.run(`
437
437
  UPDATE sdk_sessions
438
- SET platform_source = '${c}'
438
+ SET platform_source = '${p}'
439
439
  WHERE platform_source IS NULL OR platform_source = ''
440
- `),r||this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_platform_source ON sdk_sessions(platform_source)"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(24,new Date().toISOString()))}addObservationModelColumns(){let e=this.db.query("PRAGMA table_info(observations)").all(),t=e.some(r=>r.name==="generated_by_model"),s=e.some(r=>r.name==="relevance_count");t&&s||(t||this.db.run("ALTER TABLE observations ADD COLUMN generated_by_model TEXT"),s||this.db.run("ALTER TABLE observations ADD COLUMN relevance_count INTEGER DEFAULT 0"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(26,new Date().toISOString()))}ensureMergedIntoProjectColumns(){this.db.query("PRAGMA table_info(observations)").all().some(s=>s.name==="merged_into_project")||this.db.run("ALTER TABLE observations ADD COLUMN merged_into_project TEXT"),this.db.run("CREATE INDEX IF NOT EXISTS idx_observations_merged_into ON observations(merged_into_project)"),this.db.query("PRAGMA table_info(session_summaries)").all().some(s=>s.name==="merged_into_project")||this.db.run("ALTER TABLE session_summaries ADD COLUMN merged_into_project TEXT"),this.db.run("CREATE INDEX IF NOT EXISTS idx_summaries_merged_into ON session_summaries(merged_into_project)")}addObservationSubagentColumns(){let e=this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(27),t=this.db.query("PRAGMA table_info(observations)").all(),s=t.some(i=>i.name==="agent_type"),r=t.some(i=>i.name==="agent_id");s||this.db.run("ALTER TABLE observations ADD COLUMN agent_type TEXT"),r||this.db.run("ALTER TABLE observations ADD COLUMN agent_id TEXT"),this.db.run("CREATE INDEX IF NOT EXISTS idx_observations_agent_type ON observations(agent_type)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_observations_agent_id ON observations(agent_id)");let o=this.db.query("PRAGMA table_info(pending_messages)").all();if(o.length>0){let i=o.some(d=>d.name==="agent_type"),a=o.some(d=>d.name==="agent_id");i||this.db.run("ALTER TABLE pending_messages ADD COLUMN agent_type TEXT"),a||this.db.run("ALTER TABLE pending_messages ADD COLUMN agent_id TEXT")}e||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(27,new Date().toISOString())}ensurePendingMessagesToolUseIdColumn(){if(this.db.query("SELECT name FROM sqlite_master WHERE type='table' AND name='pending_messages'").all().length===0){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(28,new Date().toISOString());return}this.db.query("PRAGMA table_info(pending_messages)").all().some(r=>r.name==="tool_use_id")||this.db.run("ALTER TABLE pending_messages ADD COLUMN tool_use_id TEXT"),this.db.run("BEGIN TRANSACTION");try{this.db.run(`
441
- DELETE FROM pending_messages
442
- WHERE id IN (
443
- SELECT id
444
- FROM (
445
- SELECT id,
446
- ROW_NUMBER() OVER (
447
- PARTITION BY session_db_id, tool_use_id
448
- ORDER BY CASE status
449
- WHEN 'processing' THEN 0
450
- WHEN 'pending' THEN 1
451
- ELSE 2
452
- END, id
453
- ) AS duplicate_rank
454
- FROM pending_messages
455
- WHERE tool_use_id IS NOT NULL
456
- )
457
- WHERE duplicate_rank > 1
440
+ `),r||this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_platform_source ON sdk_sessions(platform_source)"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(24,new Date().toISOString()))}addObservationModelColumns(){let e=this.db.query("PRAGMA table_info(observations)").all(),s=e.some(r=>r.name==="generated_by_model"),t=e.some(r=>r.name==="relevance_count");s&&t||(s||this.db.run("ALTER TABLE observations ADD COLUMN generated_by_model TEXT"),t||this.db.run("ALTER TABLE observations ADD COLUMN relevance_count INTEGER DEFAULT 0"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(26,new Date().toISOString()))}ensureMergedIntoProjectColumns(){this.db.query("PRAGMA table_info(observations)").all().some(t=>t.name==="merged_into_project")||this.db.run("ALTER TABLE observations ADD COLUMN merged_into_project TEXT"),this.db.run("CREATE INDEX IF NOT EXISTS idx_observations_merged_into ON observations(merged_into_project)"),this.db.query("PRAGMA table_info(session_summaries)").all().some(t=>t.name==="merged_into_project")||this.db.run("ALTER TABLE session_summaries ADD COLUMN merged_into_project TEXT"),this.db.run("CREATE INDEX IF NOT EXISTS idx_summaries_merged_into ON session_summaries(merged_into_project)")}addObservationSubagentColumns(){let e=this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(27),s=this.db.query("PRAGMA table_info(observations)").all(),t=s.some(i=>i.name==="agent_type"),r=s.some(i=>i.name==="agent_id");t||this.db.run("ALTER TABLE observations ADD COLUMN agent_type TEXT"),r||this.db.run("ALTER TABLE observations ADD COLUMN agent_id TEXT"),this.db.run("CREATE INDEX IF NOT EXISTS idx_observations_agent_type ON observations(agent_type)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_observations_agent_id ON observations(agent_id)");let o=this.db.query("PRAGMA table_info(pending_messages)").all();if(o.length>0){let i=o.some(d=>d.name==="agent_type"),a=o.some(d=>d.name==="agent_id");i||this.db.run("ALTER TABLE pending_messages ADD COLUMN agent_type TEXT"),a||this.db.run("ALTER TABLE pending_messages ADD COLUMN agent_id TEXT")}e||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(27,new Date().toISOString())}ensurePendingMessagesToolUseIdColumn(){if(this.db.query("SELECT name FROM sqlite_master WHERE type='table' AND name='pending_messages'").all().length===0){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(28,new Date().toISOString());return}this.db.query("PRAGMA table_info(pending_messages)").all().some(r=>r.name==="tool_use_id")||this.db.run("ALTER TABLE pending_messages ADD COLUMN tool_use_id TEXT"),this.db.run("BEGIN TRANSACTION");try{this.dedupePendingMessagesByToolUseId(),this.db.run("COMMIT")}catch(r){this.db.run("ROLLBACK");let o=r instanceof Error?r:new Error(String(r));throw _.error("DB","Failed to de-dupe pending_messages by tool_use_id, rolled back",{},o),r}}dedupePendingMessagesByToolUseId(){this.db.run(`
441
+ DELETE FROM pending_messages
442
+ WHERE id IN (
443
+ SELECT id
444
+ FROM (
445
+ SELECT id,
446
+ ROW_NUMBER() OVER (
447
+ PARTITION BY session_db_id, tool_use_id
448
+ ORDER BY CASE status
449
+ WHEN 'processing' THEN 0
450
+ WHEN 'pending' THEN 1
451
+ ELSE 2
452
+ END, id
453
+ ) AS duplicate_rank
454
+ FROM pending_messages
455
+ WHERE tool_use_id IS NOT NULL
458
456
  )
459
- `),this.db.run(`
460
- -- tool_use_id is optional for summaries and legacy rows; enforce de-dupe
461
- -- only for rows that came from a concrete tool-use event.
462
- CREATE UNIQUE INDEX IF NOT EXISTS ux_pending_session_tool
463
- ON pending_messages(session_db_id, tool_use_id)
464
- WHERE tool_use_id IS NOT NULL
465
- `),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(28,new Date().toISOString()),this.db.run("COMMIT")}catch(r){throw this.db.run("ROLLBACK"),r}}addObservationsUniqueContentHashIndex(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(29))return;let t=this.db.query("PRAGMA table_info(observations)").all(),s=t.some(o=>o.name==="memory_session_id"),r=t.some(o=>o.name==="content_hash");if(!s||!r){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(29,new Date().toISOString());return}this.db.run("BEGIN TRANSACTION");try{this.db.run(`
466
- UPDATE observations
467
- SET content_hash = '__null_migration_' || id || '__'
468
- WHERE content_hash IS NULL
469
- `),this.db.run(`
470
- DELETE FROM observations
471
- WHERE id IN (
472
- SELECT id
473
- FROM (
474
- SELECT id,
475
- ROW_NUMBER() OVER (
476
- PARTITION BY memory_session_id, content_hash
477
- ORDER BY id
478
- ) AS duplicate_rank
479
- FROM observations
480
- )
481
- WHERE duplicate_rank > 1
457
+ WHERE duplicate_rank > 1
482
458
  )
483
- `),this.db.run(`
484
- CREATE UNIQUE INDEX IF NOT EXISTS ux_observations_session_hash
485
- ON observations(memory_session_id, content_hash)
486
- `),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(29,new Date().toISOString()),this.db.run("COMMIT")}catch(o){throw this.db.run("ROLLBACK"),o}}addObservationsMetadataColumn(){this.db.query("PRAGMA table_info(observations)").all().some(s=>s.name==="metadata")||(this.db.run("ALTER TABLE observations ADD COLUMN metadata TEXT"),E.debug("DB","Added metadata column to observations table (#2116)")),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(30,new Date().toISOString())}updateMemorySessionId(e,t){this.db.prepare(`
459
+ `),this.db.run(`
460
+ -- tool_use_id is optional for summaries and legacy rows; enforce de-dupe
461
+ -- only for rows that came from a concrete tool-use event.
462
+ CREATE UNIQUE INDEX IF NOT EXISTS ux_pending_session_tool
463
+ ON pending_messages(session_db_id, tool_use_id)
464
+ WHERE tool_use_id IS NOT NULL
465
+ `),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(28,new Date().toISOString())}addObservationsUniqueContentHashIndex(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(29))return;let s=this.db.query("PRAGMA table_info(observations)").all(),t=s.some(o=>o.name==="memory_session_id"),r=s.some(o=>o.name==="content_hash");if(!t||!r){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(29,new Date().toISOString());return}this.db.run("BEGIN TRANSACTION");try{this.dedupeObservationsByContentHash(),this.db.run("COMMIT")}catch(o){this.db.run("ROLLBACK");let i=o instanceof Error?o:new Error(String(o));throw _.error("DB","Failed to de-dupe observations by content_hash, rolled back",{},i),o}}dedupeObservationsByContentHash(){this.db.run(`
466
+ UPDATE observations
467
+ SET content_hash = '__null_migration_' || id || '__'
468
+ WHERE content_hash IS NULL
469
+ `),this.db.run(`
470
+ DELETE FROM observations
471
+ WHERE id IN (
472
+ SELECT id
473
+ FROM (
474
+ SELECT id,
475
+ ROW_NUMBER() OVER (
476
+ PARTITION BY memory_session_id, content_hash
477
+ ORDER BY id
478
+ ) AS duplicate_rank
479
+ FROM observations
480
+ )
481
+ WHERE duplicate_rank > 1
482
+ )
483
+ `),this.db.run(`
484
+ CREATE UNIQUE INDEX IF NOT EXISTS ux_observations_session_hash
485
+ ON observations(memory_session_id, content_hash)
486
+ `),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(29,new Date().toISOString())}addObservationsMetadataColumn(){this.db.query("PRAGMA table_info(observations)").all().some(t=>t.name==="metadata")||(this.db.run("ALTER TABLE observations ADD COLUMN metadata TEXT"),_.debug("DB","Added metadata column to observations table (#2116)")),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(30,new Date().toISOString())}updateMemorySessionId(e,s){this.db.prepare(`
487
487
  UPDATE sdk_sessions
488
488
  SET memory_session_id = ?
489
489
  WHERE id = ?
490
- `).run(t,e)}markSessionCompleted(e){let t=Date.now(),s=new Date(t).toISOString();this.db.prepare(`
490
+ `).run(s,e)}markSessionCompleted(e){let s=Date.now(),t=new Date(s).toISOString();this.db.prepare(`
491
491
  UPDATE sdk_sessions
492
492
  SET status = 'completed', completed_at = ?, completed_at_epoch = ?
493
493
  WHERE id = ?
494
- `).run(s,t,e)}ensureMemorySessionIdRegistered(e,t,s){let r=this.db.prepare(`
494
+ `).run(t,s,e)}ensureMemorySessionIdRegistered(e,s,t){let r=this.db.prepare(`
495
495
  SELECT id, memory_session_id, worker_port FROM sdk_sessions WHERE id = ?
496
- `).get(e);if(!r)throw new Error(`Session ${e} not found in sdk_sessions`);r.memory_session_id!==t&&(this.db.prepare(`
496
+ `).get(e);if(!r)throw new Error(`Session ${e} not found in sdk_sessions`);r.memory_session_id!==s&&(this.db.prepare(`
497
497
  UPDATE sdk_sessions SET memory_session_id = ? WHERE id = ?
498
- `).run(t,e),E.info("DB","Registered memory_session_id before storage (FK fix)",{sessionDbId:e,oldId:r.memory_session_id,newId:t})),typeof s=="number"&&r.worker_port!==s&&this.db.prepare(`
498
+ `).run(s,e),_.info("DB","Registered memory_session_id before storage (FK fix)",{sessionDbId:e,oldId:r.memory_session_id,newId:s})),typeof t=="number"&&r.worker_port!==t&&this.db.prepare(`
499
499
  UPDATE sdk_sessions SET worker_port = ? WHERE id = ?
500
- `).run(s,e)}getRecentSummaries(e,t=10){return this.db.prepare(`
501
- SELECT
502
- request, investigated, learned, completed, next_steps,
503
- files_read, files_edited, notes, prompt_number, created_at
504
- FROM session_summaries
505
- WHERE project = ?
506
- ORDER BY created_at_epoch DESC
507
- LIMIT ?
508
- `).all(e,t)}getRecentSummariesWithSessionInfo(e,t=3){return this.db.prepare(`
509
- SELECT
510
- memory_session_id, request, learned, completed, next_steps,
511
- prompt_number, created_at
512
- FROM session_summaries
513
- WHERE project = ?
514
- ORDER BY created_at_epoch DESC
515
- LIMIT ?
516
- `).all(e,t)}getRecentObservations(e,t=20){return this.db.prepare(`
517
- SELECT type, text, prompt_number, created_at
518
- FROM observations
519
- WHERE project = ?
520
- ORDER BY created_at_epoch DESC
521
- LIMIT ?
522
- `).all(e,t)}getAllRecentObservations(e=100){return this.db.prepare(`
523
- SELECT
524
- o.id,
525
- o.type,
526
- o.title,
527
- o.subtitle,
528
- o.text,
529
- o.project,
530
- COALESCE(s.platform_source, '${c}') as platform_source,
531
- o.prompt_number,
532
- o.created_at,
533
- o.created_at_epoch
534
- FROM observations o
535
- LEFT JOIN sdk_sessions s ON o.memory_session_id = s.memory_session_id
536
- ORDER BY o.created_at_epoch DESC
537
- LIMIT ?
538
- `).all(e)}getAllRecentSummaries(e=50){return this.db.prepare(`
539
- SELECT
540
- ss.id,
541
- ss.request,
542
- ss.investigated,
543
- ss.learned,
544
- ss.completed,
545
- ss.next_steps,
546
- ss.files_read,
547
- ss.files_edited,
548
- ss.notes,
549
- ss.project,
550
- COALESCE(s.platform_source, '${c}') as platform_source,
551
- ss.prompt_number,
552
- ss.created_at,
553
- ss.created_at_epoch
554
- FROM session_summaries ss
555
- LEFT JOIN sdk_sessions s ON ss.memory_session_id = s.memory_session_id
556
- ORDER BY ss.created_at_epoch DESC
557
- LIMIT ?
558
- `).all(e)}getAllRecentUserPrompts(e=100){return this.db.prepare(`
559
- SELECT
560
- up.id,
561
- up.content_session_id,
562
- s.project,
563
- COALESCE(s.platform_source, '${c}') as platform_source,
564
- up.prompt_number,
565
- up.prompt_text,
566
- up.created_at,
567
- up.created_at_epoch
568
- FROM user_prompts up
569
- LEFT JOIN sdk_sessions s ON up.session_db_id = s.id
570
- ORDER BY up.created_at_epoch DESC
571
- LIMIT ?
572
- `).all(e)}getAllProjects(e){let t=e?N(e):void 0,s=`
500
+ `).run(t,e)}getAllProjects(e){let s=e?A(e):void 0,t=`
573
501
  SELECT DISTINCT project
574
502
  FROM sdk_sessions
575
503
  WHERE project IS NOT NULL AND project != ''
576
504
  AND project != ?
577
- `,r=[ie];return t&&(s+=" AND COALESCE(platform_source, ?) = ?",r.push(c,t)),s+=" ORDER BY project ASC",this.db.prepare(s).all(...r).map(i=>i.project)}getProjectCatalog(){let e=this.db.prepare(`
505
+ `,r=[te];return s&&(t+=" AND COALESCE(platform_source, ?) = ?",r.push(p,s)),t+=" ORDER BY project ASC",this.db.prepare(t).all(...r).map(i=>i.project)}getProjectCatalog(){let e=this.db.prepare(`
578
506
  SELECT
579
- COALESCE(platform_source, '${c}') as platform_source,
507
+ COALESCE(platform_source, '${p}') as platform_source,
580
508
  project,
581
509
  MAX(started_at_epoch) as latest_epoch
582
510
  FROM sdk_sessions
583
511
  WHERE project IS NOT NULL AND project != ''
584
512
  AND project != ?
585
- GROUP BY COALESCE(platform_source, '${c}'), project
513
+ GROUP BY COALESCE(platform_source, '${p}'), project
586
514
  ORDER BY latest_epoch DESC
587
- `).all(ie),t=[],s=new Set,r={};for(let i of e){let a=N(i.platform_source);r[a]||(r[a]=[]),r[a].includes(i.project)||r[a].push(i.project),s.has(i.project)||(s.add(i.project),t.push(i.project))}let o=Ce(Object.keys(r));return{projects:t,sources:o,projectsBySource:Object.fromEntries(o.map(i=>[i,r[i]||[]]))}}getLatestUserPrompt(e,t){let s=this.resolvePromptSessionDbId(e,t),r=s!==null?"up.session_db_id = ?":"up.content_session_id = ?",o=s!==null?s:e;return this.db.prepare(`
515
+ `).all(te),s=[],t=new Set,r={};for(let i of e){let a=A(i.platform_source);r[a]||(r[a]=[]),r[a].includes(i.project)||r[a].push(i.project),t.has(i.project)||(t.add(i.project),s.push(i.project))}let o=Ne(Object.keys(r));return{projects:s,sources:o,projectsBySource:Object.fromEntries(o.map(i=>[i,r[i]||[]]))}}getLatestUserPrompt(e,s){let t=this.resolvePromptSessionDbId(e,s),r=t!==null?"up.session_db_id = ?":"up.content_session_id = ?",o=t!==null?t:e;return this.db.prepare(`
588
516
  SELECT
589
517
  up.*,
590
518
  s.memory_session_id,
591
519
  s.project,
592
- COALESCE(s.platform_source, '${c}') as platform_source
520
+ COALESCE(s.platform_source, '${p}') as platform_source
593
521
  FROM user_prompts up
594
522
  JOIN sdk_sessions s ON up.session_db_id = s.id
595
523
  WHERE ${r}
596
524
  ORDER BY up.created_at_epoch DESC
597
525
  LIMIT 1
598
- `).get(o)}findRecentDuplicateUserPrompt(e,t,s,r){return Le(this.db,e,B(t),s,this.resolvePromptSessionDbId(e,r)??void 0)}getRecentSessionsWithStatus(e,t=3,s){let r=[e],o="";return s&&(o=`AND COALESCE(NULLIF(s.platform_source, ''), '${c}') = ?`,r.push(N(s))),r.push(t),this.db.prepare(`
526
+ `).get(o)}findRecentDuplicateUserPrompt(e,s,t,r){return Ie(this.db,e,B(s),t,this.resolvePromptSessionDbId(e,r)??void 0)}getRecentSessionsWithStatus(e,s=3,t){let r=[e],o="";return t&&(o=`AND COALESCE(NULLIF(s.platform_source, ''), '${p}') = ?`,r.push(A(t))),r.push(s),this.db.prepare(`
599
527
  SELECT * FROM (
600
528
  SELECT
601
529
  s.memory_session_id,
@@ -613,44 +541,44 @@ ${o.stack}`:` ${o.message}`;else if(this.getLevel()===0&&typeof o=="object")try{
613
541
  LIMIT ?
614
542
  )
615
543
  ORDER BY started_at_epoch ASC
616
- `).all(...r)}getObservationsForSession(e,t){let s=[e],r="";return t&&(r=`
544
+ `).all(...r)}getObservationsForSession(e,s){let t=[e],r="";return s&&(r=`
617
545
  AND EXISTS (
618
546
  SELECT 1
619
547
  FROM sdk_sessions s
620
548
  WHERE s.memory_session_id = observations.memory_session_id
621
- AND COALESCE(NULLIF(s.platform_source, ''), '${c}') = ?
549
+ AND COALESCE(NULLIF(s.platform_source, ''), '${p}') = ?
622
550
  )
623
- `,s.push(N(t))),this.db.prepare(`
551
+ `,t.push(A(s))),this.db.prepare(`
624
552
  SELECT title, subtitle, type, prompt_number
625
553
  FROM observations
626
554
  WHERE memory_session_id = ?
627
555
  ${r}
628
556
  ORDER BY created_at_epoch ASC
629
- `).all(...s)}getObservationById(e,t){return t?this.db.prepare(`
557
+ `).all(...t)}getObservationById(e,s){return s?this.db.prepare(`
630
558
  SELECT o.*
631
559
  FROM observations o
632
560
  LEFT JOIN sdk_sessions s ON s.memory_session_id = o.memory_session_id
633
561
  WHERE o.id = ?
634
- AND COALESCE(NULLIF(s.platform_source, ''), '${c}') = ?
635
- `).get(e,N(t))||null:this.db.prepare(`
562
+ AND COALESCE(NULLIF(s.platform_source, ''), '${p}') = ?
563
+ `).get(e,A(s))||null:this.db.prepare(`
636
564
  SELECT *
637
565
  FROM observations
638
566
  WHERE id = ?
639
- `).get(e)||null}getObservationsByIds(e,t={}){if(e.length===0)return[];let{orderBy:s="date_desc",limit:r,project:o,platformSource:i,type:a,concepts:d,files:_}=t,m=s==="relevance",l=m?"":`ORDER BY o.created_at_epoch ${s==="date_asc"?"ASC":"DESC"}`,p=r&&!m?`LIMIT ${r}`:"",g=e.map(()=>"?").join(","),A=[...e],h=[];if(o&&(h.push("o.project = ?"),A.push(o)),i&&(h.push(`COALESCE(NULLIF(s.platform_source, ''), '${c}') = ?`),A.push(N(i))),a)if(Array.isArray(a)){let I=a.map(()=>"?").join(",");h.push(`o.type IN (${I})`),A.push(...a)}else h.push("o.type = ?"),A.push(a);if(d){let I=Array.isArray(d)?d:[d],b=I.map(()=>"EXISTS (SELECT 1 FROM json_each(o.concepts) WHERE value = ?)");A.push(...I),h.push(`(${b.join(" OR ")})`)}if(_){let I=Array.isArray(_)?_:[_],b=I.map(()=>"(EXISTS (SELECT 1 FROM json_each(o.files_read) WHERE value LIKE ?) OR EXISTS (SELECT 1 FROM json_each(o.files_modified) WHERE value LIKE ?))");I.forEach(L=>{A.push(`%${L}%`,`%${L}%`)}),h.push(`(${b.join(" OR ")})`)}let f=h.length>0?`WHERE o.id IN (${g}) AND ${h.join(" AND ")}`:`WHERE o.id IN (${g})`,C=this.db.prepare(`
567
+ `).get(e)||null}getObservationsByIds(e,s={}){if(e.length===0)return[];let{orderBy:t="date_desc",limit:r,project:o,platformSource:i,type:a,concepts:d,files:u}=s,m=t==="relevance",l=m?"":`ORDER BY o.created_at_epoch ${t==="date_asc"?"ASC":"DESC"}`,c=r&&!m?`LIMIT ${r}`:"",T=e.map(()=>"?").join(","),h=[...e],b=[];if(o&&(b.push("o.project = ?"),h.push(o)),i&&(b.push(`COALESCE(NULLIF(s.platform_source, ''), '${p}') = ?`),h.push(A(i))),a)if(Array.isArray(a)){let N=a.map(()=>"?").join(",");b.push(`o.type IN (${N})`),h.push(...a)}else b.push("o.type = ?"),h.push(a);if(d){let N=Array.isArray(d)?d:[d],O=N.map(()=>"EXISTS (SELECT 1 FROM json_each(o.concepts) WHERE value = ?)");h.push(...N),b.push(`(${O.join(" OR ")})`)}if(u){let N=Array.isArray(u)?u:[u],O=N.map(()=>"(EXISTS (SELECT 1 FROM json_each(o.files_read) WHERE value LIKE ?) OR EXISTS (SELECT 1 FROM json_each(o.files_modified) WHERE value LIKE ?))");N.forEach(L=>{h.push(`%${L}%`,`%${L}%`)}),b.push(`(${O.join(" OR ")})`)}let g=b.length>0?`WHERE o.id IN (${T}) AND ${b.join(" AND ")}`:`WHERE o.id IN (${T})`,C=this.db.prepare(`
640
568
  SELECT o.*
641
569
  FROM observations o
642
570
  LEFT JOIN sdk_sessions s ON s.memory_session_id = o.memory_session_id
643
- ${f}
571
+ ${g}
644
572
  ${l}
645
- ${p}
646
- `).all(...A);if(!m)return C;let y=new Map(C.map(I=>[I.id,I])),R=e.map(I=>y.get(I)).filter(I=>!!I);return r?R.slice(0,r):R}getSummaryForSession(e,t){let s=[e],r="";return t&&(r=`
573
+ ${c}
574
+ `).all(...h);if(!m)return C;let y=new Map(C.map(N=>[N.id,N])),R=e.map(N=>y.get(N)).filter(N=>!!N);return r?R.slice(0,r):R}getSummaryForSession(e,s){let t=[e],r="";return s&&(r=`
647
575
  AND EXISTS (
648
576
  SELECT 1
649
577
  FROM sdk_sessions sdk
650
578
  WHERE sdk.memory_session_id = session_summaries.memory_session_id
651
- AND COALESCE(NULLIF(sdk.platform_source, ''), '${c}') = ?
579
+ AND COALESCE(NULLIF(sdk.platform_source, ''), '${p}') = ?
652
580
  )
653
- `,s.push(N(t))),this.db.prepare(`
581
+ `,t.push(A(s))),this.db.prepare(`
654
582
  SELECT
655
583
  request, investigated, learned, completed, next_steps,
656
584
  files_read, files_edited, notes, prompt_number, created_at,
@@ -660,258 +588,175 @@ ${o.stack}`:` ${o.message}`;else if(this.getLevel()===0&&typeof o=="object")try{
660
588
  ${r}
661
589
  ORDER BY created_at_epoch DESC
662
590
  LIMIT 1
663
- `).get(...s)||null}getFilesForSession(e){let s=this.db.prepare(`
664
- SELECT files_read, files_modified
665
- FROM observations
666
- WHERE memory_session_id = ?
667
- `).all(e),r=new Set,o=new Set;for(let i of s)de(i.files_read).forEach(a=>r.add(a)),de(i.files_modified).forEach(a=>o.add(a));return{filesRead:Array.from(r),filesModified:Array.from(o)}}getSessionById(e){return this.db.prepare(`
591
+ `).get(...t)||null}getSessionById(e){return this.db.prepare(`
668
592
  SELECT id, content_session_id, memory_session_id, project,
669
- COALESCE(platform_source, '${c}') as platform_source,
593
+ COALESCE(platform_source, '${p}') as platform_source,
670
594
  user_prompt, custom_title, status
671
595
  FROM sdk_sessions
672
596
  WHERE id = ?
673
597
  LIMIT 1
674
- `).get(e)||null}getSdkSessionsBySessionIds(e){if(e.length===0)return[];let t=e.map(()=>"?").join(",");return this.db.prepare(`
598
+ `).get(e)||null}getSdkSessionsBySessionIds(e){if(e.length===0)return[];let s=e.map(()=>"?").join(",");return this.db.prepare(`
675
599
  SELECT id, content_session_id, memory_session_id, project,
676
- COALESCE(platform_source, '${c}') as platform_source,
600
+ COALESCE(platform_source, '${p}') as platform_source,
677
601
  user_prompt, custom_title,
678
602
  started_at, started_at_epoch, completed_at, completed_at_epoch, status
679
603
  FROM sdk_sessions
680
- WHERE memory_session_id IN (${t})
604
+ WHERE memory_session_id IN (${s})
681
605
  ORDER BY started_at_epoch DESC
682
- `).all(...e)}getPromptNumberFromUserPrompts(e,t){let s=this.resolvePromptSessionDbId(e,t);return s!==null?this.db.prepare(`
606
+ `).all(...e)}getPromptNumberFromUserPrompts(e,s){let t=this.resolvePromptSessionDbId(e,s);return t!==null?this.db.prepare(`
683
607
  SELECT COUNT(*) as count FROM user_prompts WHERE session_db_id = ?
684
- `).get(s).count:this.db.prepare(`
608
+ `).get(t).count:this.db.prepare(`
685
609
  SELECT COUNT(*) as count FROM user_prompts WHERE content_session_id = ?
686
- `).get(e).count}createSDKSession(e,t,s,r,o){let i=new Date,a=i.getTime(),d=as(r,o),_=d.platformSource??c,m=B(s),l=this.db.prepare(`
610
+ `).get(e).count}createSDKSession(e,s,t,r,o){let i=new Date,a=i.getTime(),d=o?A(o):p,u=B(t),m=this.db.prepare(`
687
611
  SELECT id, platform_source
688
612
  FROM sdk_sessions
689
613
  WHERE COALESCE(NULLIF(platform_source, ''), ?) = ?
690
614
  AND content_session_id = ?
691
- `).get(c,_,e);if(l)return t&&this.db.prepare(`
615
+ `).get(p,d,e);if(m)return s&&this.db.prepare(`
692
616
  UPDATE sdk_sessions SET project = ?
693
617
  WHERE id = ? AND (project IS NULL OR project = '')
694
- `).run(t,l.id),d.customTitle&&this.db.prepare(`
618
+ `).run(s,m.id),r&&this.db.prepare(`
695
619
  UPDATE sdk_sessions SET custom_title = ?
696
620
  WHERE id = ? AND custom_title IS NULL
697
- `).run(d.customTitle,l.id),l.id;let p=this.db.prepare(`
621
+ `).run(r,m.id),m.id;let l=this.db.prepare(`
698
622
  INSERT INTO sdk_sessions
699
623
  (content_session_id, memory_session_id, project, platform_source, user_prompt, custom_title, started_at, started_at_epoch, status)
700
624
  VALUES (?, NULL, ?, ?, ?, ?, ?, ?, 'active')
701
- `).run(e,t,_,m,d.customTitle||null,i.toISOString(),a);return Number(p.lastInsertRowid)}saveUserPrompt(e,t,s,r){let o=new Date,i=o.getTime(),a=B(s),d=this.resolvePromptSessionDbId(e,r);return this.db.prepare(`
625
+ `).run(e,s,d,u,r||null,i.toISOString(),a);return Number(l.lastInsertRowid)}saveUserPrompt(e,s,t,r){let o=new Date,i=o.getTime(),a=B(t),d=this.resolvePromptSessionDbId(e,r);return this.db.prepare(`
702
626
  INSERT INTO user_prompts
703
627
  (session_db_id, content_session_id, prompt_number, prompt_text, created_at, created_at_epoch)
704
628
  VALUES (?, ?, ?, ?, ?, ?)
705
- `).run(d,e,t,a,o.toISOString(),i).lastInsertRowid}getUserPrompt(e,t,s){let r=this.resolvePromptSessionDbId(e,s);return r!==null?this.db.prepare(`
629
+ `).run(d,e,s,a,o.toISOString(),i).lastInsertRowid}getUserPrompt(e,s,t){let r=this.resolvePromptSessionDbId(e,t);return r!==null?this.db.prepare(`
706
630
  SELECT prompt_text
707
631
  FROM user_prompts
708
632
  WHERE session_db_id = ? AND prompt_number = ?
709
633
  LIMIT 1
710
- `).get(r,t)?.prompt_text??null:this.db.prepare(`
634
+ `).get(r,s)?.prompt_text??null:this.db.prepare(`
711
635
  SELECT prompt_text
712
636
  FROM user_prompts
713
637
  WHERE content_session_id = ? AND prompt_number = ?
714
638
  LIMIT 1
715
- `).get(e,t)?.prompt_text??null}storeObservation(e,t,s,r,o=0,i,a){let d=i??Date.now(),_=new Date(d).toISOString(),m=ae(e,s.title,s.narrative),p=this.db.prepare(`
716
- INSERT INTO observations
717
- (memory_session_id, project, type, title, subtitle, facts, narrative, concepts,
718
- files_read, files_modified, prompt_number, discovery_tokens, agent_type, agent_id, content_hash, created_at, created_at_epoch,
719
- generated_by_model, metadata)
720
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
721
- ON CONFLICT(memory_session_id, content_hash) DO NOTHING
722
- RETURNING id, created_at_epoch
723
- `).get(e,t,s.type,s.title,s.subtitle,JSON.stringify(s.facts),s.narrative,JSON.stringify(s.concepts),JSON.stringify(s.files_read),JSON.stringify(s.files_modified),r||null,o,s.agent_type??null,s.agent_id??null,m,_,d,a||null,s.metadata??null);if(p)return{id:p.id,createdAtEpoch:p.created_at_epoch};let g=this.db.prepare("SELECT id, created_at_epoch FROM observations WHERE memory_session_id = ? AND content_hash = ?").get(e,m);if(!g)throw new Error(`storeObservation: ON CONFLICT without existing row for content_hash=${m}`);return{id:g.id,createdAtEpoch:g.created_at_epoch}}storeSummary(e,t,s,r,o=0,i){let a=i??Date.now(),d=new Date(a).toISOString(),m=this.db.prepare(`
639
+ `).get(e,s)?.prompt_text??null}storeObservation(e,s,t,r,o=0,i,a){let d=this.storeObservations(e,s,[t],null,r,o,i,a);return{id:d.observationIds[0],createdAtEpoch:d.createdAtEpoch}}storeSummary(e,s,t,r,o=0,i){let a=i??Date.now(),d=new Date(a).toISOString(),m=this.db.prepare(`
724
640
  INSERT INTO session_summaries
725
641
  (memory_session_id, project, request, investigated, learned, completed,
726
642
  next_steps, notes, prompt_number, discovery_tokens, created_at, created_at_epoch)
727
643
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
728
- `).run(e,t,s.request,s.investigated,s.learned,s.completed,s.next_steps,s.notes,r||null,o,d,a);return{id:Number(m.lastInsertRowid),createdAtEpoch:a}}storeObservations(e,t,s,r,o,i=0,a,d){let _=a??Date.now(),m=new Date(_).toISOString();return this.db.transaction(()=>{let p=[],g=this.db.prepare(`
644
+ `).run(e,s,t.request,t.investigated,t.learned,t.completed,t.next_steps,t.notes,r||null,o,d,a);return{id:Number(m.lastInsertRowid),createdAtEpoch:a}}storeObservations(e,s,t,r,o,i=0,a,d){let u=a??Date.now(),m=new Date(u).toISOString();return this.db.transaction(()=>{let c=[],T=this.db.prepare(`
729
645
  INSERT INTO observations
730
646
  (memory_session_id, project, type, title, subtitle, facts, narrative, concepts,
731
647
  files_read, files_modified, prompt_number, discovery_tokens, agent_type, agent_id, content_hash, created_at, created_at_epoch,
732
- generated_by_model)
733
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
648
+ generated_by_model, metadata)
649
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
734
650
  ON CONFLICT(memory_session_id, content_hash) DO NOTHING
735
651
  RETURNING id
736
- `),A=this.db.prepare("SELECT id FROM observations WHERE memory_session_id = ? AND content_hash = ?");for(let f of s){let S=ae(e,f.title,f.narrative),C=g.get(e,t,f.type,f.title,f.subtitle,JSON.stringify(f.facts),f.narrative,JSON.stringify(f.concepts),JSON.stringify(f.files_read),JSON.stringify(f.files_modified),o||null,i,f.agent_type??null,f.agent_id??null,S,m,_,d||null);if(C){p.push(C.id);continue}let y=A.get(e,S);if(!y)throw new Error(`storeObservations: ON CONFLICT without existing row for content_hash=${S}`);p.push(y.id)}let h=null;if(r){let S=this.db.prepare(`
652
+ `),h=this.db.prepare("SELECT id FROM observations WHERE memory_session_id = ? AND content_hash = ?");for(let g of t){let S=he(e,g.title,g.narrative),C=T.get(e,s,g.type,g.title,g.subtitle,JSON.stringify(g.facts),g.narrative,JSON.stringify(g.concepts),JSON.stringify(g.files_read),JSON.stringify(g.files_modified),o||null,i,g.agent_type??null,g.agent_id??null,S,m,u,d||null,g.metadata??null);if(C){c.push(C.id);continue}let y=h.get(e,S);if(!y)throw new Error(`storeObservations: ON CONFLICT without existing row for content_hash=${S}`);c.push(y.id)}let b=null;if(r){let S=this.db.prepare(`
737
653
  INSERT INTO session_summaries
738
654
  (memory_session_id, project, request, investigated, learned, completed,
739
655
  next_steps, notes, prompt_number, discovery_tokens, created_at, created_at_epoch)
740
656
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
741
- `).run(e,t,r.request,r.investigated,r.learned,r.completed,r.next_steps,r.notes,o||null,i,m,_);h=Number(S.lastInsertRowid)}return{observationIds:p,summaryId:h,createdAtEpoch:_}})()}getSessionSummariesByIds(e,t={}){if(e.length===0)return[];let{orderBy:s="date_desc",limit:r,project:o,platformSource:i}=t,a=s==="relevance",d=a?"":`ORDER BY ss.created_at_epoch ${s==="date_asc"?"ASC":"DESC"}`,_=r&&!a?`LIMIT ${r}`:"",m=e.map(()=>"?").join(","),l=[...e],p=[];o&&(p.push("ss.project = ?"),l.push(o)),i&&(p.push(`COALESCE(NULLIF(s.platform_source, ''), '${c}') = ?`),l.push(N(i)));let g=p.length>0?`AND ${p.join(" AND ")}`:"",h=this.db.prepare(`
657
+ `).run(e,s,r.request,r.investigated,r.learned,r.completed,r.next_steps,r.notes,o||null,i,m,u);b=Number(S.lastInsertRowid)}return{observationIds:c,summaryId:b,createdAtEpoch:u}})()}getSessionSummariesByIds(e,s={}){if(e.length===0)return[];let{orderBy:t="date_desc",limit:r,project:o,platformSource:i}=s,a=t==="relevance",d=a?"":`ORDER BY ss.created_at_epoch ${t==="date_asc"?"ASC":"DESC"}`,u=r&&!a?`LIMIT ${r}`:"",m=e.map(()=>"?").join(","),l=[...e],c=[];o&&(c.push("ss.project = ?"),l.push(o)),i&&(c.push(`COALESCE(NULLIF(s.platform_source, ''), '${p}') = ?`),l.push(A(i)));let T=c.length>0?`AND ${c.join(" AND ")}`:"",b=this.db.prepare(`
742
658
  SELECT ss.*
743
659
  FROM session_summaries ss
744
660
  LEFT JOIN sdk_sessions s ON s.memory_session_id = ss.memory_session_id
745
- WHERE ss.id IN (${m}) ${g}
661
+ WHERE ss.id IN (${m}) ${T}
746
662
  ${d}
747
- ${_}
748
- `).all(...l);if(!a)return h;let f=new Map(h.map(C=>[C.id,C])),S=e.map(C=>f.get(C)).filter(C=>!!C);return r?S.slice(0,r):S}getUserPromptsByIds(e,t={}){if(e.length===0)return[];let{orderBy:s="date_desc",limit:r,project:o,platformSource:i}=t,a=s==="relevance",d=a?"":`ORDER BY up.created_at_epoch ${s==="date_asc"?"ASC":"DESC"}`,_=r?`LIMIT ${r}`:"",m=e.map(()=>"?").join(","),l=[...e],p=[];o&&(p.push("s.project = ?"),l.push(o)),i&&(p.push(`COALESCE(NULLIF(s.platform_source, ''), '${c}') = ?`),l.push(N(i)));let g=p.length>0?`AND ${p.join(" AND ")}`:"",h=this.db.prepare(`
663
+ ${u}
664
+ `).all(...l);if(!a)return b;let g=new Map(b.map(C=>[C.id,C])),S=e.map(C=>g.get(C)).filter(C=>!!C);return r?S.slice(0,r):S}getUserPromptsByIds(e,s={}){if(e.length===0)return[];let{orderBy:t="date_desc",limit:r,project:o,platformSource:i}=s,a=t==="relevance",d=a?"":`ORDER BY up.created_at_epoch ${t==="date_asc"?"ASC":"DESC"}`,u=r?`LIMIT ${r}`:"",m=e.map(()=>"?").join(","),l=[...e],c=[];o&&(c.push("s.project = ?"),l.push(o)),i&&(c.push(`COALESCE(NULLIF(s.platform_source, ''), '${p}') = ?`),l.push(A(i)));let T=c.length>0?`AND ${c.join(" AND ")}`:"",b=this.db.prepare(`
749
665
  SELECT
750
666
  up.*,
751
667
  s.project,
752
668
  s.memory_session_id,
753
- COALESCE(NULLIF(s.platform_source, ''), '${c}') as platform_source
669
+ COALESCE(NULLIF(s.platform_source, ''), '${p}') as platform_source
754
670
  FROM user_prompts up
755
671
  JOIN sdk_sessions s ON up.session_db_id = s.id
756
- WHERE up.id IN (${m}) ${g}
672
+ WHERE up.id IN (${m}) ${T}
757
673
  ${d}
758
- ${_}
759
- `).all(...l);if(!a)return h;let f=new Map(h.map(S=>[S.id,S]));return e.map(S=>f.get(S)).filter(S=>!!S)}getTimelineAroundTimestamp(e,t=10,s=10,r,o){return this.getTimelineAroundObservation(null,e,t,s,r,o)}getTimelineAroundObservation(e,t,s=10,r=10,o,i){let a=i?N(i):void 0,d=(R,I)=>{let b=[],L=[];return o&&(b.push(`${R}.project = ?`),L.push(o)),a&&(b.push(`COALESCE(NULLIF(${I}.platform_source, ''), '${c}') = ?`),L.push(a)),{clause:b.length>0?`AND ${b.join(" AND ")}`:"",params:L}},_=d("o","src"),m=d("ss","src"),l=d("s","s"),p,g;if(e!==null){let R=`
674
+ ${u}
675
+ `).all(...l);if(!a)return b;let g=new Map(b.map(S=>[S.id,S]));return e.map(S=>g.get(S)).filter(S=>!!S)}getTimelineAroundTimestamp(e,s=10,t=10,r,o){return this.getTimelineAroundObservation(null,e,s,t,r,o)}getTimelineAroundObservation(e,s,t=10,r=10,o,i){let a=i?A(i):void 0,d=(R,N)=>{let O=[],L=[];return o&&(O.push(`${R}.project = ?`),L.push(o)),a&&(O.push(`COALESCE(NULLIF(${N}.platform_source, ''), '${p}') = ?`),L.push(a)),{clause:O.length>0?`AND ${O.join(" AND ")}`:"",params:L}},u=d("o","src"),m=d("ss","src"),l=d("s","s"),c,T;if(e!==null){let R=`
760
676
  SELECT o.id, o.created_at_epoch
761
677
  FROM observations o
762
678
  LEFT JOIN sdk_sessions src ON src.memory_session_id = o.memory_session_id
763
- WHERE o.id <= ? ${_.clause}
679
+ WHERE o.id <= ? ${u.clause}
764
680
  ORDER BY o.id DESC
765
681
  LIMIT ?
766
- `,I=`
682
+ `,N=`
767
683
  SELECT o.id, o.created_at_epoch
768
684
  FROM observations o
769
685
  LEFT JOIN sdk_sessions src ON src.memory_session_id = o.memory_session_id
770
- WHERE o.id >= ? ${_.clause}
686
+ WHERE o.id >= ? ${u.clause}
771
687
  ORDER BY o.id ASC
772
688
  LIMIT ?
773
- `;try{let b=this.db.prepare(R).all(e,..._.params,s+1),L=this.db.prepare(I).all(e,..._.params,r+1);if(b.length===0&&L.length===0)return{observations:[],sessions:[],prompts:[]};p=b.length>0?b[b.length-1].created_at_epoch:t,g=L.length>0?L[L.length-1].created_at_epoch:t}catch(b){return b instanceof Error?E.error("DB","Error getting boundary observations",{project:o},b):E.error("DB","Error getting boundary observations with non-Error",{},new Error(String(b))),{observations:[],sessions:[],prompts:[]}}}else{let R=`
689
+ `;try{let O=this.db.prepare(R).all(e,...u.params,t+1),L=this.db.prepare(N).all(e,...u.params,r+1);if(O.length===0&&L.length===0)return{observations:[],sessions:[],prompts:[]};c=O.length>0?O[O.length-1].created_at_epoch:s,T=L.length>0?L[L.length-1].created_at_epoch:s}catch(O){return O instanceof Error?_.error("DB","Error getting boundary observations",{project:o},O):_.error("DB","Error getting boundary observations with non-Error",{},new Error(String(O))),{observations:[],sessions:[],prompts:[]}}}else{let R=`
774
690
  SELECT o.created_at_epoch
775
691
  FROM observations o
776
692
  LEFT JOIN sdk_sessions src ON src.memory_session_id = o.memory_session_id
777
- WHERE o.created_at_epoch <= ? ${_.clause}
693
+ WHERE o.created_at_epoch <= ? ${u.clause}
778
694
  ORDER BY o.created_at_epoch DESC
779
695
  LIMIT ?
780
- `,I=`
696
+ `,N=`
781
697
  SELECT o.created_at_epoch
782
698
  FROM observations o
783
699
  LEFT JOIN sdk_sessions src ON src.memory_session_id = o.memory_session_id
784
- WHERE o.created_at_epoch >= ? ${_.clause}
700
+ WHERE o.created_at_epoch >= ? ${u.clause}
785
701
  ORDER BY o.created_at_epoch ASC
786
702
  LIMIT ?
787
- `;try{let b=this.db.prepare(R).all(t,..._.params,s),L=this.db.prepare(I).all(t,..._.params,r+1);if(b.length===0&&L.length===0)return{observations:[],sessions:[],prompts:[]};p=b.length>0?b[b.length-1].created_at_epoch:t,g=L.length>0?L[L.length-1].created_at_epoch:t}catch(b){return b instanceof Error?E.error("DB","Error getting boundary timestamps",{project:o},b):E.error("DB","Error getting boundary timestamps with non-Error",{},new Error(String(b))),{observations:[],sessions:[],prompts:[]}}}let A=`
703
+ `;try{let O=this.db.prepare(R).all(s,...u.params,t),L=this.db.prepare(N).all(s,...u.params,r+1);if(O.length===0&&L.length===0)return{observations:[],sessions:[],prompts:[]};c=O.length>0?O[O.length-1].created_at_epoch:s,T=L.length>0?L[L.length-1].created_at_epoch:s}catch(O){return O instanceof Error?_.error("DB","Error getting boundary timestamps",{project:o},O):_.error("DB","Error getting boundary timestamps with non-Error",{},new Error(String(O))),{observations:[],sessions:[],prompts:[]}}}let h=`
788
704
  SELECT o.*
789
705
  FROM observations o
790
706
  LEFT JOIN sdk_sessions src ON src.memory_session_id = o.memory_session_id
791
- WHERE o.created_at_epoch >= ? AND o.created_at_epoch <= ? ${_.clause}
707
+ WHERE o.created_at_epoch >= ? AND o.created_at_epoch <= ? ${u.clause}
792
708
  ORDER BY o.created_at_epoch ASC
793
- `,h=`
709
+ `,b=`
794
710
  SELECT ss.*
795
711
  FROM session_summaries ss
796
712
  LEFT JOIN sdk_sessions src ON src.memory_session_id = ss.memory_session_id
797
713
  WHERE ss.created_at_epoch >= ? AND ss.created_at_epoch <= ? ${m.clause}
798
714
  ORDER BY ss.created_at_epoch ASC
799
- `,f=`
800
- SELECT up.*, s.project, s.memory_session_id, COALESCE(NULLIF(s.platform_source, ''), '${c}') as platform_source
715
+ `,g=`
716
+ SELECT up.*, s.project, s.memory_session_id, COALESCE(NULLIF(s.platform_source, ''), '${p}') as platform_source
801
717
  FROM user_prompts up
802
718
  JOIN sdk_sessions s ON up.session_db_id = s.id
803
719
  WHERE up.created_at_epoch >= ? AND up.created_at_epoch <= ? ${l.clause}
804
720
  ORDER BY up.created_at_epoch ASC
805
- `,S=this.db.prepare(A).all(p,g,..._.params),C=this.db.prepare(h).all(p,g,...m.params),y=this.db.prepare(f).all(p,g,...l.params);return{observations:S,sessions:C.map(R=>({id:R.id,memory_session_id:R.memory_session_id,project:R.project,request:R.request,completed:R.completed,next_steps:R.next_steps,created_at:R.created_at,created_at_epoch:R.created_at_epoch})),prompts:y.map(R=>({id:R.id,content_session_id:R.content_session_id,prompt_number:R.prompt_number,prompt_text:R.prompt_text,project:R.project,platform_source:R.platform_source,created_at:R.created_at,created_at_epoch:R.created_at_epoch}))}}getPromptById(e){return this.db.prepare(`
806
- SELECT
807
- p.id,
808
- p.content_session_id,
809
- p.prompt_number,
810
- p.prompt_text,
811
- s.project,
812
- p.created_at,
813
- p.created_at_epoch
814
- FROM user_prompts p
815
- LEFT JOIN sdk_sessions s ON p.session_db_id = s.id
816
- WHERE p.id = ?
817
- LIMIT 1
818
- `).get(e)||null}getPromptsByIds(e){if(e.length===0)return[];let t=e.map(()=>"?").join(",");return this.db.prepare(`
819
- SELECT
820
- p.id,
821
- p.content_session_id,
822
- p.prompt_number,
823
- p.prompt_text,
824
- s.project,
825
- p.created_at,
826
- p.created_at_epoch
827
- FROM user_prompts p
828
- LEFT JOIN sdk_sessions s ON p.session_db_id = s.id
829
- WHERE p.id IN (${t})
830
- ORDER BY p.created_at_epoch DESC
831
- `).all(...e)}getOrCreateManualSession(e){let t=`manual-${e}`,s=`manual-content-${e}`;if(this.db.prepare("SELECT memory_session_id FROM sdk_sessions WHERE memory_session_id = ?").get(t))return t;let o=new Date;return this.db.prepare(`
721
+ `,S=this.db.prepare(h).all(c,T,...u.params),C=this.db.prepare(b).all(c,T,...m.params),y=this.db.prepare(g).all(c,T,...l.params);return{observations:S,sessions:C.map(R=>({id:R.id,memory_session_id:R.memory_session_id,project:R.project,request:R.request,completed:R.completed,next_steps:R.next_steps,created_at:R.created_at,created_at_epoch:R.created_at_epoch})),prompts:y.map(R=>({id:R.id,content_session_id:R.content_session_id,prompt_number:R.prompt_number,prompt_text:R.prompt_text,project:R.project,platform_source:R.platform_source,created_at:R.created_at,created_at_epoch:R.created_at_epoch}))}}getOrCreateManualSession(e){let s=`manual-${e}`,t=`manual-content-${e}`;if(this.db.prepare("SELECT memory_session_id FROM sdk_sessions WHERE memory_session_id = ?").get(s))return s;let o=new Date;return this.db.prepare(`
832
722
  INSERT INTO sdk_sessions (memory_session_id, content_session_id, project, platform_source, started_at, started_at_epoch, status)
833
723
  VALUES (?, ?, ?, ?, ?, ?, 'active')
834
- `).run(t,s,e,c,o.toISOString(),o.getTime()),E.info("SESSION","Created manual session",{memorySessionId:t,project:e}),t}close(){this.db.close()}importSdkSession(e){let t=N(e.platform_source),s=this.db.prepare(`SELECT id FROM sdk_sessions
835
- WHERE platform_source = ? AND content_session_id = ?`).get(t,e.content_session_id);return s?{imported:!1,id:s.id}:{imported:!0,id:this.db.prepare(`
724
+ `).run(s,t,e,p,o.toISOString(),o.getTime()),_.info("SESSION","Created manual session",{memorySessionId:s,project:e}),s}close(){this.db.close()}importSdkSession(e){let s=A(e.platform_source),t=this.db.prepare(`SELECT id FROM sdk_sessions
725
+ WHERE platform_source = ? AND content_session_id = ?`).get(s,e.content_session_id);return t?{imported:!1,id:t.id}:{imported:!0,id:this.db.prepare(`
836
726
  INSERT INTO sdk_sessions (
837
727
  content_session_id, memory_session_id, project, platform_source, user_prompt,
838
728
  started_at, started_at_epoch, completed_at, completed_at_epoch, status
839
729
  ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
840
- `).run(e.content_session_id,e.memory_session_id,e.project,t,e.user_prompt,e.started_at,e.started_at_epoch,e.completed_at,e.completed_at_epoch,e.status).lastInsertRowid}}importSessionSummary(e){let t=this.db.prepare("SELECT id FROM session_summaries WHERE memory_session_id = ?").get(e.memory_session_id);return t?{imported:!1,id:t.id}:{imported:!0,id:this.db.prepare(`
730
+ `).run(e.content_session_id,e.memory_session_id,e.project,s,e.user_prompt,e.started_at,e.started_at_epoch,e.completed_at,e.completed_at_epoch,e.status).lastInsertRowid}}importSessionSummary(e){let s=this.db.prepare("SELECT id FROM session_summaries WHERE memory_session_id = ?").get(e.memory_session_id);return s?{imported:!1,id:s.id}:{imported:!0,id:this.db.prepare(`
841
731
  INSERT INTO session_summaries (
842
732
  memory_session_id, project, request, investigated, learned,
843
733
  completed, next_steps, files_read, files_edited, notes,
844
734
  prompt_number, discovery_tokens, created_at, created_at_epoch
845
735
  ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
846
- `).run(e.memory_session_id,e.project,e.request,e.investigated,e.learned,e.completed,e.next_steps,e.files_read,e.files_edited,e.notes,e.prompt_number,e.discovery_tokens||0,e.created_at,e.created_at_epoch).lastInsertRowid}}importObservation(e){let t=this.db.prepare(`
736
+ `).run(e.memory_session_id,e.project,e.request,e.investigated,e.learned,e.completed,e.next_steps,e.files_read,e.files_edited,e.notes,e.prompt_number,e.discovery_tokens||0,e.created_at,e.created_at_epoch).lastInsertRowid}}importObservation(e){let s=this.db.prepare(`
847
737
  SELECT id FROM observations
848
738
  WHERE memory_session_id = ? AND title = ? AND created_at_epoch = ?
849
- `).get(e.memory_session_id,e.title,e.created_at_epoch);return t?{imported:!1,id:t.id}:{imported:!0,id:this.db.prepare(`
739
+ `).get(e.memory_session_id,e.title,e.created_at_epoch);return s?{imported:!1,id:s.id}:{imported:!0,id:this.db.prepare(`
850
740
  INSERT INTO observations (
851
741
  memory_session_id, project, text, type, title, subtitle,
852
742
  facts, narrative, concepts, files_read, files_modified,
853
743
  prompt_number, discovery_tokens, agent_type, agent_id,
854
744
  created_at, created_at_epoch
855
745
  ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
856
- `).run(e.memory_session_id,e.project,e.text,e.type,e.title,e.subtitle,e.facts,e.narrative,e.concepts,e.files_read,e.files_modified,e.prompt_number,e.discovery_tokens||0,e.agent_type??null,e.agent_id??null,e.created_at,e.created_at_epoch).lastInsertRowid}}rebuildObservationsFTSIndex(){this.db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='observations_fts'").all().length>0&&this.db.run("INSERT INTO observations_fts(observations_fts) VALUES('rebuild')")}importUserPrompt(e){let t=null,s=e.platform_source?N(e.platform_source):void 0;if(typeof e.session_db_id=="number"){let a=this.db.prepare(`
857
- SELECT id, content_session_id, COALESCE(NULLIF(platform_source, ''), '${c}') as platform_source
746
+ `).run(e.memory_session_id,e.project,e.text,e.type,e.title,e.subtitle,e.facts,e.narrative,e.concepts,e.files_read,e.files_modified,e.prompt_number,e.discovery_tokens||0,e.agent_type??null,e.agent_id??null,e.created_at,e.created_at_epoch).lastInsertRowid}}rebuildObservationsFTSIndex(){this.db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='observations_fts'").all().length>0&&this.db.run("INSERT INTO observations_fts(observations_fts) VALUES('rebuild')")}importUserPrompt(e){let s=null,t=e.platform_source?A(e.platform_source):void 0;if(typeof e.session_db_id=="number"){let a=this.db.prepare(`
747
+ SELECT id, content_session_id, COALESCE(NULLIF(platform_source, ''), '${p}') as platform_source
858
748
  FROM sdk_sessions
859
749
  WHERE id = ?
860
750
  LIMIT 1
861
- `).get(e.session_db_id);a&&a.content_session_id===e.content_session_id&&(!s||N(a.platform_source)===s)&&(t=a.id)}t===null&&(t=this.resolvePromptSessionDbId(e.content_session_id,void 0,s));let r=this.db.prepare(`
751
+ `).get(e.session_db_id);a&&a.content_session_id===e.content_session_id&&(!t||A(a.platform_source)===t)&&(s=a.id)}s===null&&(s=this.resolvePromptSessionDbId(e.content_session_id,void 0,t));let r=this.db.prepare(`
862
752
  SELECT id FROM user_prompts
863
- WHERE ${t!==null?"session_db_id = ?":"content_session_id = ?"} AND prompt_number = ?
864
- `).get(t??e.content_session_id,e.prompt_number);return r?{imported:!1,id:r.id}:{imported:!0,id:this.db.prepare(`
753
+ WHERE ${s!==null?"session_db_id = ?":"content_session_id = ?"} AND prompt_number = ?
754
+ `).get(s??e.content_session_id,e.prompt_number);return r?{imported:!1,id:r.id}:{imported:!0,id:this.db.prepare(`
865
755
  INSERT INTO user_prompts (
866
756
  session_db_id, content_session_id, prompt_number, prompt_text,
867
757
  created_at, created_at_epoch
868
758
  ) VALUES (?, ?, ?, ?, ?, ?)
869
- `).run(t,e.content_session_id,e.prompt_number,e.prompt_text,e.created_at,e.created_at_epoch).lastInsertRowid}}};var ke=require("os"),Fe=k(require("path"),1),we=require("child_process");var Y=require("fs"),V=k(require("path"),1);var w={isWorktree:!1,worktreeName:null,parentRepoPath:null,parentProjectName:null};function xe(n){let e=V.default.join(n,".git"),t;try{t=(0,Y.statSync)(e)}catch(m){return m instanceof Error&&m.code!=="ENOENT"&&E.warn("GIT","Unexpected error checking .git",{error:m instanceof Error?m.message:String(m)}),w}if(!t.isFile())return w;let s;try{s=(0,Y.readFileSync)(e,"utf-8").trim()}catch(m){return E.warn("GIT","Failed to read .git file",{error:m instanceof Error?m.message:String(m)}),w}let r=s.match(/^gitdir:\s*(.+)$/);if(!r)return w;let i=r[1].match(/^(.+)[/\\]\.git[/\\]worktrees[/\\]([^/\\]+)$/);if(!i)return w;let a=i[1],d=V.default.basename(n),_=V.default.basename(a);return{isWorktree:!0,worktreeName:d,parentRepoPath:a,parentProjectName:_}}function Pe(n){return n==="~"||n.startsWith("~/")?n.replace(/^~/,(0,ke.homedir)()):n}function ds(n){try{return(0,we.execFileSync)("git",["rev-parse","--show-toplevel"],{cwd:n,encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim()||null}catch{return null}}function _s(n){if(!n||n.trim()==="")return E.warn("PROJECT_NAME","Empty cwd provided, using fallback",{cwd:n}),"unknown-project";let e=Pe(n),s=ds(e)??e,r=Fe.default.basename(s);if(r===""){if(process.platform==="win32"){let i=n.match(/^([A-Z]):\\/i);if(i){let d=`drive-${i[1].toUpperCase()}`;return E.info("PROJECT_NAME","Drive root detected",{cwd:n,projectName:d}),d}}return E.warn("PROJECT_NAME","Root directory detected, using fallback",{cwd:n}),"unknown-project"}return r}function $e(n){let e=_s(n);if(!n)return{primary:e,parent:null,isWorktree:!1,allProjects:[e]};let t=Pe(n),s=xe(t);if(s.isWorktree&&s.parentProjectName){let r=`${s.parentProjectName}/${e}`;return{primary:r,parent:s.parentProjectName,isWorktree:!0,allProjects:[s.parentProjectName,r]}}return{primary:e,parent:null,isWorktree:!1,allProjects:[e]}}var M=require("fs"),P=require("path"),me=require("os");var Ee={DEFAULT:3e5,HEALTH_CHECK:3e3,API_REQUEST:3e4,HOOK_READINESS_WAIT:1e4,POST_SPAWN_WAIT:15e3,READINESS_WAIT:3e4,PORT_IN_USE_WAIT:3e3,WORKER_STARTUP_WAIT:1e3,PRE_RESTART_SETTLE_DELAY:2e3,POWERSHELL_COMMAND:1e4,WINDOWS_MULTIPLIER:1.5};function He(n){return process.platform==="win32"?Math.round(n*Ee.WINDOWS_MULTIPLIER):n}var q=class{static DEFAULTS={CLAUDE_MEM_MODEL:"claude-haiku-4-5-20251001",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_WORKER_PORT:String(37700+(process.getuid?.()??77)%100),CLAUDE_MEM_WORKER_HOST:"127.0.0.1",CLAUDE_MEM_API_TIMEOUT_MS:String(He(Ee.API_REQUEST)),CLAUDE_MEM_SKIP_TOOLS:"ListMcpResourcesTool,SlashCommand,Skill,TodoWrite,AskUserQuestion",CLAUDE_MEM_PROVIDER:"claude",CLAUDE_MEM_CLAUDE_AUTH_METHOD:"subscription",CLAUDE_MEM_GEMINI_API_KEY:"",CLAUDE_MEM_GEMINI_MODEL:"gemini-2.5-flash-lite",CLAUDE_MEM_GEMINI_RATE_LIMITING_ENABLED:"true",CLAUDE_MEM_OPENROUTER_API_KEY:"",CLAUDE_MEM_OPENROUTER_MODEL:"xiaomi/mimo-v2-flash:free",CLAUDE_MEM_OPENROUTER_BASE_URL:"",CLAUDE_MEM_OPENROUTER_SITE_URL:"",CLAUDE_MEM_OPENROUTER_APP_NAME:"claude-mem",CLAUDE_MEM_DATA_DIR:(0,P.join)((0,me.homedir)(),".claude-mem"),CLAUDE_MEM_LOG_LEVEL:"INFO",CLAUDE_MEM_PYTHON_VERSION:"3.13",CLAUDE_CODE_PATH:"",CLAUDE_MEM_MODE:"code",CLAUDE_MEM_CONTEXT_SHOW_READ_TOKENS:"false",CLAUDE_MEM_CONTEXT_SHOW_WORK_TOKENS:"false",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT:"false",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT:"true",CLAUDE_MEM_CONTEXT_FULL_COUNT:"0",CLAUDE_MEM_CONTEXT_FULL_FIELD:"narrative",CLAUDE_MEM_CONTEXT_SESSION_COUNT:"10",CLAUDE_MEM_CONTEXT_SHOW_LAST_SUMMARY:"true",CLAUDE_MEM_CONTEXT_SHOW_LAST_MESSAGE:"false",CLAUDE_MEM_CONTEXT_SHOW_TERMINAL_OUTPUT:"true",CLAUDE_MEM_WELCOME_HINT_ENABLED:"true",CLAUDE_MEM_FOLDER_CLAUDEMD_ENABLED:"false",CLAUDE_MEM_FOLDER_USE_LOCAL_MD:"false",CLAUDE_MEM_TRANSCRIPTS_ENABLED:"true",CLAUDE_MEM_TRANSCRIPTS_CONFIG_PATH:(0,P.join)((0,me.homedir)(),".claude-mem","transcript-watch.json"),CLAUDE_MEM_CODEX_TRANSCRIPT_INGESTION:"false",CLAUDE_MEM_MAX_CONCURRENT_AGENTS:"2",CLAUDE_MEM_HOOK_FAIL_LOUD_THRESHOLD:"3",CLAUDE_MEM_EXCLUDED_PROJECTS:"",CLAUDE_MEM_FOLDER_MD_EXCLUDE:"[]",CLAUDE_MEM_FOLDER_MD_SKELETON_DENYLIST:"[]",CLAUDE_MEM_SEMANTIC_INJECT:"false",CLAUDE_MEM_SEMANTIC_INJECT_LIMIT:"5",CLAUDE_MEM_TIER_ROUTING_ENABLED:"true",CLAUDE_MEM_TIER_SIMPLE_MODEL:"haiku",CLAUDE_MEM_TIER_SUMMARY_MODEL:"",CLAUDE_MEM_TIER_FAST_MODEL:"haiku",CLAUDE_MEM_TIER_SMART_MODEL:"sonnet",CLAUDE_MEM_CHROMA_ENABLED:"true",CLAUDE_MEM_CHROMA_MODE:"local",CLAUDE_MEM_CHROMA_HOST:"127.0.0.1",CLAUDE_MEM_CHROMA_PORT:"8000",CLAUDE_MEM_CHROMA_SSL:"false",CLAUDE_MEM_CHROMA_API_KEY:"",CLAUDE_MEM_CHROMA_TENANT:"default_tenant",CLAUDE_MEM_CHROMA_DATABASE:"default_database",CLAUDE_MEM_CHROMA_PREWARM_TIMEOUT_MS:"120000",CLAUDE_MEM_TELEGRAM_ENABLED:"true",CLAUDE_MEM_TELEGRAM_BOT_TOKEN:"",CLAUDE_MEM_TELEGRAM_CHAT_ID:"",CLAUDE_MEM_TELEGRAM_TRIGGER_TYPES:"security_alert",CLAUDE_MEM_TELEGRAM_TRIGGER_CONCEPTS:"",CLAUDE_MEM_QUEUE_ENGINE:"sqlite",CLAUDE_MEM_REDIS_URL:"",CLAUDE_MEM_REDIS_HOST:"127.0.0.1",CLAUDE_MEM_REDIS_PORT:"6379",CLAUDE_MEM_REDIS_MODE:"external",CLAUDE_MEM_QUEUE_REDIS_PREFIX:`claude_mem_${process.env.CLAUDE_MEM_WORKER_PORT??String(37700+(process.getuid?.()??77)%100)}`,CLAUDE_MEM_AUTH_MODE:"api-key",CLAUDE_MEM_RUNTIME:"worker",CLAUDE_MEM_SERVER_URL:`http://127.0.0.1:${process.env.CLAUDE_MEM_SERVER_PORT??String(37877+(process.getuid?.()??77)%100)}`,CLAUDE_MEM_SERVER_API_KEY:"",CLAUDE_MEM_SERVER_PROJECT_ID:"",CLAUDE_MEM_SERVER_BETA_URL:`http://127.0.0.1:${process.env.CLAUDE_MEM_SERVER_PORT??String(37877+(process.getuid?.()??77)%100)}`,CLAUDE_MEM_SERVER_BETA_API_KEY:"",CLAUDE_MEM_SERVER_BETA_PROJECT_ID:""};static getAllDefaults(){return{...this.DEFAULTS}}static get(e){return process.env[e]??this.DEFAULTS[e]}static getInt(e){let t=this.get(e);return parseInt(t,10)}static getBool(e){let t=this.get(e);return t==="true"||t===!0}static applyEnvOverrides(e){let t={...e};for(let s of Object.keys(this.DEFAULTS))process.env[s]!==void 0&&(t[s]=process.env[s]);return t}static loadFromFile(e,t=!0){try{if(!(0,M.existsSync)(e)){let a=this.getAllDefaults();try{let d=(0,P.dirname)(e);(0,M.existsSync)(d)||(0,M.mkdirSync)(d,{recursive:!0}),(0,M.writeFileSync)(e,JSON.stringify(a,null,2),"utf-8"),console.warn("[SETTINGS] Created settings file with defaults:",e)}catch(d){console.warn("[SETTINGS] Failed to create settings file, using in-memory defaults:",e,d instanceof Error?d.message:String(d))}return t?this.applyEnvOverrides(a):a}let s=(0,M.readFileSync)(e,"utf-8"),r=JSON.parse(s.replace(/^\uFEFF/,"")),o=r;if(r.env&&typeof r.env=="object"){o=r.env;try{(0,M.writeFileSync)(e,JSON.stringify(o,null,2),"utf-8"),console.warn("[SETTINGS] Migrated settings file from nested to flat schema:",e)}catch(a){console.warn("[SETTINGS] Failed to auto-migrate settings file:",e,a instanceof Error?a.message:String(a))}}let i={...this.DEFAULTS};for(let a of Object.keys(this.DEFAULTS))o[a]!==void 0&&(i[a]=o[a]);return t?this.applyEnvOverrides(i):i}catch(s){console.warn("[SETTINGS] Failed to load settings, using defaults:",e,s instanceof Error?s.message:String(s));let r=this.getAllDefaults();return t?this.applyEnvOverrides(r):r}}};var $=require("fs"),K=require("path");var D=class n{static instance=null;activeMode=null;modesDir;constructor(){let e=Ie(),t=[...process.env.CLAUDE_MEM_MODES_DIR?[process.env.CLAUDE_MEM_MODES_DIR]:[],(0,K.join)(e,"modes"),(0,K.join)(e,"..","plugin","modes")],s=t.find(r=>(0,$.existsSync)(r));this.modesDir=s||t[0]}static getInstance(){return n.instance||(n.instance=new n),n.instance}parseInheritance(e){let t=e.split("--");if(t.length===1)return{hasParent:!1,parentId:"",overrideId:""};if(t.length>2)throw new Error(`Invalid mode inheritance: ${e}. Only one level of inheritance supported (parent--override)`);return{hasParent:!0,parentId:t[0],overrideId:e}}isPlainObject(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}deepMerge(e,t){let s={...e};for(let r in t){let o=t[r],i=e[r];this.isPlainObject(o)&&this.isPlainObject(i)?s[r]=this.deepMerge(i,o):s[r]=o}return s}loadModeFile(e){let t=(0,K.join)(this.modesDir,`${e}.json`);if(!(0,$.existsSync)(t))throw new Error(`Mode file not found: ${t}`);let s=(0,$.readFileSync)(t,"utf-8");return JSON.parse(s)}loadMode(e){let t=this.parseInheritance(e);if(!t.hasParent)try{let d=this.loadModeFile(e);return this.activeMode=d,E.debug("SYSTEM",`Loaded mode: ${d.name} (${e})`,void 0,{types:d.observation_types.map(_=>_.id),concepts:d.observation_concepts.map(_=>_.id)}),d}catch(d){if(d instanceof Error?E.warn("WORKER",`Mode file not found: ${e}, falling back to 'code'`,{message:d.message}):E.warn("WORKER",`Mode file not found: ${e}, falling back to 'code'`,{error:String(d)}),e==="code")throw new Error("Critical: code.json mode file missing");return this.loadMode("code")}let{parentId:s,overrideId:r}=t,o;try{o=this.loadMode(s)}catch(d){d instanceof Error?E.warn("WORKER",`Parent mode '${s}' not found for ${e}, falling back to 'code'`,{message:d.message}):E.warn("WORKER",`Parent mode '${s}' not found for ${e}, falling back to 'code'`,{error:String(d)}),o=this.loadMode("code")}let i;try{i=this.loadModeFile(r),E.debug("SYSTEM",`Loaded override file: ${r} for parent ${s}`)}catch(d){return d instanceof Error?E.warn("WORKER",`Override file '${r}' not found, using parent mode '${s}' only`,{message:d.message}):E.warn("WORKER",`Override file '${r}' not found, using parent mode '${s}' only`,{error:String(d)}),this.activeMode=o,o}if(!i)return E.warn("SYSTEM",`Invalid override file: ${r}, using parent mode '${s}' only`),this.activeMode=o,o;let a=this.deepMerge(o,i);return this.activeMode=a,E.debug("SYSTEM",`Loaded mode with inheritance: ${a.name} (${e} = ${s} + ${r})`,void 0,{parent:s,override:r,types:a.observation_types.map(d=>d.id),concepts:a.observation_concepts.map(d=>d.id)}),a}getActiveMode(){if(!this.activeMode)throw new Error("No mode loaded. Call loadMode() first.");return this.activeMode}getObservationTypes(){return this.getActiveMode().observation_types}getTypeIcon(e){return this.getObservationTypes().find(s=>s.id===e)?.emoji||"\u{1F4DD}"}getWorkEmoji(e){return this.getObservationTypes().find(s=>s.id===e)?.work_emoji||"\u{1F4DD}"}};function Xe(){let n=F.settings(),e=q.loadFromFile(n),t=D.getInstance().getActiveMode(),s=new Set(t.observation_types.map(o=>o.id)),r=new Set(t.observation_concepts.map(o=>o.id));return{totalObservationCount:parseInt(e.CLAUDE_MEM_CONTEXT_OBSERVATIONS,10),fullObservationCount:parseInt(e.CLAUDE_MEM_CONTEXT_FULL_COUNT,10),sessionCount:parseInt(e.CLAUDE_MEM_CONTEXT_SESSION_COUNT,10),showReadTokens:e.CLAUDE_MEM_CONTEXT_SHOW_READ_TOKENS==="true",showWorkTokens:e.CLAUDE_MEM_CONTEXT_SHOW_WORK_TOKENS==="true",showSavingsAmount:e.CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT==="true",showSavingsPercent:e.CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT==="true",observationTypes:s,observationConcepts:r,fullObservationField:e.CLAUDE_MEM_CONTEXT_FULL_FIELD,showLastSummary:e.CLAUDE_MEM_CONTEXT_SHOW_LAST_SUMMARY==="true",showLastMessage:e.CLAUDE_MEM_CONTEXT_SHOW_LAST_MESSAGE==="true"}}var u={reset:"\x1B[0m",bright:"\x1B[1m",dim:"\x1B[2m",cyan:"\x1B[36m",green:"\x1B[32m",yellow:"\x1B[33m",blue:"\x1B[34m",magenta:"\x1B[35m",gray:"\x1B[90m",red:"\x1B[31m"},Ge=4,pe=1;function je(n){let e=(n.title?.length||0)+(n.subtitle?.length||0)+(n.narrative?.length||0)+JSON.stringify(n.facts||[]).length;return Math.ceil(e/Ge)}function ce(n){let e=n.length,t=n.reduce((i,a)=>i+je(a),0),s=n.reduce((i,a)=>i+(a.discovery_tokens||0),0),r=s-t,o=s>0?Math.round(r/s*100):0;return{totalObservations:e,totalReadTokens:t,totalDiscoveryTokens:s,savings:r,savingsPercent:o}}function us(n){return D.getInstance().getWorkEmoji(n)}function H(n,e){let t=je(n),s=n.discovery_tokens||0,r=us(n.type),o=s>0?`${r} ${s.toLocaleString()}`:"-";return{readTokens:t,discoveryTokens:s,discoveryDisplay:o,workEmoji:r}}function J(n){return n.showReadTokens||n.showWorkTokens||n.showSavingsAmount||n.showSavingsPercent}var Be=k(require("path"),1),Q=require("fs");function We(n,e,t,s){let r=Array.from(t.observationTypes),o=r.map(()=>"?").join(","),i=Array.from(t.observationConcepts),a=i.map(()=>"?").join(",");return n.db.prepare(`
870
- SELECT
871
- o.id,
872
- o.memory_session_id,
873
- COALESCE(s.platform_source, 'claude') as platform_source,
874
- o.type,
875
- o.title,
876
- o.subtitle,
877
- o.narrative,
878
- o.facts,
879
- o.concepts,
880
- o.files_read,
881
- o.files_modified,
882
- o.discovery_tokens,
883
- o.created_at,
884
- o.created_at_epoch
885
- FROM observations o
886
- LEFT JOIN sdk_sessions s ON o.memory_session_id = s.memory_session_id
887
- WHERE (o.project = ? OR o.merged_into_project = ?)
888
- AND (? IS NULL OR s.platform_source = ?)
889
- AND type IN (${o})
890
- AND EXISTS (
891
- SELECT 1 FROM json_each(o.concepts)
892
- WHERE value IN (${a})
893
- )
894
- ORDER BY o.created_at_epoch DESC
895
- LIMIT ?
896
- `).all(e,e,s??null,s??null,...r,...i,t.totalObservationCount)}function Ve(n,e,t,s){return n.db.prepare(`
897
- SELECT
898
- ss.id,
899
- ss.memory_session_id,
900
- COALESCE(s.platform_source, 'claude') as platform_source,
901
- ss.request,
902
- ss.investigated,
903
- ss.learned,
904
- ss.completed,
905
- ss.next_steps,
906
- ss.created_at,
907
- ss.created_at_epoch
908
- FROM session_summaries ss
909
- LEFT JOIN sdk_sessions s ON ss.memory_session_id = s.memory_session_id
910
- WHERE (ss.project = ? OR ss.merged_into_project = ?)
911
- AND (? IS NULL OR s.platform_source = ?)
912
- ORDER BY ss.created_at_epoch DESC
913
- LIMIT ?
914
- `).all(e,e,s??null,s??null,t.sessionCount+pe)}function Ye(n,e,t,s){let r=Array.from(t.observationTypes),o=r.map(()=>"?").join(","),i=Array.from(t.observationConcepts),a=i.map(()=>"?").join(","),d=e.map(()=>"?").join(",");return n.db.prepare(`
759
+ `).run(s,e.content_session_id,e.prompt_number,e.prompt_text,e.created_at,e.created_at_epoch).lastInsertRowid}}};var ye=require("os"),Ue=x(require("path"),1),xe=require("child_process");var V=require("fs"),W=x(require("path"),1);var w={isWorktree:!1,worktreeName:null,parentRepoPath:null,parentProjectName:null};function ve(n){let e=W.default.join(n,".git"),s;try{s=(0,V.statSync)(e)}catch(m){return m instanceof Error&&m.code!=="ENOENT"&&_.warn("GIT","Unexpected error checking .git",{error:m instanceof Error?m.message:String(m)}),w}if(!s.isFile())return w;let t;try{t=(0,V.readFileSync)(e,"utf-8").trim()}catch(m){return _.warn("GIT","Failed to read .git file",{error:m instanceof Error?m.message:String(m)}),w}let r=t.match(/^gitdir:\s*(.+)$/);if(!r)return w;let i=r[1].match(/^(.+)[/\\]\.git[/\\]worktrees[/\\]([^/\\]+)$/);if(!i)return w;let a=i[1],d=W.default.basename(n),u=W.default.basename(a);return{isWorktree:!0,worktreeName:d,parentRepoPath:a,parentProjectName:u}}function ke(n){return n==="~"||n.startsWith("~/")?n.replace(/^~/,(0,ye.homedir)()):n}function Zs(n){try{return(0,xe.execFileSync)("git",["rev-parse","--show-toplevel"],{cwd:n,encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim()||null}catch(e){let s=e instanceof Error?e:new Error(String(e));return _.debug("PROJECT_NAME","git rev-parse failed, falling back to basename",{dir:n},s),null}}function et(n){if(!n||n.trim()==="")return _.warn("PROJECT_NAME","Empty cwd provided, using fallback",{cwd:n}),"unknown-project";let e=ke(n),t=Zs(e)??e,r=Ue.default.basename(t);if(r===""){if(process.platform==="win32"){let i=n.match(/^([A-Z]):\\/i);if(i){let d=`drive-${i[1].toUpperCase()}`;return _.info("PROJECT_NAME","Drive root detected",{cwd:n,projectName:d}),d}}return _.warn("PROJECT_NAME","Root directory detected, using fallback",{cwd:n}),"unknown-project"}return r}function we(n){let e=et(n);if(!n)return{primary:e,parent:null,isWorktree:!1,allProjects:[e]};let s=ke(n),t=ve(s);if(t.isWorktree&&t.parentProjectName){let r=`${t.parentProjectName}/${e}`;return{primary:r,parent:t.parentProjectName,isWorktree:!0,allProjects:[t.parentProjectName,r]}}return{primary:e,parent:null,isWorktree:!1,allProjects:[e]}}var M=require("fs"),F=require("path"),Ee=require("os");var _e={HEALTH_CHECK:3e3,API_REQUEST:3e4,HOOK_READINESS_WAIT:1e4,POST_SPAWN_WAIT:15e3,READINESS_WAIT:3e4,PORT_IN_USE_WAIT:3e3,POWERSHELL_COMMAND:1e4,WINDOWS_MULTIPLIER:1.5};function Fe(n){return process.platform==="win32"?Math.round(n*_e.WINDOWS_MULTIPLIER):n}var K=class{static DEFAULTS={CLAUDE_MEM_MODEL:"claude-haiku-4-5-20251001",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_WORKER_PORT:String(37700+(process.getuid?.()??77)%100),CLAUDE_MEM_WORKER_HOST:"127.0.0.1",CLAUDE_MEM_API_TIMEOUT_MS:String(Fe(_e.API_REQUEST)),CLAUDE_MEM_SKIP_TOOLS:"ListMcpResourcesTool,SlashCommand,Skill,TodoWrite,AskUserQuestion",CLAUDE_MEM_PROVIDER:"claude",CLAUDE_MEM_CLAUDE_AUTH_METHOD:"subscription",CLAUDE_MEM_GEMINI_API_KEY:"",CLAUDE_MEM_GEMINI_MODEL:"gemini-2.5-flash-lite",CLAUDE_MEM_GEMINI_RATE_LIMITING_ENABLED:"true",CLAUDE_MEM_OPENROUTER_API_KEY:"",CLAUDE_MEM_OPENROUTER_MODEL:"xiaomi/mimo-v2-flash:free",CLAUDE_MEM_OPENROUTER_BASE_URL:"",CLAUDE_MEM_OPENROUTER_SITE_URL:"",CLAUDE_MEM_OPENROUTER_APP_NAME:"claude-mem",CLAUDE_MEM_DATA_DIR:(0,F.join)((0,Ee.homedir)(),".claude-mem"),CLAUDE_MEM_LOG_LEVEL:"INFO",CLAUDE_MEM_PYTHON_VERSION:"3.13",CLAUDE_CODE_PATH:"",CLAUDE_MEM_MODE:"code",CLAUDE_MEM_CONTEXT_SHOW_READ_TOKENS:"false",CLAUDE_MEM_CONTEXT_SHOW_WORK_TOKENS:"false",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT:"false",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT:"true",CLAUDE_MEM_CONTEXT_FULL_COUNT:"0",CLAUDE_MEM_CONTEXT_FULL_FIELD:"narrative",CLAUDE_MEM_CONTEXT_SESSION_COUNT:"10",CLAUDE_MEM_CONTEXT_SHOW_LAST_SUMMARY:"true",CLAUDE_MEM_CONTEXT_SHOW_LAST_MESSAGE:"false",CLAUDE_MEM_CONTEXT_SHOW_TERMINAL_OUTPUT:"true",CLAUDE_MEM_WELCOME_HINT_ENABLED:"true",CLAUDE_MEM_FOLDER_CLAUDEMD_ENABLED:"false",CLAUDE_MEM_FOLDER_USE_LOCAL_MD:"false",CLAUDE_MEM_TRANSCRIPTS_ENABLED:"true",CLAUDE_MEM_TRANSCRIPTS_CONFIG_PATH:(0,F.join)((0,Ee.homedir)(),".claude-mem","transcript-watch.json"),CLAUDE_MEM_CODEX_TRANSCRIPT_INGESTION:"false",CLAUDE_MEM_MAX_CONCURRENT_AGENTS:"2",CLAUDE_MEM_HOOK_FAIL_LOUD_THRESHOLD:"3",CLAUDE_MEM_EXCLUDED_PROJECTS:"",CLAUDE_MEM_FOLDER_MD_EXCLUDE:"[]",CLAUDE_MEM_FOLDER_MD_SKELETON_DENYLIST:"[]",CLAUDE_MEM_SEMANTIC_INJECT:"false",CLAUDE_MEM_SEMANTIC_INJECT_LIMIT:"5",CLAUDE_MEM_TIER_ROUTING_ENABLED:"true",CLAUDE_MEM_TIER_SIMPLE_MODEL:"haiku",CLAUDE_MEM_TIER_SUMMARY_MODEL:"",CLAUDE_MEM_TIER_FAST_MODEL:"haiku",CLAUDE_MEM_TIER_SMART_MODEL:"sonnet",CLAUDE_MEM_CHROMA_ENABLED:"true",CLAUDE_MEM_CHROMA_MODE:"local",CLAUDE_MEM_CHROMA_HOST:"127.0.0.1",CLAUDE_MEM_CHROMA_PORT:"8000",CLAUDE_MEM_CHROMA_SSL:"false",CLAUDE_MEM_CHROMA_API_KEY:"",CLAUDE_MEM_CHROMA_TENANT:"default_tenant",CLAUDE_MEM_CHROMA_DATABASE:"default_database",CLAUDE_MEM_CHROMA_PREWARM_TIMEOUT_MS:"120000",CLAUDE_MEM_TELEGRAM_ENABLED:"true",CLAUDE_MEM_TELEGRAM_BOT_TOKEN:"",CLAUDE_MEM_TELEGRAM_CHAT_ID:"",CLAUDE_MEM_TELEGRAM_TRIGGER_TYPES:"security_alert",CLAUDE_MEM_TELEGRAM_TRIGGER_CONCEPTS:"",CLAUDE_MEM_QUEUE_ENGINE:"sqlite",CLAUDE_MEM_REDIS_URL:"",CLAUDE_MEM_REDIS_HOST:"127.0.0.1",CLAUDE_MEM_REDIS_PORT:"6379",CLAUDE_MEM_REDIS_MODE:"external",CLAUDE_MEM_QUEUE_REDIS_PREFIX:`claude_mem_${process.env.CLAUDE_MEM_WORKER_PORT??String(37700+(process.getuid?.()??77)%100)}`,CLAUDE_MEM_AUTH_MODE:"api-key",CLAUDE_MEM_RUNTIME:"worker",CLAUDE_MEM_SERVER_URL:`http://127.0.0.1:${process.env.CLAUDE_MEM_SERVER_PORT??String(37877+(process.getuid?.()??77)%100)}`,CLAUDE_MEM_SERVER_API_KEY:"",CLAUDE_MEM_SERVER_PROJECT_ID:"",CLAUDE_MEM_SERVER_BETA_URL:`http://127.0.0.1:${process.env.CLAUDE_MEM_SERVER_PORT??String(37877+(process.getuid?.()??77)%100)}`,CLAUDE_MEM_SERVER_BETA_API_KEY:"",CLAUDE_MEM_SERVER_BETA_PROJECT_ID:""};static getAllDefaults(){return{...this.DEFAULTS}}static get(e){return process.env[e]??this.DEFAULTS[e]}static getInt(e){let s=this.get(e);return parseInt(s,10)}static applyEnvOverrides(e){let s={...e};for(let t of Object.keys(this.DEFAULTS))process.env[t]!==void 0&&(s[t]=process.env[t]);return s}static loadFromFile(e,s=!0){try{if(!(0,M.existsSync)(e)){let a=this.getAllDefaults();try{let d=(0,F.dirname)(e);(0,M.existsSync)(d)||(0,M.mkdirSync)(d,{recursive:!0}),(0,M.writeFileSync)(e,JSON.stringify(a,null,2),"utf-8"),console.warn("[SETTINGS] Created settings file with defaults:",e)}catch(d){console.warn("[SETTINGS] Failed to create settings file, using in-memory defaults:",e,d instanceof Error?d.message:String(d))}return s?this.applyEnvOverrides(a):a}let t=(0,M.readFileSync)(e,"utf-8"),r=JSON.parse(t.replace(/^\uFEFF/,"")),o=r;if(r.env&&typeof r.env=="object"){o=r.env;try{(0,M.writeFileSync)(e,JSON.stringify(o,null,2),"utf-8"),console.warn("[SETTINGS] Migrated settings file from nested to flat schema:",e)}catch(a){console.warn("[SETTINGS] Failed to auto-migrate settings file:",e,a instanceof Error?a.message:String(a))}}let i={...this.DEFAULTS};for(let a of Object.keys(this.DEFAULTS))o[a]!==void 0&&(i[a]=o[a]);return s?this.applyEnvOverrides(i):i}catch(t){console.warn("[SETTINGS] Failed to load settings, using defaults:",e,t instanceof Error?t.message:String(t));let r=this.getAllDefaults();return s?this.applyEnvOverrides(r):r}}};var P=require("fs"),Y=require("path");var D=class n{static instance=null;activeMode=null;modesDir;constructor(){let e=Re(),s=[...process.env.CLAUDE_MEM_MODES_DIR?[process.env.CLAUDE_MEM_MODES_DIR]:[],(0,Y.join)(e,"modes"),(0,Y.join)(e,"..","plugin","modes")],t=s.find(r=>(0,P.existsSync)(r));this.modesDir=t||s[0]}static getInstance(){return n.instance||(n.instance=new n),n.instance}parseInheritance(e){let s=e.split("--");if(s.length===1)return{hasParent:!1,parentId:"",overrideId:""};if(s.length>2)throw new Error(`Invalid mode inheritance: ${e}. Only one level of inheritance supported (parent--override)`);return{hasParent:!0,parentId:s[0],overrideId:e}}isPlainObject(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}deepMerge(e,s){let t={...e};for(let r in s){let o=s[r],i=e[r];this.isPlainObject(o)&&this.isPlainObject(i)?t[r]=this.deepMerge(i,o):t[r]=o}return t}loadModeFile(e){let s=(0,Y.join)(this.modesDir,`${e}.json`);if(!(0,P.existsSync)(s))throw new Error(`Mode file not found: ${s}`);let t=(0,P.readFileSync)(s,"utf-8");return JSON.parse(t)}loadMode(e){let s=this.parseInheritance(e);if(!s.hasParent)try{let d=this.loadModeFile(e);return this.activeMode=d,_.debug("SYSTEM",`Loaded mode: ${d.name} (${e})`,void 0,{types:d.observation_types.map(u=>u.id),concepts:d.observation_concepts.map(u=>u.id)}),d}catch(d){if(d instanceof Error?_.warn("WORKER",`Mode file not found: ${e}, falling back to 'code'`,{message:d.message}):_.warn("WORKER",`Mode file not found: ${e}, falling back to 'code'`,{error:String(d)}),e==="code")throw new Error("Critical: code.json mode file missing");return this.loadMode("code")}let{parentId:t,overrideId:r}=s,o;try{o=this.loadMode(t)}catch(d){d instanceof Error?_.warn("WORKER",`Parent mode '${t}' not found for ${e}, falling back to 'code'`,{message:d.message}):_.warn("WORKER",`Parent mode '${t}' not found for ${e}, falling back to 'code'`,{error:String(d)}),o=this.loadMode("code")}let i;try{i=this.loadModeFile(r),_.debug("SYSTEM",`Loaded override file: ${r} for parent ${t}`)}catch(d){return d instanceof Error?_.warn("WORKER",`Override file '${r}' not found, using parent mode '${t}' only`,{message:d.message}):_.warn("WORKER",`Override file '${r}' not found, using parent mode '${t}' only`,{error:String(d)}),this.activeMode=o,o}if(!i)return _.warn("SYSTEM",`Invalid override file: ${r}, using parent mode '${t}' only`),this.activeMode=o,o;let a=this.deepMerge(o,i);return this.activeMode=a,_.debug("SYSTEM",`Loaded mode with inheritance: ${a.name} (${e} = ${t} + ${r})`,void 0,{parent:t,override:r,types:a.observation_types.map(d=>d.id),concepts:a.observation_concepts.map(d=>d.id)}),a}getActiveMode(){if(!this.activeMode)throw new Error("No mode loaded. Call loadMode() first.");return this.activeMode}getObservationTypes(){return this.getActiveMode().observation_types}getTypeIcon(e){return this.getObservationTypes().find(t=>t.id===e)?.emoji||"\u{1F4DD}"}getWorkEmoji(e){return this.getObservationTypes().find(t=>t.id===e)?.work_emoji||"\u{1F4DD}"}};function Pe(){let n=k.settings(),e=K.loadFromFile(n),s=D.getInstance().getActiveMode(),t=new Set(s.observation_types.map(o=>o.id)),r=new Set(s.observation_concepts.map(o=>o.id));return{totalObservationCount:parseInt(e.CLAUDE_MEM_CONTEXT_OBSERVATIONS,10),fullObservationCount:parseInt(e.CLAUDE_MEM_CONTEXT_FULL_COUNT,10),sessionCount:parseInt(e.CLAUDE_MEM_CONTEXT_SESSION_COUNT,10),showReadTokens:e.CLAUDE_MEM_CONTEXT_SHOW_READ_TOKENS==="true",showWorkTokens:e.CLAUDE_MEM_CONTEXT_SHOW_WORK_TOKENS==="true",showSavingsAmount:e.CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT==="true",showSavingsPercent:e.CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT==="true",observationTypes:t,observationConcepts:r,fullObservationField:e.CLAUDE_MEM_CONTEXT_FULL_FIELD,showLastSummary:e.CLAUDE_MEM_CONTEXT_SHOW_LAST_SUMMARY==="true",showLastMessage:e.CLAUDE_MEM_CONTEXT_SHOW_LAST_MESSAGE==="true"}}var E={reset:"\x1B[0m",bright:"\x1B[1m",dim:"\x1B[2m",cyan:"\x1B[36m",green:"\x1B[32m",yellow:"\x1B[33m",blue:"\x1B[34m",magenta:"\x1B[35m",gray:"\x1B[90m",red:"\x1B[31m"},$e=4,Xe=1;function He(n){let e=(n.title?.length||0)+(n.subtitle?.length||0)+(n.narrative?.length||0)+JSON.stringify(n.facts||[]).length;return Math.ceil(e/$e)}function ue(n){let e=n.length,s=n.reduce((i,a)=>i+He(a),0),t=n.reduce((i,a)=>i+(a.discovery_tokens||0),0),r=t-s,o=t>0?Math.round(r/t*100):0;return{totalObservations:e,totalReadTokens:s,totalDiscoveryTokens:t,savings:r,savingsPercent:o}}function st(n){return D.getInstance().getWorkEmoji(n)}function $(n,e){let s=He(n),t=n.discovery_tokens||0,r=st(n.type),o=t>0?`${r} ${t.toLocaleString()}`:"-";return{readTokens:s,discoveryTokens:t,discoveryDisplay:o,workEmoji:r}}function q(n){return n.showReadTokens||n.showWorkTokens||n.showSavingsAmount||n.showSavingsPercent}var Ge=x(require("path"),1),J=require("fs");function Be(n,e,s,t){let r=Array.from(s.observationTypes),o=r.map(()=>"?").join(","),i=Array.from(s.observationConcepts),a=i.map(()=>"?").join(","),d=e.map(()=>"?").join(",");return n.db.prepare(`
915
760
  SELECT
916
761
  o.id,
917
762
  o.memory_session_id,
@@ -940,7 +785,7 @@ ${o.stack}`:` ${o.message}`;else if(this.getLevel()===0&&typeof o=="object")try{
940
785
  )
941
786
  ORDER BY o.created_at_epoch DESC
942
787
  LIMIT ?
943
- `).all(...e,...e,s??null,s??null,...r,...i,t.totalObservationCount)}function qe(n,e,t,s){let r=e.map(()=>"?").join(",");return n.db.prepare(`
788
+ `).all(...e,...e,t??null,t??null,...r,...i,s.totalObservationCount)}function je(n,e,s,t){let r=e.map(()=>"?").join(",");return n.db.prepare(`
944
789
  SELECT
945
790
  ss.id,
946
791
  ss.memory_session_id,
@@ -960,14 +805,14 @@ ${o.stack}`:` ${o.message}`;else if(this.getLevel()===0&&typeof o=="object")try{
960
805
  AND (? IS NULL OR s.platform_source = ?)
961
806
  ORDER BY ss.created_at_epoch DESC
962
807
  LIMIT ?
963
- `).all(...e,...e,s??null,s??null,t.sessionCount+pe)}function Es(n){return n.replace(/[/.]/g,"-")}function ms(n){if(!n.includes('"type":"assistant"'))return null;let e=JSON.parse(n);if(e.type==="assistant"&&e.message?.content&&Array.isArray(e.message.content)){let t="";for(let s of e.message.content)s.type==="text"&&(t+=s.text);if(t=t.replace(ye,"").trim(),t)return t}return null}function ps(n){for(let e=n.length-1;e>=0;e--)try{let t=ms(n[e]);if(t)return t}catch(t){t instanceof Error?E.debug("WORKER","Skipping malformed transcript line",{lineIndex:e},t):E.debug("WORKER","Skipping malformed transcript line",{lineIndex:e,error:String(t)});continue}return""}function cs(n){try{if(!(0,Q.existsSync)(n))return{assistantMessage:""};let e=(0,Q.readFileSync)(n,"utf-8").trim();if(!e)return{assistantMessage:""};let t=e.split(`
964
- `).filter(r=>r.trim());return{assistantMessage:ps(t)}}catch(e){return e instanceof Error?E.failure("WORKER","Failed to extract prior messages from transcript",{transcriptPath:n},e):E.warn("WORKER","Failed to extract prior messages from transcript",{transcriptPath:n,error:String(e)}),{assistantMessage:""}}}function Ke(n,e,t,s){if(!e.showLastMessage||n.length===0)return{assistantMessage:""};let r=n.find(d=>d.memory_session_id!==t);if(!r)return{assistantMessage:""};let o=r.memory_session_id,i=Es(s),a=Be.default.join(x,"projects",i,`${o}.jsonl`);return cs(a)}function Je(n,e){let t=e[0]?.id;return n.map((s,r)=>{let o=r===0?null:e[r+1];return{...s,displayEpoch:o?o.created_at_epoch:s.created_at_epoch,displayTime:o?o.created_at:s.created_at,shouldShowLink:s.id!==t}})}function Qe(n,e){let t=[...n.map(s=>({type:"observation",data:s})),...e.map(s=>({type:"summary",data:s}))];return t.sort((s,r)=>{let o=s.type==="observation"?s.data.created_at_epoch:s.data.displayEpoch,i=r.type==="observation"?r.data.created_at_epoch:r.data.displayEpoch;return o-i}),t}function ze(n,e){return new Set(n.slice(0,e).map(t=>t.id))}function Ze(){let n=new Date,e=n.toLocaleDateString("en-CA"),t=n.toLocaleTimeString("en-US",{hour:"numeric",minute:"2-digit",hour12:!0}).toLowerCase().replace(" ",""),s=n.toLocaleTimeString("en-US",{timeZoneName:"short"}).split(" ").pop();return`${e} ${t} ${s}`}function et(n){return[`# [${n}] recent context, ${Ze()}`,""]}function tt(){return[`Legend: \u{1F3AF}session ${D.getInstance().getActiveMode().observation_types.map(t=>`${t.emoji}${t.id}`).join(" ")}`,"Format: ID TIME TYPE TITLE","Fetch details: get_observations([IDs]) | Search: mem-search skill",""]}function st(n,e){let t=[],s=[`${n.totalObservations} obs (${n.totalReadTokens.toLocaleString()}t read)`,`${n.totalDiscoveryTokens.toLocaleString()}t work`];return n.totalDiscoveryTokens>0&&(e.showSavingsAmount||e.showSavingsPercent)&&(e.showSavingsPercent?s.push(`${n.savingsPercent}% savings`):e.showSavingsAmount&&s.push(`${n.savings.toLocaleString()}t saved`)),t.push(`Stats: ${s.join(" | ")}`),t.push(""),t}function rt(n){return[`### ${n}`]}function nt(n){return n.toLowerCase().replace(" am","a").replace(" pm","p")}function ot(n,e,t){let s=n.title||"Untitled",r=D.getInstance().getTypeIcon(n.type),o=e?nt(e):'"';return`${n.id} ${o} ${r} ${s}`}function it(n,e,t,s){let r=[],o=n.title||"Untitled",i=D.getInstance().getTypeIcon(n.type),a=e?nt(e):'"',{readTokens:d,discoveryDisplay:_}=H(n,s);r.push(`**${n.id}** ${a} ${i} **${o}**`),t&&r.push(t);let m=[];return s.showReadTokens&&m.push(`~${d}t`),s.showWorkTokens&&m.push(_),m.length>0&&r.push(m.join(" ")),r.push(""),r}function at(n,e){return[`S${n.id} ${n.request||"Session started"} (${e})`]}function X(n,e){return e?[`**${n}**: ${e}`,""]:[]}function dt(n){return n.assistantMessage?["","---","","**Previously**","",`A: ${n.assistantMessage}`,""]:[]}function _t(n,e){return["",`Access ${Math.round(n/1e3)}k tokens of past work via get_observations([IDs]) or mem-search skill.`]}function ut(n){return`# [${n}] recent context, ${Ze()}
808
+ `).all(...e,...e,t??null,t??null,s.sessionCount+Xe)}function tt(n){return n.replace(/[/.]/g,"-")}function rt(n){if(!n.includes('"type":"assistant"'))return null;let e=JSON.parse(n);if(e.type==="assistant"&&e.message?.content&&Array.isArray(e.message.content)){let s="";for(let t of e.message.content)t.type==="text"&&(s+=t.text);if(s=s.replace(De,"").trim(),s)return s}return null}function nt(n){for(let e=n.length-1;e>=0;e--)try{let s=rt(n[e]);if(s)return s}catch(s){s instanceof Error?_.debug("WORKER","Skipping malformed transcript line",{lineIndex:e},s):_.debug("WORKER","Skipping malformed transcript line",{lineIndex:e,error:String(s)});continue}return""}function ot(n){try{if(!(0,J.existsSync)(n))return{assistantMessage:""};let e=(0,J.readFileSync)(n,"utf-8").trim();if(!e)return{assistantMessage:""};let s=e.split(`
809
+ `).filter(r=>r.trim());return{assistantMessage:nt(s)}}catch(e){return e instanceof Error?_.failure("WORKER","Failed to extract prior messages from transcript",{transcriptPath:n},e):_.warn("WORKER","Failed to extract prior messages from transcript",{transcriptPath:n,error:String(e)}),{assistantMessage:""}}}function We(n,e,s,t){if(!e.showLastMessage||n.length===0)return{assistantMessage:""};let r=n.find(d=>d.memory_session_id!==s);if(!r)return{assistantMessage:""};let o=r.memory_session_id,i=tt(t),a=Ge.default.join(se,"projects",i,`${o}.jsonl`);return ot(a)}function Ve(n,e){let s=e[0]?.id;return n.map((t,r)=>{let o=r===0?null:e[r+1];return{...t,displayEpoch:o?o.created_at_epoch:t.created_at_epoch,displayTime:o?o.created_at:t.created_at,shouldShowLink:t.id!==s}})}function Ke(n,e){let s=[...n.map(t=>({type:"observation",data:t})),...e.map(t=>({type:"summary",data:t}))];return s.sort((t,r)=>{let o=t.type==="observation"?t.data.created_at_epoch:t.data.displayEpoch,i=r.type==="observation"?r.data.created_at_epoch:r.data.displayEpoch;return o-i}),s}function Ye(n,e){return new Set(n.slice(0,e).map(s=>s.id))}function qe(){let n=new Date,e=n.toLocaleDateString("en-CA"),s=n.toLocaleTimeString("en-US",{hour:"numeric",minute:"2-digit",hour12:!0}).toLowerCase().replace(" ",""),t=n.toLocaleTimeString("en-US",{timeZoneName:"short"}).split(" ").pop();return`${e} ${s} ${t}`}function Je(n){return[`# [${n}] recent context, ${qe()}`,""]}function Qe(){return[`Legend: \u{1F3AF}session ${D.getInstance().getActiveMode().observation_types.map(s=>`${s.emoji}${s.id}`).join(" ")}`,"Format: ID TIME TYPE TITLE","Fetch details: get_observations([IDs]) | Search: mem-search skill",""]}function ze(n,e){let s=[],t=[`${n.totalObservations} obs (${n.totalReadTokens.toLocaleString()}t read)`,`${n.totalDiscoveryTokens.toLocaleString()}t work`];return n.totalDiscoveryTokens>0&&(e.showSavingsAmount||e.showSavingsPercent)&&(e.showSavingsPercent?t.push(`${n.savingsPercent}% savings`):e.showSavingsAmount&&t.push(`${n.savings.toLocaleString()}t saved`)),s.push(`Stats: ${t.join(" | ")}`),s.push(""),s}function Ze(n){return[`### ${n}`]}function es(n){return n.toLowerCase().replace(" am","a").replace(" pm","p")}function ss(n,e,s){let t=n.title||"Untitled",r=D.getInstance().getTypeIcon(n.type),o=e?es(e):'"';return`${n.id} ${o} ${r} ${t}`}function ts(n,e,s,t){let r=[],o=n.title||"Untitled",i=D.getInstance().getTypeIcon(n.type),a=e?es(e):'"',{readTokens:d,discoveryDisplay:u}=$(n,t);r.push(`**${n.id}** ${a} ${i} **${o}**`),s&&r.push(s);let m=[];return t.showReadTokens&&m.push(`~${d}t`),t.showWorkTokens&&m.push(u),m.length>0&&r.push(m.join(" ")),r.push(""),r}function rs(n,e){return[`S${n.id} ${n.request||"Session started"} (${e})`]}function X(n,e){return e?[`**${n}**: ${e}`,""]:[]}function ns(n){return n.assistantMessage?["","---","","**Previously**","",`A: ${n.assistantMessage}`,""]:[]}function os(n,e){return["",`Access ${Math.round(n/1e3)}k tokens of past work via get_observations([IDs]) or mem-search skill.`]}function is(n){return`# [${n}] recent context, ${qe()}
965
810
 
966
- No previous sessions found.`}function Et(){let n=new Date,e=n.toLocaleDateString("en-CA"),t=n.toLocaleTimeString("en-US",{hour:"numeric",minute:"2-digit",hour12:!0}).toLowerCase().replace(" ",""),s=n.toLocaleTimeString("en-US",{timeZoneName:"short"}).split(" ").pop();return`${e} ${t} ${s}`}function mt(n){return["",`${u.bright}${u.cyan}[${n}] recent context, ${Et()}${u.reset}`,`${u.gray}${"\u2500".repeat(60)}${u.reset}`,""]}function pt(){let e=D.getInstance().getActiveMode().observation_types.map(t=>`${t.emoji} ${t.id}`).join(" | ");return[`${u.dim}Legend: session-request | ${e}${u.reset}`,""]}function ct(){return[`${u.bright}Column Key${u.reset}`,`${u.dim} Read: Tokens to read this observation (cost to learn it now)${u.reset}`,`${u.dim} Work: Tokens spent on work that produced this record ( research, building, deciding)${u.reset}`,""]}function lt(){return[`${u.dim}Context Index: This semantic index (titles, types, files, tokens) is usually sufficient to understand past work.${u.reset}`,"",`${u.dim}When you need implementation details, rationale, or debugging context:${u.reset}`,`${u.dim} - Fetch by ID: get_observations([IDs]) for observations visible in this index${u.reset}`,`${u.dim} - Search history: Use the mem-search skill for past decisions, bugs, and deeper research${u.reset}`,`${u.dim} - Trust this index over re-reading code for past decisions and learnings${u.reset}`,""]}function Tt(n,e){let t=[];if(t.push(`${u.bright}${u.cyan}Context Economics${u.reset}`),t.push(`${u.dim} Loading: ${n.totalObservations} observations (${n.totalReadTokens.toLocaleString()} tokens to read)${u.reset}`),t.push(`${u.dim} Work investment: ${n.totalDiscoveryTokens.toLocaleString()} tokens spent on research, building, and decisions${u.reset}`),n.totalDiscoveryTokens>0&&(e.showSavingsAmount||e.showSavingsPercent)){let s=" Your savings: ";e.showSavingsAmount&&e.showSavingsPercent?s+=`${n.savings.toLocaleString()} tokens (${n.savingsPercent}% reduction from reuse)`:e.showSavingsAmount?s+=`${n.savings.toLocaleString()} tokens`:s+=`${n.savingsPercent}% reduction from reuse`,t.push(`${u.green}${s}${u.reset}`)}return t.push(""),t}function gt(n){return[`${u.bright}${u.cyan}${n}${u.reset}`,""]}function St(n){return[`${u.dim}${n}${u.reset}`]}function ft(n,e,t,s){let r=n.title||"Untitled",o=D.getInstance().getTypeIcon(n.type),{readTokens:i,discoveryTokens:a,workEmoji:d}=H(n,s),_=t?`${u.dim}${e}${u.reset}`:" ".repeat(e.length),m=s.showReadTokens&&i>0?`${u.dim}(~${i}t)${u.reset}`:"",l=s.showWorkTokens&&a>0?`${u.dim}(${d} ${a.toLocaleString()}t)${u.reset}`:"";return` ${u.dim}#${n.id}${u.reset} ${_} ${o} ${r} ${m} ${l}`}function Rt(n,e,t,s,r){let o=[],i=n.title||"Untitled",a=D.getInstance().getTypeIcon(n.type),{readTokens:d,discoveryTokens:_,workEmoji:m}=H(n,r),l=t?`${u.dim}${e}${u.reset}`:" ".repeat(e.length),p=r.showReadTokens&&d>0?`${u.dim}(~${d}t)${u.reset}`:"",g=r.showWorkTokens&&_>0?`${u.dim}(${m} ${_.toLocaleString()}t)${u.reset}`:"";return o.push(` ${u.dim}#${n.id}${u.reset} ${l} ${a} ${u.bright}${i}${u.reset}`),s&&o.push(` ${u.dim}${s}${u.reset}`),(p||g)&&o.push(` ${p} ${g}`),o.push(""),o}function bt(n,e){let t=`${n.request||"Session started"} (${e})`;return[`${u.yellow}#S${n.id}${u.reset} ${t}`,""]}function G(n,e,t){return e?[`${t}${n}:${u.reset} ${e}`,""]:[]}function Ot(n){return n.assistantMessage?["","---","",`${u.bright}${u.magenta}Previously${u.reset}`,"",`${u.dim}A: ${n.assistantMessage}${u.reset}`,""]:[]}function ht(n,e){let t=Math.round(n/1e3);return["",`${u.dim}Access ${t}k tokens of past research & decisions for just ${e.toLocaleString()}t. Use the claude-mem skill to access memories by ID.${u.reset}`]}function At(n){return`
967
- ${u.bright}${u.cyan}[${n}] recent context, ${Et()}${u.reset}
968
- ${u.gray}${"\u2500".repeat(60)}${u.reset}
811
+ No previous sessions found.`}function as(){let n=new Date,e=n.toLocaleDateString("en-CA"),s=n.toLocaleTimeString("en-US",{hour:"numeric",minute:"2-digit",hour12:!0}).toLowerCase().replace(" ",""),t=n.toLocaleTimeString("en-US",{timeZoneName:"short"}).split(" ").pop();return`${e} ${s} ${t}`}function ds(n){return["",`${E.bright}${E.cyan}[${n}] recent context, ${as()}${E.reset}`,`${E.gray}${"\u2500".repeat(60)}${E.reset}`,""]}function _s(){let e=D.getInstance().getActiveMode().observation_types.map(s=>`${s.emoji} ${s.id}`).join(" | ");return[`${E.dim}Legend: session-request | ${e}${E.reset}`,""]}function Es(){return[`${E.bright}Column Key${E.reset}`,`${E.dim} Read: Tokens to read this observation (cost to learn it now)${E.reset}`,`${E.dim} Work: Tokens spent on work that produced this record ( research, building, deciding)${E.reset}`,""]}function us(){return[`${E.dim}Context Index: This semantic index (titles, types, files, tokens) is usually sufficient to understand past work.${E.reset}`,"",`${E.dim}When you need implementation details, rationale, or debugging context:${E.reset}`,`${E.dim} - Fetch by ID: get_observations([IDs]) for observations visible in this index${E.reset}`,`${E.dim} - Search history: Use the mem-search skill for past decisions, bugs, and deeper research${E.reset}`,`${E.dim} - Trust this index over re-reading code for past decisions and learnings${E.reset}`,""]}function ms(n,e){let s=[];if(s.push(`${E.bright}${E.cyan}Context Economics${E.reset}`),s.push(`${E.dim} Loading: ${n.totalObservations} observations (${n.totalReadTokens.toLocaleString()} tokens to read)${E.reset}`),s.push(`${E.dim} Work investment: ${n.totalDiscoveryTokens.toLocaleString()} tokens spent on research, building, and decisions${E.reset}`),n.totalDiscoveryTokens>0&&(e.showSavingsAmount||e.showSavingsPercent)){let t=" Your savings: ";e.showSavingsAmount&&e.showSavingsPercent?t+=`${n.savings.toLocaleString()} tokens (${n.savingsPercent}% reduction from reuse)`:e.showSavingsAmount?t+=`${n.savings.toLocaleString()} tokens`:t+=`${n.savingsPercent}% reduction from reuse`,s.push(`${E.green}${t}${E.reset}`)}return s.push(""),s}function ps(n){return[`${E.bright}${E.cyan}${n}${E.reset}`,""]}function cs(n){return[`${E.dim}${n}${E.reset}`]}function ls(n,e,s,t){let r=n.title||"Untitled",o=D.getInstance().getTypeIcon(n.type),{readTokens:i,discoveryTokens:a,workEmoji:d}=$(n,t),u=s?`${E.dim}${e}${E.reset}`:" ".repeat(e.length),m=t.showReadTokens&&i>0?`${E.dim}(~${i}t)${E.reset}`:"",l=t.showWorkTokens&&a>0?`${E.dim}(${d} ${a.toLocaleString()}t)${E.reset}`:"";return` ${E.dim}#${n.id}${E.reset} ${u} ${o} ${r} ${m} ${l}`}function Ts(n,e,s,t,r){let o=[],i=n.title||"Untitled",a=D.getInstance().getTypeIcon(n.type),{readTokens:d,discoveryTokens:u,workEmoji:m}=$(n,r),l=s?`${E.dim}${e}${E.reset}`:" ".repeat(e.length),c=r.showReadTokens&&d>0?`${E.dim}(~${d}t)${E.reset}`:"",T=r.showWorkTokens&&u>0?`${E.dim}(${m} ${u.toLocaleString()}t)${E.reset}`:"";return o.push(` ${E.dim}#${n.id}${E.reset} ${l} ${a} ${E.bright}${i}${E.reset}`),t&&o.push(` ${E.dim}${t}${E.reset}`),(c||T)&&o.push(` ${c} ${T}`),o.push(""),o}function gs(n,e){let s=`${n.request||"Session started"} (${e})`;return[`${E.yellow}#S${n.id}${E.reset} ${s}`,""]}function H(n,e,s){return e?[`${s}${n}:${E.reset} ${e}`,""]:[]}function Ss(n){return n.assistantMessage?["","---","",`${E.bright}${E.magenta}Previously${E.reset}`,"",`${E.dim}A: ${n.assistantMessage}${E.reset}`,""]:[]}function fs(n,e){let s=Math.round(n/1e3);return["",`${E.dim}Access ${s}k tokens of past research & decisions for just ${e.toLocaleString()}t. Use the claude-mem skill to access memories by ID.${E.reset}`]}function Rs(n){return`
812
+ ${E.bright}${E.cyan}[${n}] recent context, ${as()}${E.reset}
813
+ ${E.gray}${"\u2500".repeat(60)}${E.reset}
969
814
 
970
- ${u.dim}No previous sessions found for this project yet.${u.reset}
971
- `}function It(n,e,t,s){let r=[];return s?r.push(...mt(n)):r.push(...et(n)),s?r.push(...pt()):r.push(...tt()),s&&(r.push(...ct()),r.push(...lt())),J(t)&&(s?r.push(...Tt(e,t)):r.push(...st(e,t))),r}var le=k(require("path"),1);function ee(n){if(!n)return[];try{let e=JSON.parse(n);return Array.isArray(e)?e:[]}catch(e){return E.debug("PARSER","Failed to parse JSON array, using empty fallback",{preview:n?.substring(0,50)},e instanceof Error?e:new Error(String(e))),[]}}function Te(n){return new Date(n).toLocaleString("en-US",{month:"short",day:"numeric",hour:"numeric",minute:"2-digit",hour12:!0})}function ge(n){return new Date(n).toLocaleString("en-US",{hour:"numeric",minute:"2-digit",hour12:!0})}function Ct(n){return new Date(n).toLocaleString("en-US",{month:"short",day:"numeric",year:"numeric"})}function Nt(n,e){return le.default.isAbsolute(n)?le.default.relative(e,n):n}function Lt(n,e,t){let s=ee(n);if(s.length>0)return Nt(s[0],e);if(t){let r=ee(t);if(r.length>0)return Nt(r[0],e)}return"General"}function ls(n){let e=new Map;for(let s of n){let r=s.type==="observation"?s.data.created_at:s.data.displayTime,o=Ct(r);e.has(o)||e.set(o,[]),e.get(o).push(s)}let t=Array.from(e.entries()).sort((s,r)=>{let o=new Date(s[0]).getTime(),i=new Date(r[0]).getTime();return o-i});return new Map(t)}function Dt(n,e){return e.fullObservationField==="narrative"?n.narrative:n.facts?ee(n.facts).join(`
972
- `):null}function Ts(n,e,t,s){let r=[];r.push(...rt(n));let o="";for(let i of e)if(i.type==="summary"){let a=i.data,d=Te(a.displayTime);r.push(...at(a,d))}else{let a=i.data,d=ge(a.created_at),m=d!==o?d:"";if(o=d,t.has(a.id)){let p=Dt(a,s);r.push(...it(a,m,p,s))}else r.push(ot(a,m,s))}return r}function gs(n,e,t,s,r){let o=[];o.push(...gt(n));let i=null,a="";for(let d of e)if(d.type==="summary"){i=null,a="";let _=d.data,m=Te(_.displayTime);o.push(...bt(_,m))}else{let _=d.data,m=Lt(_.files_modified,r,_.files_read),l=ge(_.created_at),p=l!==a;a=l;let g=t.has(_.id);if(m!==i&&(o.push(...St(m)),i=m),g){let A=Dt(_,s);o.push(...Rt(_,l,p,A,s))}else o.push(ft(_,l,p,s))}return o.push(""),o}function Ss(n,e,t,s,r,o){return o?gs(n,e,t,s,r):Ts(n,e,t,s)}function Mt(n,e,t,s,r){let o=[],i=ls(n);for(let[a,d]of i)o.push(...Ss(a,d,e,t,s,r));return o}function vt(n,e,t){return!(!n.showLastSummary||!e||!!!(e.investigated||e.learned||e.completed||e.next_steps)||t&&e.created_at_epoch<=t.created_at_epoch)}function yt(n,e){let t=[];return e?(t.push(...G("Investigated",n.investigated,u.blue)),t.push(...G("Learned",n.learned,u.yellow)),t.push(...G("Completed",n.completed,u.green)),t.push(...G("Next Steps",n.next_steps,u.magenta))):(t.push(...X("Investigated",n.investigated)),t.push(...X("Learned",n.learned)),t.push(...X("Completed",n.completed)),t.push(...X("Next Steps",n.next_steps))),t}function Ut(n,e){return e?Ot(n):dt(n)}function xt(n,e,t){return!J(e)||n.totalDiscoveryTokens<=0||n.savings<=0?[]:t?ht(n.totalDiscoveryTokens,n.totalReadTokens):_t(n.totalDiscoveryTokens,n.totalReadTokens)}var fs=kt.default.join((0,Ft.homedir)(),".claude","plugins","marketplaces","thedotmack","plugin",".install-version");function Rs(){try{return new W}catch(n){if(n instanceof Error&&n.code==="ERR_DLOPEN_FAILED"){try{(0,wt.unlinkSync)(fs)}catch(e){e instanceof Error?E.debug("WORKER","Marker file cleanup failed (may not exist)",{},e):E.debug("WORKER","Marker file cleanup failed (may not exist)",{error:String(e)})}return E.error("WORKER","Native module rebuild needed - restart Claude Code to auto-fix"),null}throw n}}function bs(n,e){return e?At(n):ut(n)}function Os(n,e,t,s,r,o,i){let a=[],d=ce(e);a.push(...It(n,d,s,i));let _=t.slice(0,s.sessionCount),m=Je(_,t),l=Qe(e,m),p=ze(e,s.fullObservationCount);a.push(...Mt(l,p,s,r,i));let g=t[0],A=e[0];vt(s,g,A)&&a.push(...yt(g,i));let h=Ke(e,s,o,r);return a.push(...Ut(h,i)),a.push(...xt(d,s,i)),a.join(`
973
- `).trimEnd()}var hs=new Set(["bugfix","discovery","decision","refactor"]);function As(n,e,t){let s=ce(n),r={bugfix:0,discovery:0,decision:0,refactor:0,other:0},o=new Set,i=Number.POSITIVE_INFINITY;for(let d of n){let _=hs.has(d.type)?d.type:"other";r[_]++,d.memory_session_id&&o.add(d.memory_session_id),d.created_at_epoch&&d.created_at_epoch<i&&(i=d.created_at_epoch)}let a=Number.isFinite(i)?Math.max(0,Math.floor((Date.now()-i)/864e5)):0;return{observation_count:n.length,session_count:o.size,timeline_depth_days:a,has_session_summary:e.length>0,obs_type_bugfix:r.bugfix,obs_type_discovery:r.discovery,obs_type_decision:r.decision,obs_type_refactor:r.refactor,obs_type_other:r.other,tokens_injected:s.totalReadTokens,tokens_saved_vs_naive:s.savings,search_strategy:t?"full":"timeline"}}async function Se(n,e=!1){let t=Xe(),s=n?.cwd??process.cwd(),r=$e(s),o=n?.projects?.length?n.projects:r.allProjects,i=o[o.length-1]??r.primary;n?.full&&(t.totalObservationCount=999999,t.sessionCount=999999);let a=Rs();if(!a)return{text:"",stats:null};try{let d=n?.platformSource?N(n.platformSource):void 0,_=o.length>1?Ye(a,o,t,d):We(a,i,t,d),m=o.length>1?qe(a,o,t,d):Ve(a,i,t,d);return _.length===0&&m.length===0?{text:bs(i,e),stats:null}:{text:Os(i,_,m,t,s,n?.session_id,e),stats:As(_,m,!!n?.full)}}finally{a.close()}}async function Pt(n,e=!1){return(await Se(n,e)).text}0&&(module.exports={generateContext,generateContextWithStats});
815
+ ${E.dim}No previous sessions found for this project yet.${E.reset}
816
+ `}function Os(n,e,s,t){let r=[];return t?r.push(...ds(n)):r.push(...Je(n)),t?r.push(..._s()):r.push(...Qe()),t&&(r.push(...Es()),r.push(...us())),q(s)&&(t?r.push(...ms(e,s)):r.push(...ze(e,s))),r}var me=x(require("path"),1);function Z(n){if(!n)return[];try{let e=JSON.parse(n);return Array.isArray(e)?e:[]}catch(e){return _.debug("PARSER","Failed to parse JSON array, using empty fallback",{preview:n?.substring(0,50)},e instanceof Error?e:new Error(String(e))),[]}}function pe(n){return new Date(n).toLocaleString("en-US",{month:"short",day:"numeric",hour:"numeric",minute:"2-digit",hour12:!0})}function ce(n){return new Date(n).toLocaleString("en-US",{hour:"numeric",minute:"2-digit",hour12:!0})}function hs(n){return new Date(n).toLocaleString("en-US",{month:"short",day:"numeric",year:"numeric"})}function bs(n,e){return me.default.isAbsolute(n)?me.default.relative(e,n):n}function Ns(n,e,s){let t=Z(n);if(t.length>0)return bs(t[0],e);if(s){let r=Z(s);if(r.length>0)return bs(r[0],e)}return"General"}function it(n){let e=new Map;for(let t of n){let r=t.type==="observation"?t.data.created_at:t.data.displayTime,o=hs(r);e.has(o)||e.set(o,[]),e.get(o).push(t)}let s=Array.from(e.entries()).sort((t,r)=>{let o=new Date(t[0]).getTime(),i=new Date(r[0]).getTime();return o-i});return new Map(s)}function Is(n,e){return e.fullObservationField==="narrative"?n.narrative:n.facts?Z(n.facts).join(`
817
+ `):null}function at(n,e,s,t){let r=[];r.push(...Ze(n));let o="";for(let i of e)if(i.type==="summary"){let a=i.data,d=pe(a.displayTime);r.push(...rs(a,d))}else{let a=i.data,d=ce(a.created_at),m=d!==o?d:"";if(o=d,s.has(a.id)){let c=Is(a,t);r.push(...ts(a,m,c,t))}else r.push(ss(a,m,t))}return r}function dt(n,e,s,t,r){let o=[];o.push(...ps(n));let i=null,a="";for(let d of e)if(d.type==="summary"){i=null,a="";let u=d.data,m=pe(u.displayTime);o.push(...gs(u,m))}else{let u=d.data,m=Ns(u.files_modified,r,u.files_read),l=ce(u.created_at),c=l!==a;a=l;let T=s.has(u.id);if(m!==i&&(o.push(...cs(m)),i=m),T){let h=Is(u,t);o.push(...Ts(u,l,c,h,t))}else o.push(ls(u,l,c,t))}return o.push(""),o}function _t(n,e,s,t,r,o){return o?dt(n,e,s,t,r):at(n,e,s,t)}function As(n,e,s,t,r){let o=[],i=it(n);for(let[a,d]of i)o.push(..._t(a,d,e,s,t,r));return o}function Cs(n,e,s){return!(!n.showLastSummary||!e||!!!(e.investigated||e.learned||e.completed||e.next_steps)||s&&e.created_at_epoch<=s.created_at_epoch)}function Ls(n,e){let s=[];return e?(s.push(...H("Investigated",n.investigated,E.blue)),s.push(...H("Learned",n.learned,E.yellow)),s.push(...H("Completed",n.completed,E.green)),s.push(...H("Next Steps",n.next_steps,E.magenta))):(s.push(...X("Investigated",n.investigated)),s.push(...X("Learned",n.learned)),s.push(...X("Completed",n.completed)),s.push(...X("Next Steps",n.next_steps))),s}function Ds(n,e){return e?Ss(n):ns(n)}function Ms(n,e,s){return!q(e)||n.totalDiscoveryTokens<=0||n.savings<=0?[]:s?fs(n.totalDiscoveryTokens,n.totalReadTokens):os(n.totalDiscoveryTokens,n.totalReadTokens)}var Et=vs.default.join((0,ys.homedir)(),".claude","plugins","marketplaces","thedotmack","plugin",".install-version");function ut(){try{return new j}catch(n){if(n instanceof Error&&n.code==="ERR_DLOPEN_FAILED"){try{(0,Us.unlinkSync)(Et)}catch(e){e instanceof Error?_.debug("WORKER","Marker file cleanup failed (may not exist)",{},e):_.debug("WORKER","Marker file cleanup failed (may not exist)",{error:String(e)})}return _.error("WORKER","Native module rebuild needed - restart Claude Code to auto-fix"),null}throw n}}function mt(n,e){return e?Rs(n):is(n)}function pt(n,e,s,t,r,o,i){let a=[],d=ue(e);a.push(...Os(n,d,t,i));let u=s.slice(0,t.sessionCount),m=Ve(u,s),l=Ke(e,m),c=Ye(e,t.fullObservationCount);a.push(...As(l,c,t,r,i));let T=s[0],h=e[0];Cs(t,T,h)&&a.push(...Ls(T,i));let b=We(e,t,o,r);return a.push(...Ds(b,i)),a.push(...Ms(d,t,i)),a.join(`
818
+ `).trimEnd()}var ct=new Set(["bugfix","discovery","decision","refactor"]);function lt(n,e,s){let t=ue(n),r={bugfix:0,discovery:0,decision:0,refactor:0,other:0},o=new Set,i=Number.POSITIVE_INFINITY;for(let d of n){let u=ct.has(d.type)?d.type:"other";r[u]++,d.memory_session_id&&o.add(d.memory_session_id),d.created_at_epoch&&d.created_at_epoch<i&&(i=d.created_at_epoch)}let a=Number.isFinite(i)?Math.max(0,Math.floor((Date.now()-i)/864e5)):0;return{observation_count:n.length,session_count:o.size,timeline_depth_days:a,has_session_summary:e.length>0,obs_type_bugfix:r.bugfix,obs_type_discovery:r.discovery,obs_type_decision:r.decision,obs_type_refactor:r.refactor,obs_type_other:r.other,tokens_injected:t.totalReadTokens,tokens_saved_vs_naive:t.savings,search_strategy:s?"full":"timeline"}}async function le(n,e=!1){let s=Pe(),t=n?.cwd??process.cwd(),r=we(t),o=n?.projects?.length?n.projects:r.allProjects,i=o[o.length-1]??r.primary;n?.full&&(s.totalObservationCount=999999,s.sessionCount=999999);let a=ut();if(!a)return{text:"",stats:null};try{let d=n?.platformSource?A(n.platformSource):void 0,u=o.length>1?o:[i],m=Be(a,u,s,d),l=je(a,u,s,d);return m.length===0&&l.length===0?{text:mt(i,e),stats:null}:{text:pt(i,m,l,s,t,n?.session_id,e),stats:lt(m,l,!!n?.full)}}finally{a.close()}}async function xs(n,e=!1){return(await le(n,e)).text}0&&(module.exports={generateContext,generateContextWithStats});