claude-mem 13.34.2 → 13.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.codex-plugin/plugin.json +1 -1
  4. package/.qoder-plugin/plugin.json +15 -0
  5. package/README.md +5 -16
  6. package/dist/bug-report/index.js +68 -68
  7. package/dist/npx-cli/index.js +371 -336
  8. package/dist/opencode-plugin/index.js +43 -41
  9. package/dsh/package.json +1 -1
  10. package/openclaw/openclaw.plugin.json +1 -1
  11. package/package.json +4 -1
  12. package/plugin/.claude-plugin/plugin.json +1 -1
  13. package/plugin/.codex-plugin/plugin.json +1 -1
  14. package/plugin/.qoder-plugin/plugin.json +15 -0
  15. package/plugin/hooks/codex-hooks.json +1 -1
  16. package/plugin/hooks/hooks.json +1 -1
  17. package/plugin/hooks/qoder-hooks.json +97 -0
  18. package/plugin/hooks/qoder-repo-hooks.json +97 -0
  19. package/plugin/package.json +1 -1
  20. package/plugin/qoder.mcp.json +12 -0
  21. package/plugin/scripts/bun-runner.js +24 -5
  22. package/plugin/scripts/context-generator.cjs +59 -58
  23. package/plugin/scripts/context-generator.cjs.map +2 -2
  24. package/plugin/scripts/mcp-server.cjs +101 -57
  25. package/plugin/scripts/mcp-server.cjs.map +3 -3
  26. package/plugin/scripts/qoder-hook-launcher.cjs +114 -0
  27. package/plugin/scripts/server-service.cjs +197 -162
  28. package/plugin/scripts/server-service.cjs.map +3 -3
  29. package/plugin/scripts/transcript-watcher.cjs +27 -28
  30. package/plugin/scripts/transcript-watcher.cjs.map +3 -3
  31. package/plugin/scripts/worker-service.cjs +605 -534
  32. package/plugin/scripts/worker-service.cjs.map +3 -3
  33. package/plugin/skills/mem-search/SKILL.md +81 -128
  34. package/plugin/skills/screenpipe/SKILL.md +80 -0
  35. package/plugin/skills/screenpipe/screenpipe.mjs +157 -0
  36. package/plugin/sqlite/SessionStore.js +181 -176
  37. package/plugin/sqlite/SessionStore.js.map +3 -3
  38. package/plugin/sqlite/observations/files.js +7 -7
  39. package/plugin/sqlite/observations/files.js.map +2 -2
  40. package/plugin/ui/viewer-bundle.js +12 -12
@@ -1,18 +1,18 @@
1
1
  var __CM_FILENAME__ = typeof __filename !== "undefined" ? __filename : require("node:path").resolve(process.argv[1] || "");
2
2
  var __CM_DIRNAME__ = typeof __dirname !== "undefined" ? __dirname : require("node:path").dirname(__CM_FILENAME__);
3
3
  var __IMPORT_META_URL__ = require("node:url").pathToFileURL(__CM_FILENAME__).href;
4
- "use strict";var Ce=Object.defineProperty;var ns=Object.getOwnPropertyDescriptor;var rs=Object.getOwnPropertyNames;var os=Object.prototype.hasOwnProperty;var is=(r,e)=>{for(var t in e)Ce(r,t,{get:e[t],enumerable:!0})},as=(r,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of rs(e))!os.call(r,n)&&n!==t&&Ce(r,n,{get:()=>e[n],enumerable:!(s=ns(e,n))||s.enumerable});return r};var _s=r=>as(Ce({},"__esModule",{value:!0}),r);var En={};is(En,{SessionStore:()=>qe,TELEGRAM_WRAPUP_CLAIM_STALE_AFTER_MS:()=>ts,rollupObservationFileLists:()=>ss});module.exports=_s(En);var Es=new Set;function $(r,e,t="additive"){for(let s of Es)s({scope:r,reason:e,kind:t})}var Ve=require("bun:sqlite"),Ne=require("crypto");var h=require("path"),he=require("os"),ae=require("fs"),tt=require("url");var C=require("fs"),Je=require("crypto"),F=require("path");var ds=null;function cs(r){return(ds??process.stderr.write.bind(process.stderr))(r)}function W(r){cs(r)}var un=Promise.resolve();var us=process.platform==="win32";function Le(r){return r.replace(/^\uFEFF/,"")}function Ie(r){return JSON.parse(Le(r))}function z(r){return Ie((0,C.readFileSync)(r,"utf-8"))}function ls(r){(0,C.existsSync)(r)||(0,C.mkdirSync)(r,{recursive:!0})}function P(r,e,t={}){let s=r;try{if((0,C.lstatSync)(r).isSymbolicLink())try{s=(0,C.realpathSync)(r)}catch(c){let d=c instanceof Error?c:new Error(String(c));W(`claude-mem: realpathSync failed for ${r}, resolving symlink manually: ${d.message}
5
- `);let l=(0,C.readlinkSync)(r);s=(0,F.resolve)((0,F.dirname)(r),l)}}catch(c){let d=c.code;if(d!=="ENOENT"&&d!=="ENOTDIR")throw c}ls((0,F.dirname)(s));let n=(0,F.dirname)(s),i=(0,F.basename)(s),o=(0,F.join)(n,`.${i}.${process.pid}.${(0,Je.randomBytes)(6).toString("hex")}.tmp`),a=Buffer.from(JSON.stringify(e,null,2)+`
6
- `,"utf-8"),_=t.mode;if(_===void 0)try{_=(0,C.statSync)(s).mode&511}catch{}let E;try{E=_!==void 0?(0,C.openSync)(o,"w",_):(0,C.openSync)(o,"w");let c=0;for(;c<a.length;){let d=(0,C.writeSync)(E,a,c,a.length-c);if(d===0)throw new Error(`writeSync stalled at ${c}/${a.length} bytes`);c+=d}if((0,C.fsyncSync)(E),(0,C.closeSync)(E),E=void 0,(0,C.renameSync)(o,s),!us){let d;try{d=(0,C.openSync)(n,"r"),(0,C.fsyncSync)(d)}catch(l){let O=l instanceof Error?l:new Error(String(l));W(`claude-mem: directory fsync failed for ${n}: ${O.message}
7
- `)}finally{if(d!==void 0)try{(0,C.closeSync)(d)}catch{}}}}catch(c){if(E!==void 0)try{(0,C.closeSync)(E)}catch{}try{(0,C.unlinkSync)(o)}catch{}throw c}}var ps=r=>r!==null&&typeof r=="object"&&!Array.isArray(r);function ze(r){let e=r.env;return ps(e)&&Object.keys(e).some(t=>t.startsWith("CLAUDE_MEM_"))?"nested":"flat"}function K(r){return ze(r)==="nested"?r.env:r}function Qe(r){return ze(r)!=="nested"?r:Object.fromEntries(Object.entries(r).filter(([e])=>!e.startsWith("CLAUDE_MEM_")))}var Ze=require("os"),et=require("path");function ie(r,e=process.platform,t=(0,Ze.homedir)()){return typeof r!="string"||r.length===0?r:r==="~"?t:r.startsWith("~/")||e==="win32"&&r.startsWith("~\\")?(0,et.join)(t,r.slice(2)):r}function ms(){return typeof __CM_DIRNAME__<"u"?__CM_DIRNAME__:(0,h.dirname)((0,tt.fileURLToPath)(__IMPORT_META_URL__))}var bn=ms();function Ts(){if(process.env.CLAUDE_MEM_DATA_DIR)return ie(process.env.CLAUDE_MEM_DATA_DIR);let r=(0,h.join)((0,he.homedir)(),".claude-mem"),e=(0,h.join)(r,"settings.json");try{if((0,ae.existsSync)(e)){let t=z(e);if(t===null||typeof t!="object"||Array.isArray(t))return r;let s=K(t);if(typeof s.CLAUDE_MEM_DATA_DIR=="string"&&s.CLAUDE_MEM_DATA_DIR)return ie(s.CLAUDE_MEM_DATA_DIR)}}catch{}return r}var M=Ts(),Ss=(0,h.join)((0,he.homedir)(),".claude"),As=process.env.CLAUDE_CONFIG_DIR||Ss,Cn=(0,h.join)(As,"plugins","marketplaces","thedotmack"),Os=(0,h.join)(M,"logs"),_e=(0,h.join)(M,"settings.json"),st="claude-mem.db";var Ee=(0,h.join)(M,st),gs=(0,h.join)(M,"observer-sessions"),Q=(0,h.basename)(gs);function de(r){(0,ae.mkdirSync)(r,{recursive:!0})}var De={dataDir:()=>M,workerPid:()=>(0,h.join)(M,"worker.pid"),serverPid:()=>(0,h.join)(M,".server-beta.pid"),serverPort:()=>(0,h.join)(M,".server-beta.port"),serverRuntime:()=>(0,h.join)(M,".server-beta.runtime.json"),settings:()=>(0,h.join)(M,"settings.json"),database:()=>(0,h.join)(M,st),chroma:()=>(0,h.join)(M,"chroma"),combinedCerts:()=>(0,h.join)(M,"combined_certs.pem"),transcriptsConfig:()=>(0,h.join)(M,"transcript-watch.json"),transcriptsState:()=>(0,h.join)(M,"transcript-watch-state.json"),corpora:()=>(0,h.join)(M,"corpora"),supervisorRegistry:()=>(0,h.join)(M,"supervisor.json"),envFile:()=>(0,h.join)(M,".env"),logsDir:()=>Os};var X=require("fs"),nt=require("path");var Ue=(i=>(i[i.DEBUG=0]="DEBUG",i[i.INFO=1]="INFO",i[i.WARN=2]="WARN",i[i.ERROR=3]="ERROR",i[i.SILENT=4]="SILENT",i))(Ue||{}),Me=null,ye=class{level=null;useColor;logFilePath=null;logFileInitialized=!1;logFileDate=null;constructor(){this.useColor=process.stdout.isTTY??!1}ensureLogFileInitialized(){let e=new Date().toISOString().split("T")[0];if(!(this.logFileInitialized&&this.logFileDate===e)){this.logFileInitialized=!0,this.logFileDate=e;try{let t=De.logsDir();(0,X.existsSync)(t)||(0,X.mkdirSync)(t,{recursive:!0}),this.logFilePath=(0,nt.join)(t,`claude-mem-${e}.log`)}catch(t){console.error("[LOGGER] Failed to initialize log file:",t instanceof Error?t.message:String(t)),this.logFilePath=null}}}getLevel(){if(this.level===null)try{let e=De.settings();if((0,X.existsSync)(e)){let s=(K(z(e)).CLAUDE_MEM_LOG_LEVEL||"INFO").toString().toUpperCase();this.level=Ue[s]??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}safeStringify(e,t,s=6){let n=new WeakSet,i=(o,a)=>{if(typeof o=="bigint")return`${o}n`;if(o===null||typeof o!="object")return o;let _=o.toJSON,E=typeof _=="function"?_.call(o):o;if(typeof E=="bigint")return`${E}n`;if(E===null||typeof E!="object")return E;if(n.has(E))return"[Circular]";if(a>=s)return Array.isArray(E)?"[Array]":"[Object]";n.add(E);try{if(Array.isArray(E))return E.map(d=>i(d,a+1));let c={};for(let d of Object.keys(E))try{c[d]=i(E[d],a+1)}catch{c[d]="[unreadable]"}return c}finally{n.delete(E)}};try{return JSON.stringify(i(e,0),null,t)??String(e)}catch{return Array.isArray(e)?`[${e.length} items]`:"[unserializable]"}}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}
8
- ${e.stack}`:e.message;if(Array.isArray(e))return`[${e.length} items]`;let t=Object.keys(e);return t.length===0?"{}":t.length<=3?this.safeStringify(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"),n=String(e.getDate()).padStart(2,"0"),i=String(e.getHours()).padStart(2,"0"),o=String(e.getMinutes()).padStart(2,"0"),a=String(e.getSeconds()).padStart(2,"0"),_=String(e.getMilliseconds()).padStart(3,"0");return`${t}-${s}-${n} ${i}:${o}:${a}.${_}`}log(e,t,s,n,i){if(e<this.getLevel())return;this.ensureLogFileInitialized();let o=this.formatTimestamp(new Date),a=Ue[e].padEnd(5),_=t.padEnd(6),E="";n?.correlationId?E=`[${n.correlationId}] `:n?.sessionId&&(E=`[session-${n.sessionId}] `);let c="";i!=null&&(i instanceof Error?c=this.getLevel()===0?`
4
+ "use strict";var Me=Object.defineProperty;var us=Object.getOwnPropertyDescriptor;var ls=Object.getOwnPropertyNames;var ps=Object.prototype.hasOwnProperty;var ms=(o,e)=>{for(var t in e)Me(o,t,{get:e[t],enumerable:!0})},Ts=(o,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of ls(e))!ps.call(o,n)&&n!==t&&Me(o,n,{get:()=>e[n],enumerable:!(s=us(e,n))||s.enumerable});return o};var Ss=o=>Ts(Me({},"__esModule",{value:!0}),o);var On={};ms(On,{SessionStore:()=>tt,TELEGRAM_WRAPUP_CLAIM_STALE_AFTER_MS:()=>ds,rollupObservationFileLists:()=>cs});module.exports=Ss(On);var As=new Set;function j(o,e,t="additive"){for(let s of As)s({scope:o,reason:e,kind:t})}var et=require("bun:sqlite"),he=require("crypto");var I=require("path"),ve=require("os"),le=require("fs"),at=require("url");var L=require("fs"),st=require("crypto"),F=require("path");var gs=null;function Os(o){return(gs??process.stderr.write.bind(process.stderr))(o)}function W(o){Os(o)}var Nn=Promise.resolve();var fs=process.platform==="win32";function Ue(o){return o.replace(/^\uFEFF/,"")}function ye(o){return JSON.parse(Ue(o))}function Z(o){return ye((0,L.readFileSync)(o,"utf-8"))}function Rs(o){(0,L.existsSync)(o)||(0,L.mkdirSync)(o,{recursive:!0})}function P(o,e,t={}){let s=o,n=new Set;try{for(;(0,L.lstatSync)(s).isSymbolicLink();){let u=(0,F.resolve)(s);if(n.has(u))throw Object.assign(new Error(`Symlink loop at ${s}`),{code:"ELOOP"});n.add(u);try{s=(0,L.realpathSync)(s);break}catch(l){if(l.code!=="ENOENT")throw l;let p=l instanceof Error?l:new Error(String(l));W(`claude-mem: realpathSync failed for ${s}, resolving symlink manually: ${p.message}
5
+ `);let S=(0,L.readlinkSync)(s);s=(0,F.resolve)((0,F.dirname)(s),S)}}}catch(u){if(u.code!=="ENOENT")throw u}Rs((0,F.dirname)(s));let i=(0,F.dirname)(s),r=(0,F.basename)(s),a=(0,F.join)(i,`.${r}.${process.pid}.${(0,st.randomBytes)(6).toString("hex")}.tmp`),_=Buffer.from(JSON.stringify(e,null,2)+`
6
+ `,"utf-8"),E=t.mode;if(E===void 0)try{E=(0,L.statSync)(s).mode&511}catch{}let d;try{d=E!==void 0?(0,L.openSync)(a,"w",E):(0,L.openSync)(a,"w");let u=0;for(;u<_.length;){let l=(0,L.writeSync)(d,_,u,_.length-u);if(l===0)throw new Error(`writeSync stalled at ${u}/${_.length} bytes`);u+=l}if((0,L.fsyncSync)(d),(0,L.closeSync)(d),d=void 0,(0,L.renameSync)(a,s),!fs){let l;try{l=(0,L.openSync)(i,"r"),(0,L.fsyncSync)(l)}catch(p){let S=p instanceof Error?p:new Error(String(p));W(`claude-mem: directory fsync failed for ${i}: ${S.message}
7
+ `)}finally{if(l!==void 0)try{(0,L.closeSync)(l)}catch{}}}}catch(u){if(d!==void 0)try{(0,L.closeSync)(d)}catch{}try{(0,L.unlinkSync)(a)}catch{}throw u}}var Ns=o=>o!==null&&typeof o=="object"&&!Array.isArray(o);function nt(o){let e=o.env;return Ns(e)&&Object.keys(e).some(t=>t.startsWith("CLAUDE_MEM_"))?"nested":"flat"}function K(o){return nt(o)==="nested"?o.env:o}function rt(o){return nt(o)!=="nested"?o:Object.fromEntries(Object.entries(o).filter(([e])=>!e.startsWith("CLAUDE_MEM_")))}var ot=require("os"),it=require("path");function ue(o,e=process.platform,t=(0,ot.homedir)()){return typeof o!="string"||o.length===0?o:o==="~"?t:o.startsWith("~/")||e==="win32"&&o.startsWith("~\\")?(0,it.join)(t,o.slice(2)):o}function bs(){return typeof __CM_DIRNAME__<"u"?__CM_DIRNAME__:(0,I.dirname)((0,at.fileURLToPath)(__IMPORT_META_URL__))}var wn=bs();function Cs(){if(process.env.CLAUDE_MEM_DATA_DIR)return ue(process.env.CLAUDE_MEM_DATA_DIR);let o=(0,I.join)((0,ve.homedir)(),".claude-mem"),e=(0,I.join)(o,"settings.json");try{if((0,le.existsSync)(e)){let t=Z(e);if(t===null||typeof t!="object"||Array.isArray(t))return o;let s=K(t);if(typeof s.CLAUDE_MEM_DATA_DIR=="string"&&s.CLAUDE_MEM_DATA_DIR)return ue(s.CLAUDE_MEM_DATA_DIR)}}catch{}return o}var M=Cs(),Ls=(0,I.join)((0,ve.homedir)(),".claude"),Is=process.env.CLAUDE_CONFIG_DIR||Ls,Pn=(0,I.join)(Is,"plugins","marketplaces","thedotmack"),hs=(0,I.join)(M,"logs"),pe=(0,I.join)(M,"settings.json"),_t="claude-mem.db";var me=(0,I.join)(M,_t),Ds=(0,I.join)(M,"observer-sessions"),ee=(0,I.basename)(Ds);function Te(o){(0,le.mkdirSync)(o,{recursive:!0})}var Fe={dataDir:()=>M,workerPid:()=>(0,I.join)(M,"worker.pid"),serverPid:()=>(0,I.join)(M,".server-beta.pid"),serverPort:()=>(0,I.join)(M,".server-beta.port"),serverRuntime:()=>(0,I.join)(M,".server-beta.runtime.json"),settings:()=>(0,I.join)(M,"settings.json"),database:()=>(0,I.join)(M,_t),chroma:()=>(0,I.join)(M,"chroma"),combinedCerts:()=>(0,I.join)(M,"combined_certs.pem"),transcriptsConfig:()=>(0,I.join)(M,"transcript-watch.json"),transcriptsState:()=>(0,I.join)(M,"transcript-watch-state.json"),corpora:()=>(0,I.join)(M,"corpora"),supervisorRegistry:()=>(0,I.join)(M,"supervisor.json"),envFile:()=>(0,I.join)(M,".env"),logsDir:()=>hs};var X=require("fs"),Et=require("path");var Pe=(i=>(i[i.DEBUG=0]="DEBUG",i[i.INFO=1]="INFO",i[i.WARN=2]="WARN",i[i.ERROR=3]="ERROR",i[i.SILENT=4]="SILENT",i))(Pe||{}),we=null,xe=class{level=null;useColor;logFilePath=null;logFileInitialized=!1;logFileDate=null;constructor(){this.useColor=process.stdout.isTTY??!1}ensureLogFileInitialized(){let e=new Date().toISOString().split("T")[0];if(this.logFileInitialized&&this.logFileDate===e)return;let t=this.logFileDate!==e;this.logFileInitialized=!1,this.logFileDate=e;try{let s=Fe.logsDir();(0,X.existsSync)(s)||(0,X.mkdirSync)(s,{recursive:!0}),this.logFilePath=(0,Et.join)(s,`claude-mem-${e}.log`),this.logFileInitialized=!0}catch(s){t&&console.error("[LOGGER] Failed to initialize log file:",s instanceof Error?s.message:String(s)),this.logFilePath=null}}getLevel(){if(this.level===null)try{let e=Fe.settings();if((0,X.existsSync)(e)){let s=(K(Z(e)).CLAUDE_MEM_LOG_LEVEL||"INFO").toString().toUpperCase();this.level=Pe[s]??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}safeStringify(e,t,s=6){let n=new WeakSet,i=(r,a)=>{if(typeof r=="bigint")return`${r}n`;if(r===null||typeof r!="object")return r;let _=r.toJSON,E=typeof _=="function"?_.call(r):r;if(typeof E=="bigint")return`${E}n`;if(E===null||typeof E!="object")return E;if(n.has(E))return"[Circular]";if(a>=s)return Array.isArray(E)?"[Array]":"[Object]";n.add(E);try{if(Array.isArray(E))return E.map(u=>i(u,a+1));let d={};for(let u of Object.keys(E))try{d[u]=i(E[u],a+1)}catch{d[u]="[unreadable]"}return d}finally{n.delete(E)}};try{return JSON.stringify(i(e,0),null,t)??String(e)}catch{return Array.isArray(e)?`[${e.length} items]`:"[unserializable]"}}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}
8
+ ${e.stack}`:e.message;if(Array.isArray(e))return`[${e.length} items]`;let t=Object.keys(e);return t.length===0?"{}":t.length<=3?this.safeStringify(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(s===null)return e;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"),n=String(e.getDate()).padStart(2,"0"),i=String(e.getHours()).padStart(2,"0"),r=String(e.getMinutes()).padStart(2,"0"),a=String(e.getSeconds()).padStart(2,"0"),_=String(e.getMilliseconds()).padStart(3,"0");return`${t}-${s}-${n} ${i}:${r}:${a}.${_}`}log(e,t,s,n,i){if(e<this.getLevel())return;this.ensureLogFileInitialized();let r=this.formatTimestamp(new Date),a=Pe[e].padEnd(5),_=t.padEnd(6),E="";n?.correlationId?E=`[${n.correlationId}] `:n?.sessionId&&(E=`[session-${n.sessionId}] `);let d="";i!=null&&(i instanceof Error?d=this.getLevel()===0?`
9
9
  ${i.message}
10
- ${i.stack}`:` ${i.message}`:this.getLevel()===0&&typeof i=="object"?c=`
11
- `+this.safeStringify(i,2):c=" "+this.formatData(i));let d="";if(n){let{sessionId:O,memorySessionId:L,correlationId:I,...f}=n;Object.keys(f).length>0&&(d=` {${Object.entries(f).map(([m,N])=>typeof N!="object"||N===null||N instanceof Error||N instanceof Date?`${m}=${N}`:`${m}=${Array.isArray(N)?this.safeStringify(N):this.formatData(N)}`).join(", ")}}`)}let l=`[${o}] [${a}] [${_}] ${E}${s}${d}${c}`;if(this.logFilePath)try{(0,X.appendFileSync)(this.logFilePath,l+`
12
- `,"utf8")}catch(O){let L=O instanceof Error?O:new Error(String(O));W(`[LOGGER] Failed to write to log file: ${L.message}
13
- ${L.stack??""}
10
+ ${i.stack}`:` ${i.message}`:this.getLevel()===0&&typeof i=="object"?d=`
11
+ `+this.safeStringify(i,2):d=" "+this.formatData(i));let u="";if(n){let{sessionId:p,memorySessionId:S,correlationId:h,...f}=n;Object.keys(f).length>0&&(u=` {${Object.entries(f).map(([R,m])=>typeof m!="object"||m===null||m instanceof Error||m instanceof Date?`${R}=${m}`:`${R}=${Array.isArray(m)?this.safeStringify(m):this.formatData(m)}`).join(", ")}}`)}let l=`[${r}] [${a}] [${_}] ${E}${s}${u}${d}`;if(this.logFilePath)try{(0,X.appendFileSync)(this.logFilePath,l+`
12
+ `,"utf8")}catch(p){let S=p instanceof Error?p:new Error(String(p));W(`[LOGGER] Failed to write to log file: ${S.message}
13
+ ${S.stack??""}
14
14
  `)}else W(l+`
15
- `)}debug(e,t,s,n){this.log(0,e,t,s,n)}info(e,t,s,n){this.log(1,e,t,s,n)}warn(e,t,s,n){this.log(2,e,t,s,n)}setErrorSink(e){Me=e}error(e,t,s,n){this.log(3,e,t,s,n),this.routeErrorToSink(t,s,n)}routeErrorToSink(e,t,s){try{if(!Me||!(s instanceof Error))return;Me(s)}catch{}}dataIn(e,t,s,n){this.info(e,`\u2192 ${t}`,s,n)}dataOut(e,t,s,n){this.info(e,`\u2190 ${t}`,s,n)}success(e,t,s,n){this.info(e,`\u2713 ${t}`,s,n)}failure(e,t,s,n){this.error(e,`\u2717 ${t}`,s,n)}},u=new ye;function w(r){let e=r.projects?.length?r.projects:r.project?[r.project]:[];return[...new Set(e.map(t=>t.trim()).filter(Boolean))]}function x(r,e,t){let s=e.map(()=>"?").join(",");return t.includeMerged?{sql:`(${r}.project COLLATE NOCASE IN (${s}) OR ${r}.merged_into_project COLLATE NOCASE IN (${s}))`,params:[...e,...e]}:{sql:`${r}.project COLLATE NOCASE IN (${s})`,params:[...e]}}function rt(r,e){let t=w({projects:e});if(t.length===0)return[];let s=t.map(()=>"?").join(","),n=[`SELECT project AS key FROM sdk_sessions WHERE project COLLATE NOCASE IN (${s})`,`SELECT project FROM observations WHERE project COLLATE NOCASE IN (${s})`,`SELECT merged_into_project FROM observations WHERE merged_into_project COLLATE NOCASE IN (${s})`,`SELECT project FROM session_summaries WHERE project COLLATE NOCASE IN (${s})`,`SELECT merged_into_project FROM session_summaries WHERE merged_into_project COLLATE NOCASE IN (${s})`,`SELECT project FROM observations WHERE merged_into_project COLLATE NOCASE IN (${s})`,`SELECT project FROM session_summaries WHERE merged_into_project COLLATE NOCASE IN (${s})`],i=r.prepare(n.join(" UNION ")).all(...n.flatMap(()=>t));return[...new Set([...t,...i.map(o=>o.key)])]}var ot=require("crypto");function ve(r){return typeof r=="string"&&r.trim()!==""}function it(r,e,t){return(0,ot.createHash)("sha256").update([r||"",e||"",t||""].join("\0")).digest("hex").slice(0,16)}function at(r){if(!r)return[];try{let e=JSON.parse(r);return Array.isArray(e)?e.filter(t=>typeof t=="string"&&t.length>0):[]}catch{return[]}}function Fe(r=new Date){return r.toISOString().slice(0,10)}function _t(r,e=new Date,t=10){let s=Fe(e);if(r.includes(s))return r;let n=[...r,s];return n.length>t?n.slice(n.length-t):n}function Et(r){let e=Fe(new Date(r));return{dates:JSON.stringify([e]),lastReinforced:e}}function ce(r,e,t=new Date){let s=r.prepare("SELECT reinforcement_dates FROM observations WHERE id = ?").get(e);if(!s)return!1;let n=at(s.reinforcement_dates),i=_t(n,t);return i===n?!1:(r.prepare("UPDATE observations SET reinforcement_dates = ?, last_reinforced = ? WHERE id = ?").run(JSON.stringify(i),i[i.length-1],e),!0)}var ut=require("crypto");var p="claude";function fs(r){return r.trim().toLowerCase().replace(/\s+/g,"-")}function b(r){if(!r)return p;let e=fs(r);return e?e==="transcript"||e.includes("codex")?"codex":e.includes("cursor")?"cursor":e.includes("claude")?"claude":e.includes("kimi")?"kimi":e==="pi-mono"?"pi":e==="agy"||e==="antigravity"||e.startsWith("antigravity-")?"antigravity-cli":e:p}function dt(r){let e=["claude","codex","antigravity-cli","cursor","kimi"];return[...r].sort((t,s)=>{let n=e.indexOf(t),i=e.indexOf(s);return n!==-1||i!==-1?n===-1?1:i===-1?-1:n-i:t.localeCompare(s)})}var Rs=64*1024,Ns=new Set(["search","timeline","get_observations","get_tool_uses","session_start_context","observation_search"]);function bs(r){if(!r)return!1;if(r.startsWith("memory_"))return!0;if(!r.startsWith("mcp__"))return!1;let e=r.split("__");if(e.length<3)return!1;let t=e[1].toLowerCase(),s=e.slice(2).join("__");return(t.includes("claude-mem")||t.includes("claude_mem")||t.includes("mcp-search")||t.includes("cmem"))&&Ns.has(s)}function ct(r,e=Rs){let t=Buffer.byteLength(r,"utf8");if(t<=e)return r;let s=Buffer.from(r,"utf8"),n=e;for(;n>0&&(s[n]&192)===128;)n--;return`${s.subarray(0,n).toString("utf8")}\u2026[truncated: ${t} bytes]`}function Cs(r,e,t){return(0,ut.createHash)("sha256").update([r||"",e||"",t||""].join("\0")).digest("hex").slice(0,16)}function lt(r){r.run(`
15
+ `)}debug(e,t,s,n){this.log(0,e,t,s,n)}info(e,t,s,n){this.log(1,e,t,s,n)}warn(e,t,s,n){this.log(2,e,t,s,n)}setErrorSink(e){we=e}error(e,t,s,n){this.log(3,e,t,s,n),this.routeErrorToSink(t,s,n)}routeErrorToSink(e,t,s){try{if(!we||!(s instanceof Error))return;we(s)}catch{}}dataIn(e,t,s,n){this.info(e,`\u2192 ${t}`,s,n)}dataOut(e,t,s,n){this.info(e,`\u2190 ${t}`,s,n)}success(e,t,s,n){this.info(e,`\u2713 ${t}`,s,n)}failure(e,t,s,n){this.error(e,`\u2717 ${t}`,s,n)}},c=new xe;function w(o){let e=o.projects?.length?o.projects:o.project?[o.project]:[];return[...new Set(e.map(t=>t.trim()).filter(Boolean))]}function x(o,e,t){let s=e.map(()=>"?").join(",");return t.includeMerged?{sql:`(${o}.project COLLATE NOCASE IN (${s}) OR ${o}.merged_into_project COLLATE NOCASE IN (${s}))`,params:[...e,...e]}:{sql:`${o}.project COLLATE NOCASE IN (${s})`,params:[...e]}}function dt(o,e){let t=w({projects:e});if(t.length===0)return[];let s=t.map(()=>"?").join(","),n=[`SELECT project AS key FROM sdk_sessions WHERE project COLLATE NOCASE IN (${s})`,`SELECT project FROM observations WHERE project COLLATE NOCASE IN (${s})`,`SELECT merged_into_project FROM observations WHERE merged_into_project COLLATE NOCASE IN (${s})`,`SELECT project FROM session_summaries WHERE project COLLATE NOCASE IN (${s})`,`SELECT merged_into_project FROM session_summaries WHERE merged_into_project COLLATE NOCASE IN (${s})`,`SELECT project FROM observations WHERE merged_into_project COLLATE NOCASE IN (${s})`,`SELECT project FROM session_summaries WHERE merged_into_project COLLATE NOCASE IN (${s})`],i=o.prepare(n.join(" UNION "));try{let r=i.all(...n.flatMap(()=>t));return[...new Set([...t,...r.map(a=>a.key)])]}finally{i.finalize()}}var ct=require("crypto");function ke(o){return typeof o=="string"&&o.trim()!==""}function ut(o,e,t){return(0,ct.createHash)("sha256").update([o||"",e||"",t||""].join("\0")).digest("hex").slice(0,16)}function lt(o){if(!o)return[];try{let e=JSON.parse(o);return Array.isArray(e)?e.filter(t=>typeof t=="string"&&t.length>0):[]}catch{return[]}}function Be(o=new Date){return o.toISOString().slice(0,10)}function pt(o,e=new Date,t=10){let s=Be(e);if(o.includes(s))return o;let n=[...o,s];return n.length>t?n.slice(n.length-t):n}function mt(o){let e=Be(new Date(o));return{dates:JSON.stringify([e]),lastReinforced:e}}function Se(o,e,t=new Date){let s=o.prepare("SELECT reinforcement_dates FROM observations WHERE id = ?").get(e);if(!s)return!1;let n=lt(s.reinforcement_dates),i=pt(n,t);return i===n?!1:(o.prepare("UPDATE observations SET reinforcement_dates = ?, last_reinforced = ? WHERE id = ?").run(JSON.stringify(i),i[i.length-1],e),!0)}var At=require("crypto");var T="claude";function Ms(o){return o.trim().toLowerCase().replace(/\s+/g,"-")}function b(o){if(!o)return T;let e=Ms(o);return e?e==="transcript"||e.includes("codex")?"codex":e.includes("cursor")?"cursor":e.includes("claude")?"claude":e.includes("kimi")?"kimi":e==="pi-mono"?"pi":e==="agy"||e==="antigravity"||e.startsWith("antigravity-")?"antigravity-cli":e:T}function Tt(o){let e=["claude","codex","antigravity-cli","cursor","kimi"];return[...o].sort((t,s)=>{let n=e.indexOf(t),i=e.indexOf(s);return n!==-1||i!==-1?n===-1?1:i===-1?-1:n-i:t.localeCompare(s)})}var Us=new Set(["mem_search","search","timeline","get_observations","get_summaries","get_tool_uses","session_start_context","observation_search","observation_context","memory_search","memory_context"]);function ys(o){if(!o.startsWith("mcp__"))return null;let e=o.split("__");if(e.length<3)return null;let t=e[1].toLowerCase();return!t.includes("claude-mem")&&!t.includes("claude_mem")&&!t.includes("mcp-search")&&!t.includes("mcp_search")&&!t.includes("cmem")?null:e.slice(2).join("__")}function Xe(o){if(!o)return!1;if(o.startsWith("memory_")||o==="mem_search"||o==="get_summaries")return!0;let e=ys(o);return e!==null&&Us.has(e)}var vs=64*1024;function St(o,e=vs){let t=Buffer.byteLength(o,"utf8");if(t<=e)return o;let s=Buffer.from(o,"utf8"),n=e;for(;n>0&&(s[n]&192)===128;)n--;return`${s.subarray(0,n).toString("utf8")}\u2026[truncated: ${t} bytes]`}function Fs(o,e,t){return(0,At.createHash)("sha256").update([o||"",e||"",t||""].join("\0")).digest("hex").slice(0,16)}function gt(o){o.run(`
16
16
  CREATE TABLE IF NOT EXISTS tool_uses (
17
17
  id INTEGER PRIMARY KEY AUTOINCREMENT,
18
18
  tool_use_id TEXT NOT NULL,
@@ -20,7 +20,7 @@ ${L.stack??""}
20
20
  memory_session_id TEXT,
21
21
  session_db_id INTEGER,
22
22
  project TEXT NOT NULL,
23
- platform_source TEXT NOT NULL DEFAULT '${p}',
23
+ platform_source TEXT NOT NULL DEFAULT '${T}',
24
24
  tool_name TEXT NOT NULL,
25
25
  tool_input TEXT,
26
26
  tool_response TEXT,
@@ -36,7 +36,7 @@ ${L.stack??""}
36
36
  created_at_epoch INTEGER NOT NULL,
37
37
  UNIQUE(content_session_id, tool_use_id)
38
38
  )
39
- `),r.run("CREATE INDEX IF NOT EXISTS idx_tool_uses_project ON tool_uses(project)"),r.run("CREATE INDEX IF NOT EXISTS idx_tool_uses_project_nocase_created ON tool_uses(project COLLATE NOCASE, created_at_epoch DESC, id DESC)"),r.run("CREATE INDEX IF NOT EXISTS idx_tool_uses_memory_session ON tool_uses(memory_session_id)"),r.run("CREATE INDEX IF NOT EXISTS idx_tool_uses_content_session ON tool_uses(content_session_id)"),r.run("CREATE INDEX IF NOT EXISTS idx_tool_uses_session_db_id ON tool_uses(session_db_id)"),r.run("CREATE INDEX IF NOT EXISTS idx_tool_uses_tool_name ON tool_uses(tool_name)"),r.run("CREATE INDEX IF NOT EXISTS idx_tool_uses_created_at_epoch ON tool_uses(created_at_epoch)"),r.run("CREATE INDEX IF NOT EXISTS idx_tool_uses_observation_id ON tool_uses(observation_id)"),r.run("CREATE INDEX IF NOT EXISTS idx_tool_uses_or_generation_id ON tool_uses(or_generation_id)")}function pt(r,e){if(!e.toolUseId||!e.contentSessionId||!e.toolName||bs(e.toolName))return null;let t=e.createdAtEpoch??Date.now(),s=new Date(t).toISOString(),n=Cs(e.toolName,e.toolInput,e.toolResponse),i=e.toolInput!=null?ct(e.toolInput):null,o=e.toolResponse!=null?ct(e.toolResponse):null,a=r.prepare(`
39
+ `),o.run("CREATE INDEX IF NOT EXISTS idx_tool_uses_project ON tool_uses(project)"),o.run("CREATE INDEX IF NOT EXISTS idx_tool_uses_project_nocase_created ON tool_uses(project COLLATE NOCASE, created_at_epoch DESC, id DESC)"),o.run("CREATE INDEX IF NOT EXISTS idx_tool_uses_memory_session ON tool_uses(memory_session_id)"),o.run("CREATE INDEX IF NOT EXISTS idx_tool_uses_content_session ON tool_uses(content_session_id)"),o.run("CREATE INDEX IF NOT EXISTS idx_tool_uses_session_db_id ON tool_uses(session_db_id)"),o.run("CREATE INDEX IF NOT EXISTS idx_tool_uses_tool_name ON tool_uses(tool_name)"),o.run("CREATE INDEX IF NOT EXISTS idx_tool_uses_created_at_epoch ON tool_uses(created_at_epoch)"),o.run("CREATE INDEX IF NOT EXISTS idx_tool_uses_observation_id ON tool_uses(observation_id)"),o.run("CREATE INDEX IF NOT EXISTS idx_tool_uses_or_generation_id ON tool_uses(or_generation_id)")}function Ot(o,e){if(!e.toolUseId||!e.contentSessionId||!e.toolName||Xe(e.toolName))return null;let t=e.createdAtEpoch??Date.now(),s=new Date(t).toISOString(),n=Fs(e.toolName,e.toolInput,e.toolResponse),i=e.toolInput!=null?St(e.toolInput):null,r=e.toolResponse!=null?St(e.toolResponse):null,a=o.prepare(`
40
40
  INSERT INTO tool_uses (
41
41
  tool_use_id, content_session_id, memory_session_id, session_db_id, project,
42
42
  platform_source, tool_name, tool_input, tool_response, cwd, prompt_number,
@@ -61,7 +61,7 @@ ${L.stack??""}
61
61
  or_session_id = COALESCE(excluded.or_session_id, tool_uses.or_session_id),
62
62
  content_hash = excluded.content_hash
63
63
  RETURNING id
64
- `).get(e.toolUseId,e.contentSessionId,e.memorySessionId??null,e.sessionDbId??null,e.project??"",b(e.platformSource),e.toolName,i,o,e.cwd??null,e.promptNumber??null,e.agentType??null,e.agentId??null,e.orGenerationId??null,e.orSessionId??null,n,s,t);return a?a.id:null}function mt(r,e){let t=e.toolUseIds.filter(i=>typeof i=="string"&&i.length>0);if(t.length===0)return 0;let s=t.map(()=>"?").join(","),n=r.prepare(`
64
+ `).get(e.toolUseId,e.contentSessionId,e.memorySessionId??null,e.sessionDbId??null,e.project??"",b(e.platformSource),e.toolName,i,r,e.cwd??null,e.promptNumber??null,e.agentType??null,e.agentId??null,e.orGenerationId??null,e.orSessionId??null,n,s,t);return a?a.id:null}function ft(o,e){let t=e.toolUseIds.filter(i=>typeof i=="string"&&i.length>0);if(t.length===0)return 0;let s=t.map(()=>"?").join(","),n=o.prepare(`
65
65
  UPDATE tool_uses
66
66
  SET observation_id = COALESCE(observation_id, ?),
67
67
  memory_session_id = CASE WHEN observation_id IS NULL
@@ -71,23 +71,23 @@ ${L.stack??""}
71
71
  WHERE content_session_id = ?
72
72
  AND tool_use_id IN (${s})
73
73
  AND (observation_id IS NULL OR observation_id = ?)
74
- `).run(e.observationId,e.memorySessionId??null,e.memorySessionId??null,e.contentSessionId,...t,e.observationId);return Number(n.changes??0)}function Tt(r){return r?{clause:`COALESCE(NULLIF(platform_source, ''), '${p}') = ?`,param:b(r)}:null}function St(r,e,t={}){let s=[],n=[];for(let c of e){if(typeof c=="number"&&Number.isInteger(c)){s.push(c);continue}if(typeof c=="string"&&c.trim().length>0){let d=Number(c);Number.isInteger(d)&&String(d)===c.trim()&&s.push(d),n.push(c.trim())}}if(s.length===0&&n.length===0)return[];let i=[],o=[];s.length>0&&(i.push(`id IN (${s.map(()=>"?").join(",")})`),o.push(...s)),n.length>0&&(i.push(`tool_use_id IN (${n.map(()=>"?").join(",")})`),o.push(...n));let a=[`(${i.join(" OR ")})`];t.project&&(a.push("project COLLATE NOCASE = ?"),o.push(t.project)),t.contentSessionId&&(a.push("content_session_id = ?"),o.push(t.contentSessionId));let _=Tt(t.platformSource);_&&(a.push(_.clause),o.push(_.param));let E=t.limit&&t.limit>0?`LIMIT ${Math.floor(t.limit)}`:"";return r.prepare(`
74
+ `).run(e.observationId,e.memorySessionId??null,e.memorySessionId??null,e.contentSessionId,...t,e.observationId);return Number(n.changes??0)}function Rt(o){return o?{clause:`COALESCE(NULLIF(platform_source, ''), '${T}') = ?`,param:b(o)}:null}function Nt(o,e,t={}){let s=[],n=[];for(let d of e){if(typeof d=="number"&&Number.isInteger(d)){s.push(d);continue}if(typeof d=="string"&&d.trim().length>0){let u=Number(d);Number.isInteger(u)&&String(u)===d.trim()&&s.push(u),n.push(d.trim())}}if(s.length===0&&n.length===0)return[];let i=[],r=[];s.length>0&&(i.push(`id IN (${s.map(()=>"?").join(",")})`),r.push(...s)),n.length>0&&(i.push(`tool_use_id IN (${n.map(()=>"?").join(",")})`),r.push(...n));let a=[`(${i.join(" OR ")})`];t.project&&(a.push("project COLLATE NOCASE = ?"),r.push(t.project)),t.contentSessionId&&(a.push("content_session_id = ?"),r.push(t.contentSessionId));let _=Rt(t.platformSource);_&&(a.push(_.clause),r.push(_.param));let E=t.limit&&t.limit>0?`LIMIT ${Math.floor(t.limit)}`:"";return o.prepare(`
75
75
  SELECT * FROM tool_uses
76
76
  WHERE ${a.join(" AND ")}
77
77
  ORDER BY created_at_epoch DESC
78
78
  ${E}
79
- `).all(...o)}function At(r,e={}){let t=[],s=[];if(e.project&&(t.push("project COLLATE NOCASE = ?"),s.push(e.project)),e.contentSessionId&&(t.push("content_session_id = ?"),s.push(e.contentSessionId)),e.memorySessionId&&(t.push("memory_session_id = ?"),s.push(e.memorySessionId)),typeof e.sessionDbId=="number"&&(t.push("session_db_id = ?"),s.push(e.sessionDbId)),e.toolName){let E=Array.isArray(e.toolName)?e.toolName:[e.toolName];E.length>0&&(t.push(`tool_name IN (${E.map(()=>"?").join(",")})`),s.push(...E))}e.agentId&&(t.push("agent_id = ?"),s.push(e.agentId));let n=Tt(e.platformSource);n&&(t.push(n.clause),s.push(n.param)),typeof e.dateStart=="number"&&(t.push("created_at_epoch >= ?"),s.push(e.dateStart)),typeof e.dateEnd=="number"&&(t.push("created_at_epoch <= ?"),s.push(e.dateEnd));let i=t.length>0?`WHERE ${t.join(" AND ")}`:"",o=e.orderBy==="date_asc"?"ASC":"DESC",a=Math.min(Math.max(Math.floor(e.limit??50),1),500),_=Math.max(Math.floor(e.offset??0),0);return r.prepare(`
79
+ `).all(...r)}function bt(o,e={}){let t=[],s=[];if(e.project&&(t.push("project COLLATE NOCASE = ?"),s.push(e.project)),e.contentSessionId&&(t.push("content_session_id = ?"),s.push(e.contentSessionId)),e.memorySessionId&&(t.push("memory_session_id = ?"),s.push(e.memorySessionId)),typeof e.sessionDbId=="number"&&(t.push("session_db_id = ?"),s.push(e.sessionDbId)),e.toolName){let E=Array.isArray(e.toolName)?e.toolName:[e.toolName];E.length>0&&(t.push(`tool_name IN (${E.map(()=>"?").join(",")})`),s.push(...E))}e.agentId&&(t.push("agent_id = ?"),s.push(e.agentId));let n=Rt(e.platformSource);n&&(t.push(n.clause),s.push(n.param)),typeof e.dateStart=="number"&&(t.push("created_at_epoch >= ?"),s.push(e.dateStart)),typeof e.dateEnd=="number"&&(t.push("created_at_epoch <= ?"),s.push(e.dateEnd));let i=t.length>0?`WHERE ${t.join(" AND ")}`:"",r=e.orderBy==="date_asc"?"ASC":"DESC",a=Math.min(Math.max(Math.floor(e.limit??50),1),500),_=Math.max(Math.floor(e.offset??0),0);return o.prepare(`
80
80
  SELECT * FROM tool_uses
81
81
  ${i}
82
- ORDER BY created_at_epoch ${o}, id ${o}
82
+ ORDER BY created_at_epoch ${r}, id ${r}
83
83
  LIMIT ${a} OFFSET ${_}
84
- `).all(...s)}function Ot(r,e={}){let t=[],s=[];e.project&&(t.push("project COLLATE NOCASE = ?"),s.push(e.project)),e.contentSessionId&&(t.push("content_session_id = ?"),s.push(e.contentSessionId)),e.agentId&&(t.push("agent_id = ?"),s.push(e.agentId)),typeof e.dateStart=="number"&&(t.push("created_at_epoch >= ?"),s.push(e.dateStart)),typeof e.dateEnd=="number"&&(t.push("created_at_epoch <= ?"),s.push(e.dateEnd));let n=t.length>0?`WHERE ${t.join(" AND ")}`:"";return r.prepare(`
84
+ `).all(...s)}function Ct(o,e={}){let t=[],s=[];e.project&&(t.push("project COLLATE NOCASE = ?"),s.push(e.project)),e.contentSessionId&&(t.push("content_session_id = ?"),s.push(e.contentSessionId)),e.agentId&&(t.push("agent_id = ?"),s.push(e.agentId)),typeof e.dateStart=="number"&&(t.push("created_at_epoch >= ?"),s.push(e.dateStart)),typeof e.dateEnd=="number"&&(t.push("created_at_epoch <= ?"),s.push(e.dateEnd));let n=t.length>0?`WHERE ${t.join(" AND ")}`:"";return o.prepare(`
85
85
  SELECT tool_name, COUNT(DISTINCT tool_use_id) AS uses
86
86
  FROM tool_uses
87
87
  ${n}
88
88
  GROUP BY tool_name
89
89
  ORDER BY uses DESC, tool_name ASC
90
- `).all(...s)}function gt(r){r.run(`
90
+ `).all(...s)}function Lt(o){o.run(`
91
91
  CREATE TABLE IF NOT EXISTS work_state_entries (
92
92
  id INTEGER PRIMARY KEY AUTOINCREMENT,
93
93
  project TEXT NOT NULL,
@@ -96,34 +96,34 @@ ${L.stack??""}
96
96
  created_at TEXT NOT NULL,
97
97
  created_at_epoch INTEGER NOT NULL
98
98
  )
99
- `),r.run("CREATE INDEX IF NOT EXISTS idx_work_state_entries_project ON work_state_entries(project COLLATE NOCASE, list_name, id)")}function ft(r,e){let t=e.createdAtEpoch??Date.now(),s=r.prepare(`
99
+ `),o.run("CREATE INDEX IF NOT EXISTS idx_work_state_entries_project ON work_state_entries(project COLLATE NOCASE, list_name, id)")}function It(o,e){let t=e.createdAtEpoch??Date.now(),s=o.prepare(`
100
100
  INSERT INTO work_state_entries (project, list_name, fields, created_at, created_at_epoch)
101
101
  VALUES (?, ?, ?, ?, ?)
102
- `).run(e.project,e.listName,JSON.stringify(e.fields),new Date(t).toISOString(),t),n=Number(s.lastInsertRowid);return u.debug("DB","Work state entry appended",{id:n,project:e.project,listName:e.listName}),n}function Rt(r,e,t){if(e.length===0)return[];let s=e.map(()=>"?").join(", "),n=t===void 0?"":" AND list_name = ?";return r.prepare(`
102
+ `).run(e.project,e.listName,JSON.stringify(e.fields),new Date(t).toISOString(),t),n=Number(s.lastInsertRowid);return c.debug("DB","Work state entry appended",{id:n,project:e.project,listName:e.listName}),n}function ht(o,e,t){if(e.length===0)return[];let s=e.map(()=>"?").join(", "),n=t===void 0?"":" AND list_name = ?";return o.prepare(`
103
103
  SELECT id, project, list_name, fields, created_at_epoch
104
104
  FROM work_state_entries
105
105
  WHERE project COLLATE NOCASE IN (${s})${n}
106
106
  ORDER BY id
107
- `).all(...e,...t===void 0?[]:[t]).map(o=>({...o,fields:JSON.parse(o.fields)}))}var G=require("fs"),k=require("path"),Z=require("os");var ue={HEALTH_CHECK:3e3,API_REQUEST:3e4,SESSION_INIT_HOOK_CAP:15e3,SESSION_INIT_REQUEST:1e4,SESSION_INIT_REQUEST_MAX:14e3,HOOK_READINESS_WAIT:1e4,POST_SPAWN_WAIT:15e3,READINESS_WAIT:3e4,PORT_IN_USE_WAIT:3e3,POWERSHELL_COMMAND:1e4,WINDOWS_MULTIPLIER:1.5};function Ls(r=process.platform){return r==="win32"?8e3:5e3}function Nt(r=process.platform){return ue.SESSION_INIT_HOOK_CAP-Ls(r)}function bt(r){return process.platform==="win32"?Math.round(r*ue.WINDOWS_MULTIPLIER):r}function Ct(r){try{return new URL(r).hostname.toLowerCase()==="openrouter.ai"}catch{return!1}}var Is="security_alert",hs="sync-hub.black-pond-afbb.workers.dev",Ds="ziczmqtpmaxbornfghye.supabase.co",Ms="https://sync.cmem.ai",Us=new Set(["xiaomi/mimo-v2-flash:free"]);function ys(r){let e=r.CLAUDE_MEM_OPENROUTER_MODEL;if(typeof e!="string"||!Us.has(e.trim()))return!1;let t=typeof r.CLAUDE_MEM_OPENROUTER_BASE_URL=="string"?r.CLAUDE_MEM_OPENROUTER_BASE_URL.trim():"";return t===""||Ct(t)}var Lt=18e4,It=[{key:"CLAUDE_MEM_LLM_TIMEOUT_MS",legacy:"30000",markerTag:"llm-timeout-migrated-v1"},{key:"CLAUDE_MEM_FIELD_OPTIMIZE_TIMEOUT_MS",legacy:"30000",markerTag:"field-optimize-timeout-migrated-v1"}];function Dt(r,e){return(0,k.join)((0,k.dirname)(r),`.${(0,k.basename)(r)}.${e.markerTag}`)}function we(r,e){try{(0,G.writeFileSync)(Dt(r,e),new Date().toISOString(),{encoding:"utf-8",mode:384})}catch{}}var ht=new Set;function vs(r){if(typeof r!="string")return null;let e=r.trim();if(e.length===0)return null;try{let t=new URL(e).hostname;if(t===hs||t===Ds)return Ms}catch{return null}return null}var Y=class{static DEFAULTS={CLAUDE_MEM_MODEL:"claude-haiku-4-5-20251001",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_SESSION_START_INCLUDE_ALL_SOURCES:"false",CLAUDE_MEM_WORKER_PORT:String(37700+(process.getuid?.()??77)%100),CLAUDE_MEM_WORKER_HOST:"127.0.0.1",CLAUDE_MEM_ALLOWED_ORIGINS:"",CLAUDE_MEM_PUBLIC_URL:"",CLAUDE_MEM_API_TIMEOUT_MS:String(bt(ue.API_REQUEST)),CLAUDE_MEM_SESSION_INIT_TIMEOUT_MS:String(Nt()),CLAUDE_MEM_IDLE_EXIT_SEC:"0",CLAUDE_MEM_SKIP_TOOLS:"ListMcpResourcesTool,SlashCommand,Skill,TodoWrite,AskUserQuestion",CLAUDE_MEM_SKIP_BASH_PATTERNS:"",CLAUDE_MEM_SKIP_SUBAGENT_OBSERVATIONS:"false",CLAUDE_MEM_SKIP_AGENT_TYPES:"",CLAUDE_MEM_CAPTURE_ADVISOR_CALLS:"false",CLAUDE_MEM_PROVIDER:"claude",CLAUDE_MEM_CODEX_MODEL:"",CLAUDE_MEM_CODEX_PATH:"codex",CLAUDE_MEM_CODEX_REASONING_EFFORT:"low",CLAUDE_MEM_CODEX_MAX_CONCURRENT_AGENTS:"2",CLAUDE_MEM_CODEX_OBSERVATION_BATCH_SIZE:"8",CLAUDE_MEM_CODEX_OBSERVATION_BATCH_MAX_CHARS:"32000",CLAUDE_MEM_CLAUDE_AUTH_METHOD:"subscription",CLAUDE_MEM_GEMINI_API_KEY:"",CLAUDE_MEM_GEMINI_API_KEYS:"",CLAUDE_MEM_GEMINI_MODEL:"gemini-flash-latest",CLAUDE_MEM_GEMINI_RATE_LIMITING_ENABLED:"true",CLAUDE_MEM_OPENROUTER_API_KEY:"",CLAUDE_MEM_OPENROUTER_API_KEYS:"",CLAUDE_MEM_OPENROUTER_MODEL:"cohere/north-mini-code:free",CLAUDE_MEM_OPENROUTER_BASE_URL:"",CLAUDE_MEM_OPENROUTER_SITE_URL:"",CLAUDE_MEM_OPENROUTER_APP_NAME:"claude-mem",CLAUDE_MEM_OPENROUTER_EXTRA_BODY:"",CLAUDE_MEM_OPENROUTER_REASONING_EFFORT:"",CLAUDE_MEM_OPENAI_COMPAT_PRESET:"",CLAUDE_MEM_OPENAI_COMPAT_API_KEY:"",CLAUDE_MEM_OPENAI_COMPAT_API_KEYS:"",CLAUDE_MEM_OPENAI_COMPAT_BASE_URL:"",CLAUDE_MEM_OPENAI_COMPAT_MODEL:"",CLAUDE_MEM_QUOTA_FALLBACK_PROVIDER:"",CLAUDE_MEM_QUOTA_FALLBACK_MODEL:"",CLAUDE_MEM_QUOTA_THRESHOLD_FIVE_HOUR:"0.95",CLAUDE_MEM_QUOTA_THRESHOLD_SEVEN_DAY:"0.93",CLAUDE_MEM_QUOTA_THRESHOLD_SEVEN_DAY_OPUS:"0.93",CLAUDE_MEM_QUOTA_THRESHOLD_SEVEN_DAY_SONNET:"0.92",CLAUDE_MEM_QUOTA_THRESHOLD_OVERAGE:"0.95",CLAUDE_MEM_DATA_DIR:(0,k.join)((0,Z.homedir)(),".claude-mem"),CLAUDE_MEM_LOG_LEVEL:"INFO",CLAUDE_MEM_PYTHON_VERSION:"3.13",CLAUDE_CODE_PATH:"",CLAUDE_MEM_CLAUDE_CONFIG_DIR:"",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_OBSERVATION_TYPES:"",CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS:"",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_MAIN_AGENT_ONLY:"true",CLAUDE_MEM_REINFORCE_ALPHA:"0",CLAUDE_MEM_CONTEXT_SHOW_TERMINAL_OUTPUT:"true",CLAUDE_MEM_WELCOME_HINT_ENABLED:"true",CLAUDE_MEM_FILE_READ_GATE_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,k.join)((0,Z.homedir)(),".claude-mem","transcript-watch.json"),CLAUDE_MEM_CODEX_TRANSCRIPT_INGESTION:"false",CLAUDE_MEM_CODEX_SUBAGENT_INGESTION:"false",CLAUDE_MEM_MAX_CONCURRENT_AGENTS:"2",CLAUDE_MEM_OBSERVER_MAX_CONVERSATION_CHARS:"400000",CLAUDE_MEM_OBSERVER_CONTEXT_WINDOW:"",CLAUDE_MEM_OBSERVER_MAX_OUTPUT_TOKENS:"4096",CLAUDE_MEM_OBSERVE_BARE_PROMPTS:"false",CLAUDE_MEM_HOOK_FAIL_LOUD_THRESHOLD:"3",CLAUDE_MEM_REDACT_ENABLED:"false",CLAUDE_MEM_REDACT_DISABLED_BUILTINS:"",CLAUDE_MEM_REDACT_CUSTOM_PATTERNS:"[]",CLAUDE_MEM_REDACT_LOG_MATCHES:"false",CLAUDE_MEM_EXCLUDED_PROJECTS:"",CLAUDE_MEM_PROJECT_ENVIRONMENTS:"[]",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_CHROMA_MUTATION_TIMEOUT_MS:"600000",CLAUDE_MEM_CHROMA_MAX_PENDING_MUTATIONS:"5000",CLAUDE_MEM_CHROMA_EMBEDDING_FUNCTION:"default",CLAUDE_MEM_CLOUD_SYNC_TOKEN:"",CLAUDE_MEM_CLOUD_SYNC_USER_ID:"",CLAUDE_MEM_CLOUD_SYNC_HUB_URL:"",CLAUDE_MEM_CLOUD_SYNC_DEVICE_ID:"",CLAUDE_MEM_CLOUD_SYNC_DEVICE_NAME:(0,Z.hostname)(),CLAUDE_MEM_CLOUD_SYNC_WS:"true",CLAUDE_MEM_CLOUD_SYNC_CONTENT_BATCH_SIZE:"40",CLAUDE_MEM_CLOUD_SYNC_REQUEST_TIMEOUT_MS:"90000",CLAUDE_MEM_LLM_TIMEOUT_MS:String(Lt),CLAUDE_MEM_FIELD_OPTIMIZE_TIMEOUT_MS:String(Lt),CLAUDE_MEM_TV_TOKEN:"",CLAUDE_MEM_PRO_TRIAL_EMAIL:"",CLAUDE_MEM_PRO_TRIAL_AT:"",CLAUDE_MEM_PRO_TRIAL_STATE:"",CLAUDE_MEM_PRO_TRIAL_ENDS_AT:"",CLAUDE_MEM_PRO_PLAN:"",CLAUDE_MEM_PRO_FALLBACK_AT:"",CLAUDE_MEM_PRO_FALLBACK_MESSAGE:"",CLAUDE_MEM_PRO_FALLBACK_ACTION:"",CLAUDE_MEM_PRO_FALLBACK_URL:"",CLAUDE_MEM_PRO_MEMORY_KEY:"",CLAUDE_MEM_PRO_MEMORY_BASE_URL:"",CLAUDE_MEM_PRO_MEMORY_MODEL:"",CLAUDE_MEM_TELEGRAM_ENABLED:"true",CLAUDE_MEM_TELEGRAM_BOT_TOKEN:"",CLAUDE_MEM_TELEGRAM_CHAT_ID:"",CLAUDE_MEM_TELEGRAM_WRAPUPS_ENABLED:"true",CLAUDE_MEM_TELEGRAM_OBSERVATION_ALERTS_ENABLED:"false",CLAUDE_MEM_TELEGRAM_WRAPUP_ROUTES:"{}",CLAUDE_MEM_TELEGRAM_TRIGGER_TYPES:"security_alert,sensitive",CLAUDE_MEM_TELEGRAM_TRIGGER_CONCEPTS:"",CLAUDE_MEM_GROK_BOT_AWARENESS_ENABLED:"true",CLAUDE_MEM_GROK_BOT_AWARENESS_AGENT_IDS:"521e962d-2ec3-4488-bfbc-54d5209ce118,95601360-61f7-4fd9-bb3a-2c976b2b85c0",CLAUDE_MEM_GROK_BOT_AWARENESS_TRIGGER_TYPES:"decision,bugfix,security_alert,sensitive",CLAUDE_MEM_GROK_BOT_AWARENESS_TRIGGER_CONCEPTS:"",CLAUDE_MEM_GROK_BOT_WEBHOOK_URL:"",CLAUDE_MEM_GROK_BOT_WEBHOOK_SECRET:"",CLAUDE_MEM_GROK_BOT_INJECT_ENABLED:"true",CLAUDE_MEM_GROK_BOT_INJECT_AGENT_IDS:"*",CLAUDE_MEM_GROK_BOT_INJECT_TIER:"episode",CLAUDE_MEM_GROK_BOT_INJECT_WINDOW:"80",CLAUDE_MEM_GROK_BOT_INJECT_FALLBACK:"house",CLAUDE_MEM_GROK_BOT_INJECT_PLATFORM_SOURCE:"",CLAUDE_MEM_GROK_BOT_INJECT_PROJECTS_BY_AGENT:"",CLAUDE_MEM_GROK_BOT_INJECT_MAX_LINE_CHARS:"160",CLAUDE_MEM_GROK_BOT_INJECT_DEBOUNCE_MS:"1500",CLAUDE_MEM_GROK_BOT_INJECT_STANDING_LINE:"",CLAUDE_MEM_CCS_ALIGN_ENABLED:"true",CLAUDE_MEM_CCS_ALIGN_VIEWER_IDS:"ccs-align",CLAUDE_MEM_CCS_ALIGN_TRIGGER_TYPES:"decision,bugfix,security_alert,sensitive",CLAUDE_MEM_CCS_ALIGN_PATCH_SHADOWS:"false",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:"",CLAUDE_MEM_DEDUP_ENABLED:"false",CLAUDE_MEM_DEDUP_COSINE_THRESHOLD:"0.80",CLAUDE_MEM_DEDUP_IDF_VETO_DF:"10",CLAUDE_MEM_DEDUP_MIN_SHARED_TOKENS:"2",CLAUDE_MEM_DEDUP_MIN_PROJECT_DOCS:"10",CLAUDE_MEM_DEDUP_MAX_SCAN:"2000",CLAUDE_MEM_DEDUP_MAX_BACKFILL_ROWS:"50000",CLAUDE_MEM_WORKER_AUTOSTART:"true",CLAUDE_MEM_PROJECT_NAME_SOURCE:"path"};static getAllDefaults(){return{...this.DEFAULTS}}static get(e){let t=process.env[e]??this.DEFAULTS[e];return e==="CLAUDE_MEM_WORKER_HOST"?this.normalizeWorkerHost(t):t}static normalizeWorkerHost(e){return e==="localhost"?"127.0.0.1":e}static finalizeSettings(e,t){let s=t?this.applyEnvOverrides(e):e;return s.CLAUDE_MEM_WORKER_HOST=this.normalizeWorkerHost(s.CLAUDE_MEM_WORKER_HOST),s}static getInt(e){let t=this.get(e);return parseInt(t,10)}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,G.existsSync)(e)){let d=this.getAllDefaults();try{P(e,d,{mode:384});for(let l of It)we(e,l);console.warn("[SETTINGS] Created settings file with defaults:",e)}catch(l){console.warn("[SETTINGS] Failed to create settings file, using in-memory defaults:",e,l instanceof Error?l.message:String(l))}return this.finalizeSettings(d,t)}let s=(0,G.readFileSync)(e,"utf-8"),n=Ie(s),i=K(n),o=i!==n,a=Qe(n),_=o&&Object.keys(a).some(d=>d!=="env");if(o&&!_)try{P(e,i,{mode:384}),console.warn("[SETTINGS] Migrated settings file from nested to flat schema:",e)}catch(d){console.warn("[SETTINGS] Failed to auto-migrate settings file:",e,d instanceof Error?d.message:String(d))}if(i.CLAUDE_MEM_TELEGRAM_TRIGGER_TYPES===Is){i={...i,CLAUDE_MEM_TELEGRAM_TRIGGER_TYPES:this.DEFAULTS.CLAUDE_MEM_TELEGRAM_TRIGGER_TYPES};try{P(e,_?{...a,env:i}:i,{mode:384}),console.warn("[SETTINGS] Migrated Telegram trigger types off the legacy default:",e)}catch(d){console.warn("[SETTINGS] Failed to migrate Telegram trigger types:",e,d instanceof Error?d.message:String(d))}}if(ys(i)){let d=String(i.CLAUDE_MEM_OPENROUTER_MODEL).trim();i={...i,CLAUDE_MEM_OPENROUTER_MODEL:this.DEFAULTS.CLAUDE_MEM_OPENROUTER_MODEL};try{P(e,_?{...a,env:i}:i,{mode:384}),console.warn(`[SETTINGS] Migrated OpenRouter model off the retired default ${d} to ${this.DEFAULTS.CLAUDE_MEM_OPENROUTER_MODEL}:`,e)}catch(l){console.warn("[SETTINGS] Failed to migrate the retired OpenRouter model:",e,l instanceof Error?l.message:String(l))}}let E=vs(i.CLAUDE_MEM_CLOUD_SYNC_HUB_URL);if(E!==null){i={...i,CLAUDE_MEM_CLOUD_SYNC_HUB_URL:E};try{P(e,_?{...a,env:i}:i,{mode:384}),console.warn("[SETTINGS] Migrated cloud sync hub URL to",E,"from a retired hub host:",e)}catch(d){console.warn("[SETTINGS] Failed to migrate cloud sync hub URL:",e,d instanceof Error?d.message:String(d))}}for(let d of It)if(!(0,G.existsSync)(Dt(e,d))){if(i[d.key]!==d.legacy){we(e,d);continue}i={...i,[d.key]:this.DEFAULTS[d.key]};try{P(e,_?{...a,env:i}:i,{mode:384}),we(e,d),console.warn(`[SETTINGS] Migrated ${d.key} off the old ${d.legacy}ms default to ${this.DEFAULTS[d.key]}ms:`,e)}catch(l){let O=`${d.key}\0${e}`;ht.has(O)||(ht.add(O),console.warn(`[SETTINGS] Failed to migrate ${d.key}; using the new default in memory (reported once per process):`,e,l instanceof Error?l.message:String(l)))}}let c={...this.DEFAULTS};for(let d of Object.keys(this.DEFAULTS))i[d]!==void 0&&(c[d]=i[d]);return this.finalizeSettings(c,t)}catch(s){console.warn("[SETTINGS] Failed to load settings, using defaults:",e,s instanceof Error?s.message:String(s));let n=this.getAllDefaults();return this.finalizeSettings(n,t)}}};var Ft=require("crypto");function ee(r){return(r??"").toLowerCase().replace(/[^\p{L}\p{N}\s]/gu," ").replace(/\s+/g," ").trim()}function H(r){return(r??"").toLowerCase().trim().split(/\s+/).filter(Boolean)}function le(r,e){return Math.log(1+e/(r+.5))}function Mt(r,e){return t=>le(r(t),e)}function Ut(r,e){let t=new Map;for(let s of new Set(r))t.set(s,e(s));return t}function yt(r,e,t){let s=Ut(r,t),n=Ut(e,t),i=0,o=0,a=0;for(let[_,E]of s){o+=E*E;let c=n.get(_);c!==void 0&&(i+=E*c)}for(let[,_]of n)a+=_*_;return o===0||a===0?0:i/Math.sqrt(o*a)}function vt(r,e,t,s){let n=new Set(r),i=new Set(e);for(let o of n)if(!i.has(o)&&t(o)>s)return!0;for(let o of i)if(!n.has(o)&&t(o)>s)return!0;return!1}function Pe(r,e,t,s){let n=ee(r);if(n!==""&&n===ee(e))return{tier:"exact",method:"exact",score:1};let i=H(r),o=H(e),a=s.minSharedTokens??2,_=new Set(o),E=0;for(let d of new Set(i))_.has(d)&&E++;if(E<a)return{tier:"none",method:"none",score:0};let c=yt(i,o,t);return c>=s.cosineThreshold&&!vt(i,o,t,s.vetoThetaIdf)?{tier:"candidate",method:"idf_cosine",score:c}:{tier:"none",method:"none",score:c}}function pe(r,e){return!!r&&!!e}function xe(r,e,t,s=!1){let n=ee(t);if(n==="")return null;let i=b(e),o=s?"subagent":"main";return(0,Ft.createHash)("sha256").update(`${r}\0${i}\0${o}\0${n}`).digest("hex").slice(0,32)}function wt(r,e,t){return t===null?null:r.prepare("SELECT id, occurrence_count, created_at_epoch FROM observations WHERE project = ? AND title_norm_key = ? ORDER BY created_at_epoch ASC, id ASC LIMIT 1").get(e,t)??null}function Pt(r,e,t){let s=[...new Set(H(t))],n=r.prepare("INSERT INTO token_df (project, token, df) VALUES (?, ?, 1) ON CONFLICT(project, token) DO UPDATE SET df = df + 1");for(let i of s)n.run(e,i);r.prepare("INSERT INTO dedup_meta (project, doc_count) VALUES (?, 1) ON CONFLICT(project) DO UPDATE SET doc_count = doc_count + 1").run(e)}function xt(r,e){return r.prepare("SELECT doc_count FROM dedup_meta WHERE project = ?").get(e)?.doc_count??0}function kt(r,e){let t=xt(r,e),s=r.prepare("SELECT token, df FROM token_df WHERE project = ?").all(e),n=new Map(s.map(i=>[i.token,i.df]));return{idfFn:Mt(i=>n.get(i)??0,t),docCount:t}}function Bt(r){return r.prepare("INSERT OR IGNORE INTO observation_dedup_candidates (observation_id, duplicate_of_id, project, method, score, status, created_at, created_at_epoch) VALUES (?, ?, ?, ?, ?, ?, ?, ?)")}function Xt(r,e,t){return xt(r,e)>=t}function Fs(r,e,t=Number.POSITIVE_INFINITY){let s=r.prepare("SELECT COUNT(*) c FROM observations WHERE project = ?").get(e).c;if(s>t)return u.warn("DEDUP",`Skipping dedup backfill for project ${e}: ${s} rows exceeds cap ${t} (CLAUDE_MEM_DEDUP_MAX_BACKFILL_ROWS)`),0;let n=r.prepare("SELECT o.id, o.title, o.agent_id, o.agent_type, s.platform_source FROM observations o LEFT JOIN sdk_sessions s ON s.memory_session_id = o.memory_session_id WHERE o.project = ?").all(e),i=r.prepare("UPDATE observations SET title_norm_key = ? WHERE id = ?"),o=r.prepare("INSERT INTO token_df (project, token, df) VALUES (?, ?, ?)");return r.transaction(()=>{let _=new Map;for(let E of n){i.run(xe(e,E.platform_source,E.title,pe(E.agent_id,E.agent_type)),E.id);for(let c of new Set(H(E.title)))_.set(c,(_.get(c)??0)+1)}r.prepare("DELETE FROM token_df WHERE project = ?").run(e);for(let[E,c]of _)o.run(e,E,c);r.prepare("INSERT INTO dedup_meta (project, doc_count, last_rebuild_doc_count, deleted_since_rebuild) VALUES (?, ?, ?, 0) ON CONFLICT(project) DO UPDATE SET doc_count = excluded.doc_count, last_rebuild_doc_count = excluded.last_rebuild_doc_count, deleted_since_rebuild = 0").run(e,n.length,n.length)})(),n.length}function ws(r,e,t){let s=r.prepare("SELECT id, title FROM observations WHERE project = ? AND title IS NOT NULL ORDER BY id ASC").all(e);if(s.length<2)return 0;if(s.length>t.maxBackfillRows)return u.warn("DEDUP",`Skipping dedup sweep for project ${e}: ${s.length} rows exceeds cap ${t.maxBackfillRows}`),0;let{idfFn:n,docCount:i}=kt(r,e),o={cosineThreshold:t.cosineThreshold,vetoThetaIdf:le(t.idfVetoDf,i),minSharedTokens:t.minSharedTokens},a=s.map(f=>new Set(H(f.title))),_=new Map;for(let f of a)for(let g of f)_.set(g,(_.get(g)??0)+1);let E=Math.max(2,Math.ceil(Math.sqrt(s.length))*4),c=new Map;a.forEach((f,g)=>{for(let m of f){let N=_.get(m);if(N<2||N>E)continue;let A=c.get(m);A||(A=[],c.set(m,A)),A.push(g)}});let d=new Map;for(let f of c.values())for(let g=0;g<f.length;g++)for(let m=g+1;m<f.length;m++){let N=`${f[g]}:${f[m]}`;d.set(N,(d.get(N)??0)+1)}let l=Bt(r),O=new Date().toISOString(),L=Date.now(),I=0;for(let[f,g]of d){if(g<t.minSharedTokens)continue;let[m,N]=f.split(":").map(Number),A=Pe(s[m].title,s[N].title,n,o);A.tier==="candidate"&&(I+=l.run(s[N].id,s[m].id,e,A.method,A.score,"pending",O,L).changes)}return I}function Gt(r,e){return r.prepare("SELECT DISTINCT project FROM observations").all().map(s=>s.project).map(s=>{let n=Fs(r,s,e.maxBackfillRows),i=ws(r,s,e);return{project:s,docs:n,candidates:i}})}function Ht(r,e,t,s,n){if(!s)return 0;let{idfFn:i,docCount:o}=kt(r,e),a={cosineThreshold:n.cosineThreshold,vetoThetaIdf:le(n.idfVetoDf,o),minSharedTokens:n.minSharedTokens},_=r.prepare("SELECT id, title FROM observations WHERE project = ? AND id != ? AND title IS NOT NULL ORDER BY created_at_epoch DESC, id DESC LIMIT ?").all(e,t,n.maxScan);_.length===n.maxScan&&u.debug("DEDUP",`Tier-1 scan hit MAX_SCAN=${n.maxScan} for project ${e}; older rows covered by dedup-scan`);let E=Bt(r),c=new Date().toISOString(),d=Date.now(),l=0;for(let O of _){let L=Pe(s,O.title,i,a);L.tier==="candidate"&&(l+=E.run(t,O.id,e,L.method,L.score,"pending",c,d).changes)}return l}function jt(r,e,t,s,n){let i=Date.now()-s,o=n!==void 0?"up.session_db_id = ?":"up.content_session_id = ?",a=n??e;return r.prepare(`
107
+ `).all(...e,...t===void 0?[]:[t]).map(r=>({...r,fields:JSON.parse(r.fields)}))}var G=require("fs"),k=require("path"),te=require("os");var Ae={HEALTH_CHECK:3e3,API_REQUEST:3e4,SESSION_INIT_HOOK_CAP:15e3,SESSION_INIT_REQUEST:1e4,SESSION_INIT_REQUEST_MAX:14e3,HOOK_READINESS_WAIT:1e4,POST_SPAWN_WAIT:15e3,READINESS_WAIT:3e4,PORT_IN_USE_WAIT:3e3,POWERSHELL_COMMAND:1e4,WINDOWS_MULTIPLIER:1.5};function ws(o=process.platform){return o==="win32"?8e3:5e3}function Dt(o=process.platform){return Ae.SESSION_INIT_HOOK_CAP-ws(o)}function Mt(o){return process.platform==="win32"?Math.round(o*Ae.WINDOWS_MULTIPLIER):o}function Ut(o){try{return new URL(o).hostname.toLowerCase()==="openrouter.ai"}catch{return!1}}var Ps="security_alert",xs="sync-hub.black-pond-afbb.workers.dev",ks="ziczmqtpmaxbornfghye.supabase.co",Bs="https://sync.cmem.ai",Xs=new Set(["xiaomi/mimo-v2-flash:free"]);function Gs(o){return typeof o=="boolean"?String(o):o}function Hs(o){let e=o.CLAUDE_MEM_OPENROUTER_MODEL;if(typeof e!="string"||!Xs.has(e.trim()))return!1;let t=typeof o.CLAUDE_MEM_OPENROUTER_BASE_URL=="string"?o.CLAUDE_MEM_OPENROUTER_BASE_URL.trim():"";return t===""||Ut(t)}var yt=18e4,vt=[{key:"CLAUDE_MEM_LLM_TIMEOUT_MS",legacy:"30000",markerTag:"llm-timeout-migrated-v1"},{key:"CLAUDE_MEM_FIELD_OPTIMIZE_TIMEOUT_MS",legacy:"30000",markerTag:"field-optimize-timeout-migrated-v1"}];function wt(o,e){return(0,k.join)((0,k.dirname)(o),`.${(0,k.basename)(o)}.${e.markerTag}`)}function Ge(o,e){try{(0,G.writeFileSync)(wt(o,e),new Date().toISOString(),{encoding:"utf-8",mode:384})}catch{}}var Ft=new Set;function $s(o){if(typeof o!="string")return null;let e=o.trim();if(e.length===0)return null;try{let t=new URL(e).hostname;if(t===xs||t===ks)return Bs}catch{return null}return null}var Y=class{static DEFAULTS={CLAUDE_MEM_MEMORY_SEARCH_HOOK_ENABLED:"true",CLAUDE_MEM_MEMORY_INSTRUCTIONS_ENABLED:"true",CLAUDE_MEM_MEMORY_WATCH_ROOTS:"",CLAUDE_MEM_MODEL:"claude-haiku-4-5-20251001",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_SESSION_START_INCLUDE_ALL_SOURCES:"false",CLAUDE_MEM_WORKER_PORT:String(37700+(process.getuid?.()??77)%100),CLAUDE_MEM_WORKER_HOST:"127.0.0.1",CLAUDE_MEM_ALLOWED_ORIGINS:"",CLAUDE_MEM_PUBLIC_URL:"",CLAUDE_MEM_API_TIMEOUT_MS:String(Mt(Ae.API_REQUEST)),CLAUDE_MEM_SESSION_INIT_TIMEOUT_MS:String(Dt()),CLAUDE_MEM_IDLE_EXIT_SEC:"0",CLAUDE_MEM_SKIP_TOOLS:"ListMcpResourcesTool,SlashCommand,Skill,TodoWrite,AskUserQuestion",CLAUDE_MEM_SKIP_BASH_PATTERNS:"",CLAUDE_MEM_SKIP_SUBAGENT_OBSERVATIONS:"false",CLAUDE_MEM_SKIP_AGENT_TYPES:"",CLAUDE_MEM_CAPTURE_ADVISOR_CALLS:"false",CLAUDE_MEM_PROVIDER:"claude",CLAUDE_MEM_CODEX_MODEL:"",CLAUDE_MEM_CODEX_PATH:"codex",CLAUDE_MEM_CODEX_REASONING_EFFORT:"low",CLAUDE_MEM_CODEX_MAX_CONCURRENT_AGENTS:"2",CLAUDE_MEM_CODEX_OBSERVATION_BATCH_SIZE:"8",CLAUDE_MEM_CODEX_OBSERVATION_BATCH_MAX_CHARS:"32000",CLAUDE_MEM_CLAUDE_AUTH_METHOD:"subscription",CLAUDE_MEM_GEMINI_API_KEY:"",CLAUDE_MEM_GEMINI_API_KEYS:"",CLAUDE_MEM_GEMINI_MODEL:"gemini-flash-latest",CLAUDE_MEM_GEMINI_RATE_LIMITING_ENABLED:"true",CLAUDE_MEM_OPENROUTER_API_KEY:"",CLAUDE_MEM_OPENROUTER_API_KEYS:"",CLAUDE_MEM_OPENROUTER_MODEL:"cohere/north-mini-code:free",CLAUDE_MEM_OPENROUTER_BASE_URL:"",CLAUDE_MEM_OPENROUTER_TEMPERATURE:"",CLAUDE_MEM_OPENROUTER_SITE_URL:"",CLAUDE_MEM_OPENROUTER_APP_NAME:"claude-mem",CLAUDE_MEM_OPENROUTER_EXTRA_BODY:"",CLAUDE_MEM_OPENROUTER_REASONING_EFFORT:"",CLAUDE_MEM_OPENAI_COMPAT_PRESET:"",CLAUDE_MEM_OPENAI_COMPAT_API_KEY:"",CLAUDE_MEM_OPENAI_COMPAT_API_KEYS:"",CLAUDE_MEM_OPENAI_COMPAT_BASE_URL:"",CLAUDE_MEM_OPENAI_COMPAT_MODEL:"",CLAUDE_MEM_QUOTA_FALLBACK_PROVIDER:"",CLAUDE_MEM_QUOTA_FALLBACK_MODEL:"",CLAUDE_MEM_QUOTA_THRESHOLD_FIVE_HOUR:"0.95",CLAUDE_MEM_QUOTA_THRESHOLD_SEVEN_DAY:"0.93",CLAUDE_MEM_QUOTA_THRESHOLD_SEVEN_DAY_OPUS:"0.93",CLAUDE_MEM_QUOTA_THRESHOLD_SEVEN_DAY_SONNET:"0.92",CLAUDE_MEM_QUOTA_THRESHOLD_OVERAGE:"0.95",CLAUDE_MEM_DATA_DIR:(0,k.join)((0,te.homedir)(),".claude-mem"),CLAUDE_MEM_LOG_LEVEL:"INFO",CLAUDE_MEM_PYTHON_VERSION:"3.13",CLAUDE_CODE_PATH:"",CLAUDE_MEM_CLAUDE_CONFIG_DIR:"",CLAUDE_MEM_OBSERVER_CLAUDE_CONFIG_DIR:"",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_OBSERVATION_TYPES:"",CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS:"",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_MAIN_AGENT_ONLY:"true",CLAUDE_MEM_REINFORCE_ALPHA:"0",CLAUDE_MEM_CONTEXT_SHOW_TERMINAL_OUTPUT:"true",CLAUDE_MEM_WELCOME_HINT_ENABLED:"true",CLAUDE_MEM_WORK_STATE_ENABLED:"true",CLAUDE_MEM_FILE_READ_GATE_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,k.join)((0,te.homedir)(),".claude-mem","transcript-watch.json"),CLAUDE_MEM_CODEX_TRANSCRIPT_INGESTION:"false",CLAUDE_MEM_CODEX_SUBAGENT_INGESTION:"false",CLAUDE_MEM_MAX_CONCURRENT_AGENTS:"2",CLAUDE_MEM_OBSERVER_MAX_CONVERSATION_CHARS:"400000",CLAUDE_MEM_OBSERVER_CONTEXT_WINDOW:"",CLAUDE_MEM_OBSERVER_MAX_OUTPUT_TOKENS:"4096",CLAUDE_MEM_OBSERVE_BARE_PROMPTS:"false",CLAUDE_MEM_HOOK_FAIL_LOUD_THRESHOLD:"3",CLAUDE_MEM_REDACT_ENABLED:"false",CLAUDE_MEM_REDACT_DISABLED_BUILTINS:"",CLAUDE_MEM_REDACT_CUSTOM_PATTERNS:"[]",CLAUDE_MEM_REDACT_LOG_MATCHES:"false",CLAUDE_MEM_EXCLUDED_PROJECTS:"",CLAUDE_MEM_PROJECT_ENVIRONMENTS:"[]",CLAUDE_MEM_FOLDER_MD_EXCLUDE:"[]",CLAUDE_MEM_FOLDER_MD_SKELETON_DENYLIST:"[]",CLAUDE_MEM_SEMANTIC_INJECT:"false",CLAUDE_MEM_SEMANTIC_INJECT_LIMIT:"5",CLAUDE_MEM_SEMANTIC_INJECT_FORMAT:"narrative",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_CHROMA_MUTATION_TIMEOUT_MS:"600000",CLAUDE_MEM_CHROMA_MAX_PENDING_MUTATIONS:"5000",CLAUDE_MEM_CHROMA_EMBEDDING_FUNCTION:"default",CLAUDE_MEM_CHROMA_UVX_PATH:"",CLAUDE_MEM_CLOUD_SYNC_TOKEN:"",CLAUDE_MEM_CLOUD_SYNC_USER_ID:"",CLAUDE_MEM_CLOUD_SYNC_HUB_URL:"",CLAUDE_MEM_CLOUD_SYNC_DEVICE_ID:"",CLAUDE_MEM_CLOUD_SYNC_DEVICE_NAME:(0,te.hostname)(),CLAUDE_MEM_CLOUD_SYNC_WS:"true",CLAUDE_MEM_CLOUD_SYNC_CONTENT_BATCH_SIZE:"40",CLAUDE_MEM_CLOUD_SYNC_REQUEST_TIMEOUT_MS:"90000",CLAUDE_MEM_LLM_TIMEOUT_MS:String(yt),CLAUDE_MEM_FIELD_OPTIMIZE_TIMEOUT_MS:String(yt),CLAUDE_MEM_TV_TOKEN:"",CLAUDE_MEM_PRO_TRIAL_EMAIL:"",CLAUDE_MEM_PRO_TRIAL_AT:"",CLAUDE_MEM_PRO_TRIAL_STATE:"",CLAUDE_MEM_PRO_TRIAL_ENDS_AT:"",CLAUDE_MEM_PRO_PLAN:"",CLAUDE_MEM_PRO_FALLBACK_AT:"",CLAUDE_MEM_PRO_FALLBACK_MESSAGE:"",CLAUDE_MEM_PRO_FALLBACK_ACTION:"",CLAUDE_MEM_PRO_FALLBACK_URL:"",CLAUDE_MEM_PRO_MEMORY_KEY:"",CLAUDE_MEM_PRO_MEMORY_BASE_URL:"",CLAUDE_MEM_PRO_MEMORY_MODEL:"",CLAUDE_MEM_TELEGRAM_ENABLED:"true",CLAUDE_MEM_TELEGRAM_BOT_TOKEN:"",CLAUDE_MEM_TELEGRAM_CHAT_ID:"",CLAUDE_MEM_TELEGRAM_WRAPUPS_ENABLED:"true",CLAUDE_MEM_TELEGRAM_OBSERVATION_ALERTS_ENABLED:"false",CLAUDE_MEM_TELEGRAM_WRAPUP_ROUTES:"{}",CLAUDE_MEM_TELEGRAM_TRIGGER_TYPES:"security_alert,sensitive",CLAUDE_MEM_TELEGRAM_TRIGGER_CONCEPTS:"",CLAUDE_MEM_GROK_BOT_AWARENESS_ENABLED:"true",CLAUDE_MEM_GROK_BOT_AWARENESS_AGENT_IDS:"521e962d-2ec3-4488-bfbc-54d5209ce118,95601360-61f7-4fd9-bb3a-2c976b2b85c0",CLAUDE_MEM_GROK_BOT_AWARENESS_TRIGGER_TYPES:"decision,bugfix,security_alert,sensitive",CLAUDE_MEM_GROK_BOT_AWARENESS_TRIGGER_CONCEPTS:"",CLAUDE_MEM_GROK_BOT_WEBHOOK_URL:"",CLAUDE_MEM_GROK_BOT_WEBHOOK_SECRET:"",CLAUDE_MEM_GROK_BOT_INJECT_ENABLED:"true",CLAUDE_MEM_GROK_BOT_INJECT_AGENT_IDS:"*",CLAUDE_MEM_GROK_BOT_INJECT_TIER:"episode",CLAUDE_MEM_GROK_BOT_INJECT_WINDOW:"80",CLAUDE_MEM_GROK_BOT_INJECT_FALLBACK:"house",CLAUDE_MEM_GROK_BOT_INJECT_PLATFORM_SOURCE:"",CLAUDE_MEM_GROK_BOT_INJECT_PROJECTS_BY_AGENT:"",CLAUDE_MEM_GROK_BOT_INJECT_MAX_LINE_CHARS:"160",CLAUDE_MEM_GROK_BOT_INJECT_DEBOUNCE_MS:"1500",CLAUDE_MEM_GROK_BOT_INJECT_STANDING_LINE:"",CLAUDE_MEM_CCS_ALIGN_ENABLED:"true",CLAUDE_MEM_CCS_ALIGN_VIEWER_IDS:"ccs-align",CLAUDE_MEM_CCS_ALIGN_TRIGGER_TYPES:"decision,bugfix,security_alert,sensitive",CLAUDE_MEM_CCS_ALIGN_PATCH_SHADOWS:"false",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:"",CLAUDE_MEM_DEDUP_ENABLED:"false",CLAUDE_MEM_DEDUP_COSINE_THRESHOLD:"0.80",CLAUDE_MEM_DEDUP_IDF_VETO_DF:"10",CLAUDE_MEM_DEDUP_MIN_SHARED_TOKENS:"2",CLAUDE_MEM_DEDUP_MIN_PROJECT_DOCS:"10",CLAUDE_MEM_DEDUP_MAX_SCAN:"2000",CLAUDE_MEM_DEDUP_MAX_BACKFILL_ROWS:"50000",CLAUDE_MEM_TOOL_USES_RETENTION_DAYS:"0",CLAUDE_MEM_WORKER_AUTOSTART:"true",CLAUDE_MEM_PROJECT_NAME_SOURCE:"path"};static getAllDefaults(){return{...this.DEFAULTS}}static get(e){let t=process.env[e]??this.DEFAULTS[e];return e==="CLAUDE_MEM_WORKER_HOST"?this.normalizeWorkerHost(t):t}static normalizeWorkerHost(e){return e==="localhost"?"127.0.0.1":e}static finalizeSettings(e,t){let s=t?this.applyEnvOverrides(e):e;return s.CLAUDE_MEM_WORKER_HOST=this.normalizeWorkerHost(s.CLAUDE_MEM_WORKER_HOST),s}static getInt(e){let t=this.get(e);return parseInt(t,10)}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,s={}){try{if(!(0,G.existsSync)(e)){let l=this.getAllDefaults();if(!s.readOnly)try{P(e,l,{mode:384});for(let p of vt)Ge(e,p);console.warn("[SETTINGS] Created settings file with defaults:",e)}catch(p){console.warn("[SETTINGS] Failed to create settings file, using in-memory defaults:",e,p instanceof Error?p.message:String(p))}return this.finalizeSettings(l,t)}let n=(0,G.readFileSync)(e,"utf-8"),i=ye(n),r=K(i),a=r!==i,_=rt(i),E=a&&Object.keys(_).some(l=>l!=="env");if(a&&!E&&!s.readOnly)try{P(e,r,{mode:384}),console.warn("[SETTINGS] Migrated settings file from nested to flat schema:",e)}catch(l){console.warn("[SETTINGS] Failed to auto-migrate settings file:",e,l instanceof Error?l.message:String(l))}if(r.CLAUDE_MEM_TELEGRAM_TRIGGER_TYPES===Ps&&(r={...r,CLAUDE_MEM_TELEGRAM_TRIGGER_TYPES:this.DEFAULTS.CLAUDE_MEM_TELEGRAM_TRIGGER_TYPES},!s.readOnly))try{P(e,E?{..._,env:r}:r,{mode:384}),console.warn("[SETTINGS] Migrated Telegram trigger types off the legacy default:",e)}catch(l){console.warn("[SETTINGS] Failed to migrate Telegram trigger types:",e,l instanceof Error?l.message:String(l))}if(Hs(r)){let l=String(r.CLAUDE_MEM_OPENROUTER_MODEL).trim();if(r={...r,CLAUDE_MEM_OPENROUTER_MODEL:this.DEFAULTS.CLAUDE_MEM_OPENROUTER_MODEL},!s.readOnly)try{P(e,E?{..._,env:r}:r,{mode:384}),console.warn(`[SETTINGS] Migrated OpenRouter model off the retired default ${l} to ${this.DEFAULTS.CLAUDE_MEM_OPENROUTER_MODEL}:`,e)}catch(p){console.warn("[SETTINGS] Failed to migrate the retired OpenRouter model:",e,p instanceof Error?p.message:String(p))}}let d=$s(r.CLAUDE_MEM_CLOUD_SYNC_HUB_URL);if(d!==null&&(r={...r,CLAUDE_MEM_CLOUD_SYNC_HUB_URL:d},!s.readOnly))try{P(e,E?{..._,env:r}:r,{mode:384}),console.warn("[SETTINGS] Migrated cloud sync hub URL to",d,"from a retired hub host:",e)}catch(l){console.warn("[SETTINGS] Failed to migrate cloud sync hub URL:",e,l instanceof Error?l.message:String(l))}for(let l of vt)if(!(0,G.existsSync)(wt(e,l))){if(r[l.key]!==l.legacy){s.readOnly||Ge(e,l);continue}if(r={...r,[l.key]:this.DEFAULTS[l.key]},!s.readOnly)try{P(e,E?{..._,env:r}:r,{mode:384}),Ge(e,l),console.warn(`[SETTINGS] Migrated ${l.key} off the old ${l.legacy}ms default to ${this.DEFAULTS[l.key]}ms:`,e)}catch(p){let S=`${l.key}\0${e}`;Ft.has(S)||(Ft.add(S),console.warn(`[SETTINGS] Failed to migrate ${l.key}; using the new default in memory (reported once per process):`,e,p instanceof Error?p.message:String(p)))}}let u={...this.DEFAULTS};for(let l of Object.keys(this.DEFAULTS))r[l]!==void 0&&(u[l]=Gs(r[l]));return this.finalizeSettings(u,t)}catch(n){console.warn("[SETTINGS] Failed to load settings, using defaults:",e,n instanceof Error?n.message:String(n));let i=this.getAllDefaults();return this.finalizeSettings(i,t)}}};var Xt=require("crypto");function se(o){let e=(o??"").normalize("NFC").toLowerCase().replace(/[^\p{L}\p{N}\p{M}\s]/gu," ").replace(/\s+/g," ").trim();return/[\p{L}\p{N}]/u.test(e)?e:""}function H(o){return(o??"").toLowerCase().trim().split(/\s+/).filter(Boolean)}function He(o,e){return Math.log(1+e/(o+.5))}function Pt(o,e){return t=>He(o(t),e)}function xt(o,e){let t=new Map;for(let s of new Set(o))t.set(s,e(s));return t}function kt(o,e,t){let s=xt(o,t),n=xt(e,t),i=0,r=0,a=0;for(let[_,E]of s){r+=E*E;let d=n.get(_);d!==void 0&&(i+=E*d)}for(let[,_]of n)a+=_*_;return r===0||a===0?0:i/Math.sqrt(r*a)}function Bt(o,e,t,s){let n=new Set(o),i=new Set(e);for(let r of n)if(!i.has(r)&&t(r)>s)return!0;for(let r of i)if(!n.has(r)&&t(r)>s)return!0;return!1}function $e(o,e,t,s){let n=se(o);if(n!==""&&n===se(e))return{tier:"exact",method:"exact",score:1};let i=H(o),r=H(e),a=s.minSharedTokens??2,_=new Set(r),E=0;for(let u of new Set(i))_.has(u)&&E++;if(E<a)return{tier:"none",method:"none",score:0};let d=kt(i,r,t);return d>=s.cosineThreshold&&!Bt(i,r,t,s.vetoThetaIdf)?{tier:"candidate",method:"idf_cosine",score:d}:{tier:"none",method:"none",score:d}}function ne(o,e){return!!o&&!!e}function ge(o,e,t,s=!1){let n=se(t);if(n==="")return null;let i=b(e),r=s?"subagent":"main";return(0,Xt.createHash)("sha256").update(`${o}\0${i}\0${r}\0${n}`).digest("hex").slice(0,32)}function Gt(o,e,t){return t===null?null:o.prepare("SELECT id, occurrence_count, created_at_epoch FROM observations WHERE project = ? AND title_norm_key = ? ORDER BY created_at_epoch ASC, id ASC LIMIT 1").get(e,t)??null}function Ht(o,e,t){let s=[...new Set(H(t))],n=o.prepare("INSERT INTO token_df (project, token, df) VALUES (?, ?, 1) ON CONFLICT(project, token) DO UPDATE SET df = df + 1");for(let i of s)n.run(e,i);o.prepare("INSERT INTO dedup_meta (project, doc_count) VALUES (?, 1) ON CONFLICT(project) DO UPDATE SET doc_count = doc_count + 1").run(e)}function $t(o,e){return He(o+1,e)}function jt(o,e){return o.prepare("SELECT doc_count FROM dedup_meta WHERE project = ?").get(e)?.doc_count??0}function Wt(o,e){let t=jt(o,e),s=o.prepare("SELECT token, df FROM token_df WHERE project = ?").all(e),n=new Map(s.map(i=>[i.token,i.df]));return{idfFn:Pt(i=>n.get(i)??0,t),docCount:t}}function Kt(o){return o.prepare("INSERT OR IGNORE INTO observation_dedup_candidates (observation_id, duplicate_of_id, project, method, score, status, created_at, created_at_epoch) VALUES (?, ?, ?, ?, ?, ?, ?, ?)")}function Yt(o,e,t){return jt(o,e)>=t}function js(o,e,t=Number.POSITIVE_INFINITY){let s=o.prepare("SELECT COUNT(*) c FROM observations WHERE project = ?").get(e).c;if(s>t)return c.warn("DEDUP",`Skipping dedup backfill for project ${e}: ${s} rows exceeds cap ${t} (CLAUDE_MEM_DEDUP_MAX_BACKFILL_ROWS)`),0;let n=o.prepare("SELECT o.id, o.title, o.agent_id, o.agent_type, s.platform_source FROM observations o LEFT JOIN sdk_sessions s ON s.memory_session_id = o.memory_session_id WHERE o.project = ?").all(e),i=o.prepare("UPDATE observations SET title_norm_key = ? WHERE id = ?"),r=o.prepare("INSERT INTO token_df (project, token, df) VALUES (?, ?, ?)");return o.transaction(()=>{let _=new Map;for(let E of n){i.run(ge(e,E.platform_source,E.title,ne(E.agent_id,E.agent_type)),E.id);for(let d of new Set(H(E.title)))_.set(d,(_.get(d)??0)+1)}o.prepare("DELETE FROM token_df WHERE project = ?").run(e);for(let[E,d]of _)r.run(e,E,d);o.prepare("INSERT INTO dedup_meta (project, doc_count, last_rebuild_doc_count, deleted_since_rebuild) VALUES (?, ?, ?, 0) ON CONFLICT(project) DO UPDATE SET doc_count = excluded.doc_count, last_rebuild_doc_count = excluded.last_rebuild_doc_count, deleted_since_rebuild = 0").run(e,n.length,n.length)})(),n.length}function Ws(o,e,t){let s=o.prepare("SELECT id, title FROM observations WHERE project = ? AND title IS NOT NULL ORDER BY id ASC").all(e);if(s.length<2)return 0;if(s.length>t.maxBackfillRows)return c.warn("DEDUP",`Skipping dedup sweep for project ${e}: ${s.length} rows exceeds cap ${t.maxBackfillRows}`),0;let{idfFn:n,docCount:i}=Wt(o,e),r={cosineThreshold:t.cosineThreshold,vetoThetaIdf:$t(t.idfVetoDf,i),minSharedTokens:t.minSharedTokens},a=s.map(f=>new Set(H(f.title))),_=new Map;for(let f of a)for(let C of f)_.set(C,(_.get(C)??0)+1);let E=Math.max(2,Math.ceil(Math.sqrt(s.length))*4),d=new Map;a.forEach((f,C)=>{for(let R of f){let m=_.get(R);if(m<2||m>E)continue;let A=d.get(R);A||(A=[],d.set(R,A)),A.push(C)}});let u=new Map;for(let f of d.values())for(let C=0;C<f.length;C++)for(let R=C+1;R<f.length;R++){let m=`${f[C]}:${f[R]}`;u.set(m,(u.get(m)??0)+1)}let l=Kt(o),p=new Date().toISOString(),S=Date.now(),h=0;for(let[f,C]of u){if(C<t.minSharedTokens)continue;let[R,m]=f.split(":").map(Number),A=$e(s[R].title,s[m].title,n,r);A.tier==="candidate"&&(h+=l.run(s[m].id,s[R].id,e,A.method,A.score,"pending",p,S).changes)}return h}function Vt(o,e){return o.prepare("SELECT DISTINCT project FROM observations").all().map(s=>s.project).map(s=>{let n=js(o,s,e.maxBackfillRows),i=Ws(o,s,e);return{project:s,docs:n,candidates:i}})}function qt(o,e,t,s,n){if(!s)return 0;let{idfFn:i,docCount:r}=Wt(o,e),a={cosineThreshold:n.cosineThreshold,vetoThetaIdf:$t(n.idfVetoDf,r),minSharedTokens:n.minSharedTokens},_=o.prepare("SELECT id, title FROM observations WHERE project = ? AND id != ? AND title IS NOT NULL ORDER BY created_at_epoch DESC, id DESC LIMIT ?").all(e,t,n.maxScan);_.length===n.maxScan&&c.debug("DEDUP",`Tier-1 scan hit MAX_SCAN=${n.maxScan} for project ${e}; older rows covered by dedup-scan`);let E=Kt(o),d=new Date().toISOString(),u=Date.now(),l=0;for(let p of _){let S=$e(s,p.title,i,a);S.tier==="candidate"&&(l+=E.run(t,p.id,e,S.method,S.score,"pending",d,u).changes)}return l}function Jt(o,e,t,s,n){let i=Date.now()-s,r=n!==void 0?"up.session_db_id = ?":"up.content_session_id = ?",a=n??e;return o.prepare(`
108
108
  SELECT
109
109
  up.*,
110
110
  s.memory_session_id,
111
111
  s.project,
112
- COALESCE(s.platform_source, '${p}') as platform_source
112
+ COALESCE(s.platform_source, '${T}') as platform_source
113
113
  FROM user_prompts up
114
114
  JOIN sdk_sessions s ON up.session_db_id = s.id
115
- WHERE ${o}
115
+ WHERE ${r}
116
116
  AND up.prompt_text = ?
117
117
  AND up.created_at_epoch >= ?
118
118
  ORDER BY up.created_at_epoch DESC
119
119
  LIMIT 1
120
- `).get(a,t,i)??void 0}var me=require("fs");var Ps=[{name:"aws_access_key",regex:/AKIA[0-9A-Z]{16}/g},{name:"aws_secret_key",regex:/(?<=AWS_SECRET_ACCESS_KEY\s*[=:]\s*['"]?)[A-Za-z0-9/+=]{40}/g},{name:"github_pat",regex:/\bgh[oprs]_[A-Za-z0-9]{36}\b|\bgithub_pat_[A-Za-z0-9_]{82}\b/g},{name:"openai_key",regex:/\bsk-(?!ant-)[A-Za-z0-9_-]{20,}\b/g},{name:"anthropic_key",regex:/\bsk-ant-[A-Za-z0-9_-]{20,}\b/g},{name:"slack_token",regex:/\bxox[baprs]-[A-Za-z0-9-]{10,}\b/g},{name:"jwt",regex:/\beyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\b/g},{name:"private_key_pem",regex:/-----BEGIN (?:RSA |DSA |EC |OPENSSH |PGP )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |DSA |EC |OPENSSH |PGP )?PRIVATE KEY-----/g},{name:"stripe_key",regex:/\b(?:sk|pk|rk)_(?:live|test)_[A-Za-z0-9]{24,}\b/g},{name:"google_api_key",regex:/\bAIza[0-9A-Za-z_-]{35}\b/g},{name:"claude_mem_key",regex:/\bcmem_[A-Za-z0-9_-]{32,}|\bcm_pro_[A-Za-z0-9_-]{8,}/g}],xs=1024*1024,ks="<redacted type='oversize'/>";function Kt(r,e){if(!e.enabled||r.length===0)return{redacted:r,counts:{},oversize:!1};if(r.length>xs)return u.warn("REDACT","field exceeds the 1M-char redaction cap; replaced by an oversize marker",void 0,{inputLength:r.length}),{redacted:ks,counts:{oversize:1},oversize:!0};let t=new Set(e.disabledBuiltinPatterns??[]),s={},n=r,i=[];for(let a of e.customPatterns??[]){if(!a.name||a.name.length===0){u.warn("REDACT","custom pattern skipped: missing name",void 0,{pattern:a});continue}try{i.push({name:a.name,regex:new RegExp(a.regex,"g")})}catch(_){u.warn("REDACT","custom pattern skipped: invalid regex",{name:a.name},_ instanceof Error?_:new Error(String(_)))}}let o=[...i,...Ps];for(let a of o)t.has(a.name)||(a.regex.lastIndex=0,n=n.replace(a.regex,()=>(s[a.name]=(s[a.name]??0)+1,`<redacted type='${a.name}'/>`)));return e.logMatches&&Object.keys(s).length>0&&u.debug("REDACT","patterns matched",void 0,{counts:s}),{redacted:n,counts:s,oversize:!1}}function Bs(r){if(!r||r.trim()==="")return[];try{let e=JSON.parse(r);return Array.isArray(e)?e.filter(t=>t&&typeof t.name=="string"&&typeof t.regex=="string"):(u.warn("REDACT","CLAUDE_MEM_REDACT_CUSTOM_PATTERNS is not a JSON array, ignoring"),[])}catch(e){return u.warn("REDACT","failed to parse CLAUDE_MEM_REDACT_CUSTOM_PATTERNS as JSON",void 0,e instanceof Error?e:new Error(String(e))),[]}}function Xs(r){return{enabled:r.CLAUDE_MEM_REDACT_ENABLED==="true",disabledBuiltinPatterns:(r.CLAUDE_MEM_REDACT_DISABLED_BUILTINS??"").split(",").map(e=>e.trim()).filter(Boolean),customPatterns:Bs(r.CLAUDE_MEM_REDACT_CUSTOM_PATTERNS??"[]"),logMatches:r.CLAUDE_MEM_REDACT_LOG_MATCHES==="true"}}var te=null,$t=0,Gs=5e3,se=null,Wt=!1,Hs={enabled:!0,disabledBuiltinPatterns:[],customPatterns:[],logMatches:!1},js=/"CLAUDE_MEM_REDACT_ENABLED"\s*:\s*"true"/;function $s(r){if(!(0,me.existsSync)(r))return null;try{return(0,me.readFileSync)(r,"utf-8")}catch{return""}}function Ws(r){if(r===null)return!1;try{let e=JSON.parse(Le(r));return e===null||typeof e!="object"||Array.isArray(e)}catch{return!0}}function Ks(r,e,t){return process.env.CLAUDE_MEM_REDACT_ENABLED==="false"||!(se?.enabled===!0||js.test(e))?t:(Wt||(Wt=!0,u.warn("REDACT","settings.json could not be read; secret redaction stays on until it is repaired",{settingsPath:r,using:se?.enabled?"the last configuration that loaded":"the built-in patterns"})),se?.enabled?se:Hs)}function Yt(r=_e){let e=Date.now();if(te&&e-$t<Gs)return te;let t=Y.loadFromFile(r),s=Xs(t),n=s.enabled?null:$s(r);return Ws(n)?te=Ks(r,n,s):(te=s,se=s),$t=e,te}var Jt=["private","claude-mem-context","system_instruction","system-instruction","persisted-output","system-reminder"],Vt=new RegExp(`<(${Jt.join("|")})\\b[^>]*>[\\s\\S]*?</\\1>`,"g");var qt=100;function Ys(r){let e=Object.fromEntries(Jt.map(i=>[i,0]));Vt.lastIndex=0;let t=0,s=r.replace(Vt,(i,o)=>(e[o]=(e[o]??0)+1,t+=1,""));return t>qt&&u.warn("SYSTEM","tag count exceeds limit",void 0,{tagCount:t,maxAllowed:qt,contentLength:r.length}),{stripped:Kt(s.trim(),Yt()).redacted,counts:e}}function Te(r){return Ys(r).stripped}var Vs=["task-notification"],br=new RegExp(`^\\s*<(${Vs.join("|")})\\b[^>]*>(?:(?!<\\1\\b|</\\1\\b)[\\s\\S])*</\\1>\\s*$`),Cr=256*1024;var ke=4e3,Be="[media prompt]";function ne(r){let e=r.trim(),s=Te(r).trim()||e;return s.length<=ke?s:(u.debug("DB","Truncated stored prompt text to the configured cap",{originalLength:s.length,storedLength:ke}),`${s.slice(0,ke-1)}\u2026`)}var qs=require("bun:sqlite");var Js=5e3,zs=4194304;function Qs(r){return r.prepare(`
120
+ `).get(a,t,i)??void 0}var Oe=require("fs");var Ks=[{name:"aws_access_key",regex:/AKIA[0-9A-Z]{16}/g},{name:"aws_secret_key",regex:/(?<=AWS_SECRET_ACCESS_KEY\s*[=:]\s*['"]?)[A-Za-z0-9/+=]{40}/g},{name:"github_pat",regex:/\bgh[oprs]_[A-Za-z0-9]{36}\b|\bgithub_pat_[A-Za-z0-9_]{82}\b/g},{name:"openai_key",regex:/\bsk-(?!ant-)[A-Za-z0-9_-]{20,}\b/g},{name:"anthropic_key",regex:/\bsk-ant-[A-Za-z0-9_-]{20,}\b/g},{name:"slack_token",regex:/\bxox[baprs]-[A-Za-z0-9-]{10,}\b/g},{name:"jwt",regex:/\beyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\b/g},{name:"private_key_pem",regex:/-----BEGIN (?:RSA |DSA |EC |OPENSSH |PGP )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |DSA |EC |OPENSSH |PGP )?PRIVATE KEY-----/g},{name:"stripe_key",regex:/\b(?:sk|pk|rk)_(?:live|test)_[A-Za-z0-9]{24,}\b/g},{name:"google_api_key",regex:/\bAIza[0-9A-Za-z_-]{35}\b/g},{name:"claude_mem_key",regex:/\bcmem_[A-Za-z0-9_-]{32,}|\bcm_pro_[A-Za-z0-9_-]{8,}/g}],Ys=1024*1024,Vs="<redacted type='oversize'/>";function Zt(o,e){if(!e.enabled||o.length===0)return{redacted:o,counts:{},oversize:!1};if(o.length>Ys)return c.warn("REDACT","field exceeds the 1M-char redaction cap; replaced by an oversize marker",void 0,{inputLength:o.length}),{redacted:Vs,counts:{oversize:1},oversize:!0};let t=new Set(e.disabledBuiltinPatterns??[]),s={},n=o,i=[];for(let a of e.customPatterns??[]){if(!a.name||a.name.length===0){c.warn("REDACT","custom pattern skipped: missing name",void 0,{pattern:a});continue}try{i.push({name:a.name,regex:new RegExp(a.regex,"g")})}catch(_){c.warn("REDACT","custom pattern skipped: invalid regex",{name:a.name},_ instanceof Error?_:new Error(String(_)))}}let r=[...i,...Ks];for(let a of r)t.has(a.name)||(a.regex.lastIndex=0,n=n.replace(a.regex,()=>(s[a.name]=(s[a.name]??0)+1,`<redacted type='${a.name}'/>`)));return e.logMatches&&Object.keys(s).length>0&&c.debug("REDACT","patterns matched",void 0,{counts:s}),{redacted:n,counts:s,oversize:!1}}function qs(o){if(!o||o.trim()==="")return[];try{let e=JSON.parse(o);return Array.isArray(e)?e.filter(t=>t&&typeof t.name=="string"&&typeof t.regex=="string"):(c.warn("REDACT","CLAUDE_MEM_REDACT_CUSTOM_PATTERNS is not a JSON array, ignoring"),[])}catch(e){return c.warn("REDACT","failed to parse CLAUDE_MEM_REDACT_CUSTOM_PATTERNS as JSON",void 0,e instanceof Error?e:new Error(String(e))),[]}}function Js(o){return{enabled:o.CLAUDE_MEM_REDACT_ENABLED==="true",disabledBuiltinPatterns:(o.CLAUDE_MEM_REDACT_DISABLED_BUILTINS??"").split(",").map(e=>e.trim()).filter(Boolean),customPatterns:qs(o.CLAUDE_MEM_REDACT_CUSTOM_PATTERNS??"[]"),logMatches:o.CLAUDE_MEM_REDACT_LOG_MATCHES==="true"}}var re=null,zt=0,zs=5e3,oe=null,Qt=!1,Qs={enabled:!0,disabledBuiltinPatterns:[],customPatterns:[],logMatches:!1},Zs=/"CLAUDE_MEM_REDACT_ENABLED"\s*:\s*"true"/;function en(o){if(!(0,Oe.existsSync)(o))return null;try{return(0,Oe.readFileSync)(o,"utf-8")}catch{return""}}function tn(o){if(o===null)return!1;try{let e=JSON.parse(Ue(o));return e===null||typeof e!="object"||Array.isArray(e)}catch{return!0}}function sn(o,e,t){return process.env.CLAUDE_MEM_REDACT_ENABLED==="false"||!(oe?.enabled===!0||Zs.test(e))?t:(Qt||(Qt=!0,c.warn("REDACT","settings.json could not be read; secret redaction stays on until it is repaired",{settingsPath:o,using:oe?.enabled?"the last configuration that loaded":"the built-in patterns"})),oe?.enabled?oe:Qs)}function es(o=pe){let e=Date.now();if(re&&e-zt<zs)return re;let t=Y.loadFromFile(o),s=Js(t),n=s.enabled?null:en(o);return tn(n)?re=sn(o,n,s):(re=s,oe=s),zt=e,re}var ns=["private","claude-mem-context","system_instruction","system-instruction","persisted-output","system-reminder"],ts=new RegExp(`<(${ns.join("|")})\\b[^>]*>[\\s\\S]*?</\\1>`,"g");var ss=100;function nn(o){let e=Object.fromEntries(ns.map(i=>[i,0]));ts.lastIndex=0;let t=0,s=o.replace(ts,(i,r)=>(e[r]=(e[r]??0)+1,t+=1,""));return t>ss&&c.warn("SYSTEM","tag count exceeds limit",void 0,{tagCount:t,maxAllowed:ss,contentLength:o.length}),{stripped:Zt(s.trim(),es()).redacted,counts:e}}function fe(o){return nn(o).stripped}var rn=["task-notification"],kr=new RegExp(`^\\s*<(${rn.join("|")})\\b[^>]*>(?:(?!<\\1\\b|</\\1\\b)[\\s\\S])*</\\1>\\s*$`),Br=256*1024;var je=4e3,We="[media prompt]";function ie(o){let e=o.trim(),s=fe(o).trim()||e;return s.length<=je?s:(c.debug("DB","Truncated stored prompt text to the configured cap",{originalLength:s.length,storedLength:je}),`${s.slice(0,je-1)}\u2026`)}var on=require("bun:sqlite");var an=5e3,_n=4194304,q=65;function En(o){return o.prepare("PRAGMA user_version").get().user_version}var Ke=class extends Error{reason="schema_newer_than_binary";constructor(e){super(e),this.name="SchemaNewerThanBinaryError"}};function Re(o,e){let t=En(o);if(!(t<=e))throw new Ke(`SQLite database has schema v${t}; this claude-mem knows up to schema v${e}. Upgrade claude-mem before opening this database.`)}function Ne(o,e){o.run(`PRAGMA user_version = ${e}`)}function dn(o){return o.prepare(`
121
121
  SELECT name
122
122
  FROM sqlite_master
123
123
  WHERE type = 'table'
124
124
  AND name NOT LIKE 'sqlite_%'
125
125
  LIMIT 1
126
- `).get()!=null}function V(r,e,t){try{r.run(e)}catch(s){let n=s instanceof Error?s:new Error(String(s));throw u.warn("DB",`Failed to apply SQLite pragma ${t}`,{sql:e},n),s}}function Se(r,e={}){let{enableWal:t=!0,enableIncrementalAutoVacuum:s=!0}=e;V(r,`PRAGMA busy_timeout = ${Js}`,"busy_timeout"),V(r,"PRAGMA foreign_keys = ON","foreign_keys"),V(r,"PRAGMA synchronous = NORMAL","synchronous"),V(r,`PRAGMA journal_size_limit = ${zs}`,"journal_size_limit"),s&&!Qs(r)&&V(r,"PRAGMA auto_vacuum = INCREMENTAL","auto_vacuum"),t&&V(r,"PRAGMA journal_mode = WAL","journal_mode")}var zt=!1;function Xe(r,...e){return typeof r.iterate=="function"?r.iterate(...e):(zt||(zt=!0,u.warn("DB","bun:sqlite lacks Statement.iterate(); falling back to .all()",{bunVersion:typeof Bun<"u"?Bun.version:"unknown",requiredBunVersion:">=1.1.31",impact:"rows are materialized in memory; upgrade Bun to restore streaming"})),r.all(...e))}function Ge(r,e,t,s){try{let n=Number(s.limit);if(!Number.isInteger(n)||n<0)throw new Error("Page limit must be a non-negative integer");let i=Number(s.offset??0);if(!Number.isInteger(i))throw new Error("Page offset must be an integer");let o=[];if(n===0)return o;let a=Math.max(0,i);for(let _ of Xe(r,...e))if(t(_)){if(a>0){a--;continue}if(o.push(_),o.length===n)break}return o}finally{r.finalize()}}var $e=require("bun:sqlite");function Ae(r){return r.replace(/\\/g,"/").replace(/\/+/g,"/").replace(/\/+$/,"")}function He(r,e){let t=Ae(r),s=Ae(e);if(t.startsWith(s+"/"))return!t.slice(s.length+1).includes("/");let n=s.split("/"),i=t.split("/");if(i.length<2)return s===""||s===".";let o=i.slice(0,-1).join("/"),a=i[i.length-1];if(s.endsWith("/"+o)||s===o)return!a.includes("/");for(let _=0;_<n.length;_++)if(n.slice(_).join("/")===o)return!0;return!1}var Zs=/^\d{4}-\d{2}-\d{2}$/;function j(r,e){if(typeof r=="number")return r;let t=new Date(r).getTime();return e==="end"&&Zs.test(r.trim())?t+864e5-1:t}var je="\\u0E00-\\u0EFF\\u1000-\\u109F\\u1780-\\u17FF\\u3040-\\u30FF\\u3100-\\u318F\\u3400-\\u4DBF\\u4E00-\\u9FFF\\uAC00-\\uD7AF\\uF900-\\uFAFF",Oe=`
126
+ `).get()!=null}function V(o,e,t){try{o.run(e)}catch(s){let n=s instanceof Error?s:new Error(String(s));throw c.warn("DB",`Failed to apply SQLite pragma ${t}`,{sql:e},n),s}}function be(o,e={}){let{enableWal:t=!0,enableIncrementalAutoVacuum:s=!0}=e;V(o,`PRAGMA busy_timeout = ${an}`,"busy_timeout"),V(o,"PRAGMA foreign_keys = ON","foreign_keys"),V(o,"PRAGMA synchronous = NORMAL","synchronous"),V(o,`PRAGMA journal_size_limit = ${_n}`,"journal_size_limit"),s&&!dn(o)&&V(o,"PRAGMA auto_vacuum = INCREMENTAL","auto_vacuum"),t&&V(o,"PRAGMA journal_mode = WAL","journal_mode")}var rs=!1;function Ce(o,...e){return typeof o.iterate=="function"?o.iterate(...e):(rs||(rs=!0,c.warn("DB","bun:sqlite lacks Statement.iterate(); falling back to .all()",{bunVersion:typeof Bun<"u"?Bun.version:"unknown",requiredBunVersion:">=1.1.31",impact:"rows are materialized in memory; upgrade Bun to restore streaming"})),o.all(...e))}function Ye(o,e,t,s){try{let n=Number(s.limit);if(!Number.isInteger(n)||n<0)throw new Error("Page limit must be a non-negative integer");let i=Number(s.offset??0);if(!Number.isInteger(i))throw new Error("Page offset must be an integer");let r=[];if(n===0)return r;let a=Math.max(0,i);for(let _ of Ce(o,...e))if(t(_)){if(a>0){a--;continue}if(r.push(_),r.length===n)break}return r}finally{o.finalize()}}var Je=require("bun:sqlite");function J(o){return o.replace(/\\/g,"/").replace(/\/+/g,"/").replace(/\/+$/,"")}function Ve(o,e){let t=J(o),s=J(e);if(t.startsWith(s+"/"))return!t.slice(s.length+1).includes("/");let n=s.split("/"),i=t.split("/");if(i.length<2)return s===""||s===".";let r=i.slice(0,-1).join("/"),a=i[i.length-1],_=/^([A-Za-z]:)?\//;if(!_.test(s)&&_.test(t)&&s!==""&&r.endsWith("/"+s))return a!=="";if(s.endsWith("/"+r)||s===r)return!a.includes("/");for(let E=0;E<n.length;E++)if(n.slice(E).join("/")===r)return!0;return!1}var cn=/^\d{4}-\d{2}-\d{2}$/;function $(o,e){if(typeof o=="number")return o;let t=o.trim(),s=new Date(t).getTime();return e==="end"&&cn.test(t)?s+864e5-1:s}var qe="\\u0E00-\\u0EFF\\u1000-\\u109F\\u1780-\\u17FF\\u3040-\\u30FF\\u3100-\\u318F\\u3400-\\u4DBF\\u4E00-\\u9FFF\\uAC00-\\uD7AF\\uF900-\\uFAFF",os=["observations_ai","observations_ad","observations_au"],is=["session_summaries_ai","session_summaries_ad","session_summaries_au"],ae=`
127
127
  CREATE TRIGGER IF NOT EXISTS observations_ai AFTER INSERT ON observations BEGIN
128
128
  INSERT INTO observations_fts(rowid, title, subtitle, narrative, text, facts, concepts)
129
129
  VALUES (new.id, new.title, new.subtitle, new.narrative, new.text, new.facts, new.concepts);
@@ -141,7 +141,7 @@ ${L.stack??""}
141
141
  INSERT INTO observations_fts(rowid, title, subtitle, narrative, text, facts, concepts)
142
142
  VALUES (new.id, new.title, new.subtitle, new.narrative, new.text, new.facts, new.concepts);
143
143
  END;
144
- `,ge=`
144
+ `,_e=`
145
145
  CREATE TRIGGER IF NOT EXISTS session_summaries_ai AFTER INSERT ON session_summaries BEGIN
146
146
  INSERT INTO session_summaries_fts(rowid, request, investigated, learned, completed, next_steps, notes)
147
147
  VALUES (new.id, new.request, new.investigated, new.learned, new.completed, new.next_steps, new.notes);
@@ -159,7 +159,7 @@ ${L.stack??""}
159
159
  INSERT INTO session_summaries_fts(rowid, request, investigated, learned, completed, next_steps, notes)
160
160
  VALUES (new.id, new.request, new.investigated, new.learned, new.completed, new.next_steps, new.notes);
161
161
  END;
162
- `,Qt=class r{db;constructor(e=Ee){e instanceof $e.Database?this.db=e:(de(M),this.db=new $e.Database(e)),Se(this.db),this._fts5Available=this.isFts5Available(),this.ensureFTSTables()}_fts5Available;ensureFTSTables(){let e=this.db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name LIKE '%_fts'").all(),t=e.some(n=>n.name==="observations_fts"),s=e.some(n=>n.name==="session_summaries_fts");if(!(t&&s)){if(!this.isFts5Available()){u.warn("DB","FTS5 not available on this platform \u2014 skipping FTS table creation (search uses ChromaDB)");return}u.info("DB","Creating FTS5 tables");try{this.db.transaction(()=>{let n=this.db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name LIKE '%_fts'").all(),i=!n.some(a=>a.name==="observations_fts"),o=!n.some(a=>a.name==="session_summaries_fts");this.createFTSTablesAndTriggers(i,o)}).immediate(),u.info("DB","FTS5 tables created successfully")}catch(n){this._fts5Available=!1,u.warn("DB","FTS5 table creation failed \u2014 search will use ChromaDB and LIKE queries",{},n instanceof Error?n:void 0)}}}isFts5Available(){try{return this.db.run("CREATE VIRTUAL TABLE temp._fts5_probe USING fts5(test_column)"),this.db.run("DROP TABLE temp._fts5_probe"),!0}catch(e){return u.debug("DB","FTS5 probe failed \u2014 FTS5 unavailable on this platform",void 0,e instanceof Error?e:new Error(String(e))),!1}}canReadFtsIndex(e){try{return this.db.prepare(`SELECT rowid FROM ${e} WHERE ${e} MATCH ? LIMIT 0`).all('"fts_read_probe"'),!0}catch{return!1}}createFTSTablesAndTriggers(e,t){e&&(this.db.run(`
162
+ `,as=class o{db;constructor(e=me){e instanceof Je.Database?this.db=e:(Te(M),this.db=new Je.Database(e)),Re(this.db,q),be(this.db),this._fts5Available=this.isFts5Available(),this.ensureFTSTables()}_fts5Available;ensureFTSTables(){let e=this.db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name LIKE '%_fts'").all(),t=e.some(r=>r.name==="observations_fts"),s=e.some(r=>r.name==="session_summaries_fts");if(t&&s&&this.hasAllFtsTriggers(os)&&this.hasAllFtsTriggers(is))return;if(!this.isFts5Available()){c.warn("DB","FTS5 not available on this platform \u2014 skipping FTS table creation (search uses ChromaDB)");return}let n=t&&s;c.info("DB",n?"Converging FTS5 indexes and recreating missing sync triggers":"Creating FTS5 tables");let i=!1;try{this.db.transaction(()=>{let r=this.db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name LIKE '%_fts'").all(),a=!r.some(u=>u.name==="observations_fts"),_=!r.some(u=>u.name==="session_summaries_fts"),E=!a&&!this.hasAllFtsTriggers(os),d=!_&&!this.hasAllFtsTriggers(is);this.createFTSTablesAndTriggers(a,_),E&&(this.rebuildFtsIndex("observations_fts"),this.db.run(ae)),d&&(this.rebuildFtsIndex("session_summaries_fts"),this.db.run(_e))}).immediate(),i=!0,c.info("DB",n?"FTS5 indexes converged and sync triggers recreated":"FTS5 tables created successfully")}catch(r){this._fts5Available=!1,c.warn("DB","FTS5 table creation failed \u2014 search will use ChromaDB and LIKE queries",{},r instanceof Error?r:void 0)}i&&Ne(this.db,q)}hasAllFtsTriggers(e){let t=e.map(()=>"?").join(", ");return this.db.prepare(`SELECT name FROM sqlite_master WHERE type='trigger' AND name IN (${t})`).all(...e).length===e.length}rebuildFtsIndex(e){this.db.run(`INSERT INTO ${e}(${e}) VALUES('rebuild')`)}isFts5Available(){try{return this.db.run("CREATE VIRTUAL TABLE temp._fts5_probe USING fts5(test_column)"),this.db.run("DROP TABLE temp._fts5_probe"),!0}catch(e){return c.debug("DB","FTS5 probe failed \u2014 FTS5 unavailable on this platform",void 0,e instanceof Error?e:new Error(String(e))),!1}}canReadFtsIndex(e){try{return this.db.prepare(`SELECT rowid FROM ${e} WHERE ${e} MATCH ? LIMIT 0`).all('"fts_read_probe"'),!0}catch{return!1}}createFTSTablesAndTriggers(e,t){e&&(this.db.run(`
163
163
  CREATE VIRTUAL TABLE IF NOT EXISTS observations_fts USING fts5(
164
164
  title,
165
165
  subtitle,
@@ -174,7 +174,7 @@ ${L.stack??""}
174
174
  INSERT INTO observations_fts(rowid, title, subtitle, narrative, text, facts, concepts)
175
175
  SELECT id, title, subtitle, narrative, text, facts, concepts
176
176
  FROM observations;
177
- `),this.db.run(Oe)),t&&(this.db.run(`
177
+ `),this.db.run(ae)),t&&(this.db.run(`
178
178
  CREATE VIRTUAL TABLE IF NOT EXISTS session_summaries_fts USING fts5(
179
179
  request,
180
180
  investigated,
@@ -189,30 +189,33 @@ ${L.stack??""}
189
189
  INSERT INTO session_summaries_fts(rowid, request, investigated, learned, completed, next_steps, notes)
190
190
  SELECT id, request, investigated, learned, completed, next_steps, notes
191
191
  FROM session_summaries;
192
- `),this.db.run(ge))}buildFilterClause(e,t,s="o"){let n=[],i=w(e);if(i.length>0){let o=x(s,i,{includeMerged:!0});n.push(o.sql),t.push(...o.params)}if(e.platformSource&&(n.push(`COALESCE(NULLIF((SELECT s2.platform_source FROM sdk_sessions s2 WHERE s2.memory_session_id = ${s}.memory_session_id), ''), '${p}') = ?`),t.push(b(e.platformSource))),e.type)if(Array.isArray(e.type)){let o=e.type.map(()=>"?").join(",");n.push(`${s}.type IN (${o})`),t.push(...e.type)}else n.push(`${s}.type = ?`),t.push(e.type);if(e.dateRange){let{start:o,end:a}=e.dateRange;o&&(n.push(`${s}.created_at_epoch >= ?`),t.push(j(o,"start"))),a&&(n.push(`${s}.created_at_epoch <= ?`),t.push(j(a,"end")))}if(e.concepts){let o=Array.isArray(e.concepts)?e.concepts:[e.concepts],a=o.map(()=>`EXISTS (SELECT 1 FROM json_each(${s}.concepts) WHERE value = ?)`);a.length>0&&(n.push(`(${a.join(" OR ")})`),t.push(...o))}if(e.files){let o=Array.isArray(e.files)?e.files:[e.files],a=o.map(()=>`(
193
- EXISTS (SELECT 1 FROM json_each(${s}.files_read) WHERE value LIKE ? ESCAPE '\\')
194
- OR EXISTS (SELECT 1 FROM json_each(${s}.files_modified) WHERE value LIKE ? ESCAPE '\\')
195
- )`);a.length>0&&(n.push(`(${a.join(" OR ")})`),o.forEach(_=>{let E=_.replace(/[\\%_]/g,"\\$&");t.push(`%${E}%`,`%${E}%`)}))}return n.length>0?n.join(" AND "):""}static UNSEGMENTED_SCRIPT=new RegExp(`[${je}]`);static UNSEGMENTED_RUN=new RegExp(`[${je}]+|[^\\s${je}]+`,"g");static MAX_SUBSTRING_TERMS=500;static buildSubstringClause(e,t){let s=[...new Set(e.match(r.UNSEGMENTED_RUN)??[])].slice(0,r.MAX_SUBSTRING_TERMS);s.length===0&&s.push(e);let n=[];return{clause:`(${s.map(o=>{let a=`%${o.replace(/[\\%_]/g,"\\$&")}%`;for(let _=0;_<t.length;_+=1)n.push(a);return`(${t.map(_=>`${_} LIKE ? ESCAPE '\\'`).join(" OR ")})`}).join(" AND ")})`,params:n}}static buildFTSMatchQuery(e){let t=(e.match(/\S+/g)??[]).filter(s=>/[\p{L}\p{N}]/u.test(s));return t.length===0?`"${e.replace(/"/g,'""')}"`:t.map(s=>`"${s.replace(/"/g,'""')}"`).join(" AND ")}buildOrderClause(e="relevance",t=!0,s="observations_fts"){switch(e){case"relevance":return t?`ORDER BY ${s}.rank ASC`:"ORDER BY o.created_at_epoch DESC";case"date_desc":return"ORDER BY o.created_at_epoch DESC";case"date_asc":return"ORDER BY o.created_at_epoch ASC";default:return"ORDER BY o.created_at_epoch DESC"}}searchObservationsBySubstring(e,t,s,n,i){let o=r.buildSubstringClause(e,["o.title","o.subtitle","o.narrative","o.text","o.facts","o.concepts"]),a=[],_=this.buildFilterClause(t,a,"o"),E=`
192
+ `),this.db.run(_e))}buildFilterClause(e,t,s="o"){let n=[],i=w(e);if(i.length>0){let r=x(s,i,{includeMerged:!0});n.push(r.sql),t.push(...r.params)}if(e.platformSource&&(n.push(`COALESCE(NULLIF((SELECT s2.platform_source FROM sdk_sessions s2 WHERE s2.memory_session_id = ${s}.memory_session_id), ''), '${T}') = ?`),t.push(b(e.platformSource))),e.type)if(Array.isArray(e.type)){let r=e.type.map(()=>"?").join(",");n.push(`${s}.type IN (${r})`),t.push(...e.type)}else n.push(`${s}.type = ?`),t.push(e.type);if(e.dateRange){let{start:r,end:a}=e.dateRange;r&&(n.push(`${s}.created_at_epoch >= ?`),t.push($(r,"start"))),a&&(n.push(`${s}.created_at_epoch <= ?`),t.push($(a,"end")))}if(e.concepts){let r=Array.isArray(e.concepts)?e.concepts:[e.concepts],a=`${s}.concepts`,_=`CASE WHEN json_valid(${a}) THEN CASE
193
+ WHEN json_type(${a}) = 'array' THEN ${a}
194
+ WHEN json_type(${a}) = 'text' THEN json_array(json_extract(${a}, '$'))
195
+ ELSE json_array(${a}) END ELSE json_array(${a}) END`,E=r.map(()=>`EXISTS (SELECT 1 FROM json_each(${_}) WHERE type = 'text' AND value = ?)`);E.length>0&&(n.push(`(${E.join(" OR ")})`),t.push(...r))}if(e.files){let r=Array.isArray(e.files)?e.files:[e.files],a=s==="s"?"files_edited":"files_modified",_=r.map(()=>`(
196
+ EXISTS (SELECT 1 FROM json_each(${o.fileArrayJson(`${s}.files_read`)}) WHERE type = 'text' AND value LIKE ? ESCAPE '\\')
197
+ OR EXISTS (SELECT 1 FROM json_each(${o.fileArrayJson(`${s}.${a}`)}) WHERE type = 'text' AND value LIKE ? ESCAPE '\\')
198
+ )`);_.length>0&&(n.push(`(${_.join(" OR ")})`),r.forEach(E=>{let d=E.replace(/[\\%_]/g,"\\$&");t.push(`%${d}%`,`%${d}%`)}))}return n.length>0?n.join(" AND "):""}static UNSEGMENTED_SCRIPT=new RegExp(`[${qe}]`);static UNSEGMENTED_RUN=new RegExp(`[${qe}]+|[^\\s${qe}]+`,"g");static MAX_SUBSTRING_TERMS=500;static buildSubstringClause(e,t){let s=[...new Set(e.match(o.UNSEGMENTED_RUN)??[])].slice(0,o.MAX_SUBSTRING_TERMS);s.length===0&&s.push(e);let n=[];return{clause:`(${s.map(r=>{let a=`%${r.replace(/[\\%_]/g,"\\$&")}%`;for(let _=0;_<t.length;_+=1)n.push(a);return`(${t.map(_=>`${_} LIKE ? ESCAPE '\\'`).join(" OR ")})`}).join(" AND ")})`,params:n}}static MIN_ANY_TERM_TOKENS=3;static buildFTSMatchQuery(e){let t=(e.match(/\S+/g)??[]).filter(s=>/[\p{L}\p{N}]/u.test(s));return t.length===0?`"${e.replace(/"/g,'""')}"`:t.map(s=>`"${s.replace(/"/g,'""')}"`).join(" AND ")}static buildFTSAnyTermQuery(e){let t=(e.match(/\S+/g)??[]).filter(s=>/[\p{L}\p{N}]/u.test(s));return t.length<o.MIN_ANY_TERM_TOKENS?null:t.map(s=>`"${s.replace(/"/g,'""')}"`).join(" OR ")}buildOrderClause(e="relevance",t=!0,s="observations_fts"){switch(e){case"relevance":return t?`ORDER BY ${s}.rank ASC`:"ORDER BY o.created_at_epoch DESC";case"date_desc":return"ORDER BY o.created_at_epoch DESC, o.id DESC";case"date_asc":return"ORDER BY o.created_at_epoch ASC, o.id ASC";default:return"ORDER BY o.created_at_epoch DESC"}}searchObservationsBySubstring(e,t,s,n,i){let r=o.buildSubstringClause(e,["o.title","o.subtitle","o.narrative","o.text","o.facts","o.concepts"]),a=[],_=this.buildFilterClause(t,a,"o"),E=`
196
199
  SELECT o.*, o.discovery_tokens
197
200
  FROM observations o
198
- WHERE ${o.clause}
201
+ WHERE ${r.clause}
199
202
  ${_?"AND "+_:""}
200
203
  ${this.buildOrderClause(s,!1)}
201
204
  LIMIT ? OFFSET ?
202
- `;return this.db.prepare(E).all(...o.params,...a,n,i)}searchSessionsBySubstring(e,t,s,n,i){let o=r.buildSubstringClause(e,["s.request","s.investigated","s.learned","s.completed","s.next_steps","s.notes"]),a={...t};delete a.type;let _=[],E=this.buildFilterClause(a,_,"s"),c=s==="date_asc"?"ORDER BY s.created_at_epoch ASC":"ORDER BY s.created_at_epoch DESC",d=`
205
+ `;return this.db.prepare(E).all(...r.params,...a,n,i)}searchSessionsBySubstring(e,t,s,n,i){let r=o.buildSubstringClause(e,["s.request","s.investigated","s.learned","s.completed","s.next_steps","s.notes"]),a={...t};delete a.type;let _=[],E=this.buildFilterClause(a,_,"s"),d=s==="date_asc"?"ORDER BY s.created_at_epoch ASC, s.id ASC":"ORDER BY s.created_at_epoch DESC, s.id DESC",u=`
203
206
  SELECT s.*, s.discovery_tokens
204
207
  FROM session_summaries s
205
- WHERE ${o.clause}
208
+ WHERE ${r.clause}
206
209
  ${E?"AND "+E:""}
207
- ${c}
210
+ ${d}
208
211
  LIMIT ? OFFSET ?
209
- `;return this.db.prepare(d).all(...o.params,..._,n,i)}searchObservations(e,t={}){let s=[],{limit:n=50,offset:i=0,orderBy:o="relevance",...a}=t;if(!e){let _=this.buildFilterClause(a,s,"o");if(!_)return[];let E=this.buildOrderClause(o,!1),c=`
212
+ `;return this.db.prepare(u).all(...r.params,..._,n,i)}searchObservations(e,t={}){let s=[],{limit:n=50,offset:i=0,orderBy:r="relevance",...a}=t;if(!e){let _=this.buildFilterClause(a,s,"o");if(!_)return[];let E=this.buildOrderClause(r,!1),d=`
210
213
  SELECT o.*, o.discovery_tokens
211
214
  FROM observations o
212
215
  WHERE ${_}
213
216
  ${E}
214
217
  LIMIT ? OFFSET ?
215
- `;return s.push(n,i),this.db.prepare(c).all(...s)}if(r.UNSEGMENTED_SCRIPT.test(e))return this.searchObservationsBySubstring(e,a,o,n,i);if(this._fts5Available||this.canReadFtsIndex("observations_fts")){let _=this.buildFilterClause(a,s,"o"),E=this.buildOrderClause(o,!0,"observations_fts"),c=`
218
+ `;return s.push(n,i),this.db.prepare(d).all(...s)}if(o.UNSEGMENTED_SCRIPT.test(e))return this.searchObservationsBySubstring(e,a,r,n,i);if(this._fts5Available||this.canReadFtsIndex("observations_fts")){let _=this.buildFilterClause(a,s,"o"),E=this.buildOrderClause(r,!0,"observations_fts"),d=`
216
219
  SELECT o.*, o.discovery_tokens
217
220
  FROM observations o
218
221
  JOIN observations_fts ON observations_fts.rowid = o.id
@@ -220,79 +223,81 @@ ${L.stack??""}
220
223
  ${_?"AND "+_:""}
221
224
  ${E}
222
225
  LIMIT ? OFFSET ?
223
- `;s.unshift(r.buildFTSMatchQuery(e));let d;try{d=this.db.prepare(c).all(...s,n,i)}catch(l){throw u.warn("DB","FTS5 observation search failed",{},l instanceof Error?l:void 0),l}return d.length>0||i>0&&this.db.prepare(c).all(...s,1,0).length>0?d:this.searchObservationsBySubstring(e,a,o,n,i)}return this.searchObservationsBySubstring(e,a,o,n,i)}searchSessions(e,t={}){let s=[],{limit:n=50,offset:i=0,orderBy:o="relevance",...a}=t;if(!e){let _={...a};delete _.type;let E=this.buildFilterClause(_,s,"s");if(!E)return[];let d=`
226
+ `;s.unshift(o.buildFTSMatchQuery(e));let u;try{u=this.db.prepare(d).all(...s,n,i)}catch(p){throw c.warn("DB","FTS5 observation search failed",{},p instanceof Error?p:void 0),p}if(u.length>0||i>0&&this.db.prepare(d).all(...s,1,0).length>0)return u;let l=this.searchObservationsBySubstring(e,a,r,n,i);return l.length>0||i>0&&this.searchObservationsBySubstring(e,a,r,1,0).length>0?l:this.searchFtsAnyTerm(d,e,s,n,i)??l}return this.searchObservationsBySubstring(e,a,r,n,i)}searchSessions(e,t={}){let s=[],{limit:n=50,offset:i=0,orderBy:r="relevance",...a}=t;if(!e){let _={...a};delete _.type;let E=this.buildFilterClause(_,s,"s");if(!E)return[];let u=`
224
227
  SELECT s.*, s.discovery_tokens
225
228
  FROM session_summaries s
226
229
  WHERE ${E}
227
- ${o==="date_asc"?"ORDER BY s.created_at_epoch ASC":"ORDER BY s.created_at_epoch DESC"}
230
+ ${r==="date_asc"?"ORDER BY s.created_at_epoch ASC, s.id ASC":"ORDER BY s.created_at_epoch DESC, s.id DESC"}
228
231
  LIMIT ? OFFSET ?
229
- `;return s.push(n,i),this.db.prepare(d).all(...s)}if(r.UNSEGMENTED_SCRIPT.test(e))return this.searchSessionsBySubstring(e,a,o,n,i);if(this._fts5Available||this.canReadFtsIndex("session_summaries_fts")){let _={...a};delete _.type;let E=this.buildFilterClause(_,s,"s"),c=o==="date_asc"?"ORDER BY s.created_at_epoch ASC":o==="date_desc"?"ORDER BY s.created_at_epoch DESC":"ORDER BY session_summaries_fts.rank ASC",d=`
232
+ `;return s.push(n,i),this.db.prepare(u).all(...s)}if(o.UNSEGMENTED_SCRIPT.test(e))return this.searchSessionsBySubstring(e,a,r,n,i);if(this._fts5Available||this.canReadFtsIndex("session_summaries_fts")){let _={...a};delete _.type;let E=this.buildFilterClause(_,s,"s"),d=r==="date_asc"?"ORDER BY s.created_at_epoch ASC, s.id ASC":r==="date_desc"?"ORDER BY s.created_at_epoch DESC, s.id DESC":"ORDER BY session_summaries_fts.rank ASC",u=`
230
233
  SELECT s.*, s.discovery_tokens
231
234
  FROM session_summaries s
232
235
  JOIN session_summaries_fts ON session_summaries_fts.rowid = s.id
233
236
  WHERE session_summaries_fts MATCH ?
234
237
  ${E?"AND "+E:""}
235
- ${c}
238
+ ${d}
236
239
  LIMIT ? OFFSET ?
237
- `;s.unshift(r.buildFTSMatchQuery(e));let l;try{l=this.db.prepare(d).all(...s,n,i)}catch(O){throw u.warn("DB","FTS5 session search failed",{},O instanceof Error?O:void 0),O}return l.length>0||i>0&&this.db.prepare(d).all(...s,1,0).length>0?l:this.searchSessionsBySubstring(e,a,o,n,i)}return this.searchSessionsBySubstring(e,a,o,n,i)}findByConcept(e,t={}){let s=[],{limit:n=50,offset:i=0,orderBy:o="date_desc",...a}=t,_={...a,concepts:e},E=this.buildFilterClause(_,s,"o"),c=this.buildOrderClause(o,!1),d=`
240
+ `;s.unshift(o.buildFTSMatchQuery(e));let l;try{l=this.db.prepare(u).all(...s,n,i)}catch(S){throw c.warn("DB","FTS5 session search failed",{},S instanceof Error?S:void 0),S}if(l.length>0||i>0&&this.db.prepare(u).all(...s,1,0).length>0)return l;let p=this.searchSessionsBySubstring(e,a,r,n,i);return p.length>0||i>0&&this.searchSessionsBySubstring(e,a,r,1,0).length>0?p:this.searchFtsAnyTerm(u,e,s,n,i)??p}return this.searchSessionsBySubstring(e,a,r,n,i)}searchFtsAnyTerm(e,t,s,n,i){let r=o.buildFTSAnyTermQuery(t);if(!r)return null;let a=[r,...s.slice(1)],_=this.db.prepare(e).all(...a,n,i);return _.length>0||i>0&&this.db.prepare(e).all(...a,1,0).length>0?_:null}findByConcept(e,t={}){let s=[],{limit:n=50,offset:i=0,orderBy:r="date_desc",...a}=t,_={...a,concepts:e},E=this.buildFilterClause(_,s,"o"),d=this.buildOrderClause(r,!1),u=`
238
241
  SELECT o.*, o.discovery_tokens
239
242
  FROM observations o
240
243
  WHERE ${E}
241
- ${c}
244
+ ${d}
242
245
  LIMIT ? OFFSET ?
243
- `;return s.push(n,i),this.db.prepare(d).all(...s)}hasDirectChildFile(e,t){let s=n=>{if(!n)return!1;try{let i=JSON.parse(n);if(Array.isArray(i))return i.some(o=>He(o,t))}catch(i){u.debug("DB",`Failed to parse files JSON for observation ${e.id}`,void 0,i instanceof Error?i:void 0)}return!1};return s(e.files_modified)||s(e.files_read)}hasDirectChildFileSession(e,t){let s=n=>{if(!n)return!1;try{let i=JSON.parse(n);if(Array.isArray(i))return i.some(o=>He(o,t))}catch(i){u.debug("DB",`Failed to parse files JSON for session summary ${e.id}`,void 0,i instanceof Error?i:void 0)}return!1};return s(e.files_read)||s(e.files_edited)}static filePathPatterns(e,t){let s=a=>a.replace(/[\\%_]/g,"\\$&"),n=[`%${s(e)}%`];if(!t||!/^([A-Za-z]:)?[\\/]/.test(e))return n;let i=Ae(e).split("/").filter(a=>a.length>0),o=/^[A-Za-z]:$/.test(i[0]??"")?1:0;for(let a=o;a<i.length;a+=1){let _=i.slice(a);n.push(`${s(_.join("/")+"/")}%`),e.includes("\\")&&n.push(`${s(_.join("\\")+"\\")}%`)}return n}static jsonArrayLikeClause(e,t){let s=Array.from({length:t},()=>"value LIKE ? ESCAPE '\\'").join(" OR ");return`(${e.map(n=>`EXISTS (SELECT 1 FROM json_each(${n}) WHERE ${s})`).join(" OR ")})`}findByFile(e,t={}){let s=[],{limit:n=50,offset:i=0,orderBy:o="date_desc",isFolder:a=!1,..._}=t;delete _.files;let E=a?"":"LIMIT ? OFFSET ?",c=r.filePathPatterns(e,a),d=this.buildFilterClause(_,s,"o");s.push(...c,...c);let l=[d,r.jsonArrayLikeClause(["o.files_read","o.files_modified"],c.length)].filter(Boolean).join(" AND "),O=`${this.buildOrderClause(o,!1)}, o.id ${o==="date_asc"?"ASC":"DESC"}`,L=`
246
+ `;return s.push(n,i),this.db.prepare(u).all(...s)}hasDirectChildFile(e,t){let s=n=>{if(!n)return!1;try{let i=JSON.parse(n);if(Array.isArray(i))return i.some(r=>typeof r=="string"&&Ve(r,t))}catch(i){c.debug("DB",`Failed to parse files JSON for observation ${e.id}`,void 0,i instanceof Error?i:void 0)}return!1};return s(e.files_modified)||s(e.files_read)}hasDirectChildFileSession(e,t){let s=n=>{if(!n)return!1;try{let i=JSON.parse(n);if(Array.isArray(i))return i.some(r=>typeof r=="string"&&Ve(r,t))}catch(i){c.debug("DB",`Failed to parse files JSON for session summary ${e.id}`,void 0,i instanceof Error?i:void 0)}return!1};return s(e.files_read)||s(e.files_edited)}static filePathPatterns(e,t){let s=_=>_.replace(/[\\%_]/g,"\\$&"),n=t?[e,J(e),J(e).replaceAll("/","\\")]:[e],i=[...new Set(n)].map(_=>`%${s(_)}%`);if(!t||!/^([A-Za-z]:)?[\\/]/.test(e))return i;let r=J(e).split("/").filter(_=>_.length>0),a=/^[A-Za-z]:$/.test(r[0]??"")?1:0;for(let _=a;_<r.length;_+=1){let E=r.slice(_);i.push(`${s(E.join("/")+"/")}%`),e.includes("\\")&&i.push(`${s(E.join("\\")+"\\")}%`)}return i}static fileArrayJson(e){return`CASE WHEN json_valid(${e}) THEN CASE WHEN json_type(${e}) = 'array' THEN ${e} ELSE '[]' END ELSE '[]' END`}static jsonArrayLikeClause(e,t){let s=Array.from({length:t},()=>"type = 'text' AND value LIKE ? ESCAPE '\\'").join(" OR ");return`(${e.map(n=>`EXISTS (SELECT 1 FROM json_each(${o.fileArrayJson(n)}) WHERE ${s})`).join(" OR ")})`}findByFile(e,t={}){let s=[],{limit:n=50,offset:i=0,orderBy:r="date_desc",isFolder:a=!1,..._}=t;delete _.files;let E=a?"":"LIMIT ? OFFSET ?",d=o.filePathPatterns(e,a),u=this.buildFilterClause(_,s,"o");s.push(...d,...d);let l=[u,o.jsonArrayLikeClause(["o.files_read","o.files_modified"],d.length)].filter(Boolean).join(" AND "),p=`${this.buildOrderClause(r,!1)}, o.id ${r==="date_asc"?"ASC":"DESC"}`,S=`
244
247
  SELECT o.*, o.discovery_tokens
245
248
  FROM observations o
246
249
  WHERE ${l}
247
- ${O}
250
+ ${p}
248
251
  ${E}
249
- `;a||s.push(n,i);let I=this.db.prepare(L),f=a?Ge(I,s,D=>this.hasDirectChildFile(D,e),{limit:n,offset:i}):I.all(...s),g=[],m={..._};delete m.type;let N=[],A=w(m);if(A.length>0){let D=x("s",A,{includeMerged:!0});N.push(D.sql),g.push(...D.params)}if(m.platformSource&&(N.push(`COALESCE(NULLIF((SELECT s2.platform_source FROM sdk_sessions s2 WHERE s2.memory_session_id = s.memory_session_id), ''), '${p}') = ?`),g.push(b(m.platformSource))),m.dateRange){let{start:D,end:v}=m.dateRange;D&&(N.push("s.created_at_epoch >= ?"),g.push(j(D,"start"))),v&&(N.push("s.created_at_epoch <= ?"),g.push(j(v,"end")))}N.push(r.jsonArrayLikeClause(["s.files_read","s.files_edited"],c.length)),g.push(...c,...c);let y=`
252
+ `;a||s.push(n,i);let h=this.db.prepare(S),f=a?Ye(h,s,O=>this.hasDirectChildFile(O,e),{limit:n,offset:i}):h.all(...s),C=[],R={..._};delete R.type;let m=[],A=w(R);if(A.length>0){let O=x("s",A,{includeMerged:!0});m.push(O.sql),C.push(...O.params)}if(R.platformSource&&(m.push(`COALESCE(NULLIF((SELECT s2.platform_source FROM sdk_sessions s2 WHERE s2.memory_session_id = s.memory_session_id), ''), '${T}') = ?`),C.push(b(R.platformSource))),R.dateRange){let{start:O,end:v}=R.dateRange;O&&(m.push("s.created_at_epoch >= ?"),C.push($(O,"start"))),v&&(m.push("s.created_at_epoch <= ?"),C.push($(v,"end")))}m.push(o.jsonArrayLikeClause(["s.files_read","s.files_edited"],d.length)),C.push(...d,...d);let y=`
250
253
  SELECT s.*, s.discovery_tokens
251
254
  FROM session_summaries s
252
- WHERE ${N.join(" AND ")}
253
- ORDER BY s.created_at_epoch ${o==="date_asc"?"ASC":"DESC"}
255
+ WHERE ${m.join(" AND ")}
256
+ ORDER BY s.created_at_epoch ${r==="date_asc"?"ASC":"DESC"}
254
257
  ${E}
255
- `;a||g.push(n,i);let T=this.db.prepare(y),S=a?Ge(T,g,D=>this.hasDirectChildFileSession(D,e),{limit:n,offset:i}):T.all(...g);return{observations:f,sessions:S}}findByType(e,t={}){let s=[],{limit:n=50,offset:i=0,orderBy:o="date_desc",...a}=t,_={...a,type:e},E=this.buildFilterClause(_,s,"o"),c=this.buildOrderClause(o,!1),d=`
258
+ `;a||C.push(n,i);let g=this.db.prepare(y),D=a?Ye(g,C,O=>this.hasDirectChildFileSession(O,e),{limit:n,offset:i}):g.all(...C);return{observations:f,sessions:D}}findByType(e,t={}){let s=[],{limit:n=50,offset:i=0,orderBy:r="date_desc",...a}=t,_={...a,type:e},E=this.buildFilterClause(_,s,"o"),d=this.buildOrderClause(r,!1),u=`
256
259
  SELECT o.*, o.discovery_tokens
257
260
  FROM observations o
258
261
  WHERE ${E}
259
- ${c}
262
+ ${d}
260
263
  LIMIT ? OFFSET ?
261
- `;return s.push(n,i),this.db.prepare(d).all(...s)}searchUserPrompts(e,t={}){let s=[],{limit:n=20,offset:i=0,orderBy:o="relevance",...a}=t,_=[],E=w(a);if(E.length>0){let L=x("s",E,{includeMerged:!1});_.push(L.sql),s.push(...L.params)}if(a.platformSource&&(_.push(`COALESCE(NULLIF(s.platform_source, ''), '${p}') = ?`),s.push(b(a.platformSource))),a.dateRange){let{start:L,end:I}=a.dateRange;L&&(_.push("up.created_at_epoch >= ?"),s.push(j(L,"start"))),I&&(_.push("up.created_at_epoch <= ?"),s.push(j(I,"end")))}if(!e){if(_.length===0)return[];let L=`WHERE ${_.join(" AND ")}`,f=`
264
+ `;return s.push(n,i),this.db.prepare(u).all(...s)}searchUserPrompts(e,t={}){let s=[],{limit:n=20,offset:i=0,orderBy:r="relevance",...a}=t,_=[],E=w(a);if(E.length>0){let S=x("s",E,{includeMerged:!1});_.push(S.sql),s.push(...S.params)}if(a.platformSource&&(_.push(`COALESCE(NULLIF(s.platform_source, ''), '${T}') = ?`),s.push(b(a.platformSource))),a.dateRange){let{start:S,end:h}=a.dateRange;S&&(_.push("up.created_at_epoch >= ?"),s.push($(S,"start"))),h&&(_.push("up.created_at_epoch <= ?"),s.push($(h,"end")))}if(!e){if(_.length===0)return[];let S=`WHERE ${_.join(" AND ")}`,f=`
262
265
  SELECT
263
266
  up.*,
264
267
  s.project,
265
268
  s.memory_session_id,
266
- COALESCE(NULLIF(s.platform_source, ''), '${p}') as platform_source
269
+ COALESCE(NULLIF(s.platform_source, ''), '${T}') as platform_source
267
270
  FROM user_prompts up
268
271
  JOIN sdk_sessions s ON up.session_db_id = s.id
269
- ${L}
270
- ${o==="date_asc"?"ORDER BY up.created_at_epoch ASC":"ORDER BY up.created_at_epoch DESC"}
272
+ ${S}
273
+ ${r==="date_asc"?"ORDER BY up.created_at_epoch ASC, up.id ASC":"ORDER BY up.created_at_epoch DESC, up.id DESC"}
271
274
  LIMIT ? OFFSET ?
272
- `;return s.push(n,i),this.db.prepare(f).all(...s)}let c=e.replace(/[\\%_]/g,"\\$&");_.push("up.prompt_text LIKE ? ESCAPE '\\'"),s.push(`%${c}%`);let d=`WHERE ${_.join(" AND ")}`,O=`
275
+ `;return s.push(n,i),this.db.prepare(f).all(...s)}let d=e.replace(/[\\%_]/g,"\\$&");_.push("up.prompt_text LIKE ? ESCAPE '\\'"),s.push(`%${d}%`);let u=`WHERE ${_.join(" AND ")}`,p=`
273
276
  SELECT
274
277
  up.*,
275
278
  s.project,
276
279
  s.memory_session_id,
277
- COALESCE(NULLIF(s.platform_source, ''), '${p}') as platform_source
280
+ COALESCE(NULLIF(s.platform_source, ''), '${T}') as platform_source
278
281
  FROM user_prompts up
279
282
  JOIN sdk_sessions s ON up.session_db_id = s.id
280
- ${d}
281
- ${o==="date_asc"?"ORDER BY up.created_at_epoch ASC":"ORDER BY up.created_at_epoch DESC"}
283
+ ${u}
284
+ ${r==="date_asc"?"ORDER BY up.created_at_epoch ASC, up.id ASC":"ORDER BY up.created_at_epoch DESC, up.id DESC"}
282
285
  LIMIT ? OFFSET ?
283
- `;return s.push(n,i),this.db.prepare(O).all(...s)}close(){this.db.close()}};var Zt=4096;var en=new Set(["set_title","set_prompt_session","remap_project"]),tn=/^(?:0|[1-9][0-9]*)$/,es=18446744073709551615n;function U(r){throw u.debug("CLOUD_SYNC","Rejected invalid canonical content",{reason:r}),new Error(`canonical content: ${r}`)}function Re(r,e={}){return typeof r!="string"||!tn.test(r)?U("decimal values must be unsigned base-10 strings without leading zeroes"):(BigInt(r)>es&&U("decimal value exceeds uint64"),e.positive&&r==="0"&&U("decimal value must be positive"),r)}function We(r){let e=Re(r);return BigInt(e)===es&&U("uint64 sequence overflow"),(BigInt(e)+1n).toString(10)}function sn(r){(r===null||typeof r!="object"||Array.isArray(r))&&U("mutation must be an object");let e=r;if((typeof e.op!="string"||!en.has(e.op))&&U("unsupported mutation op"),e.op==="set_title"){let i=re(e,["fields","op","target"],"set_title"),o=fe(i.target,["content_session_id","memory_session_id","platform_source"],"set_title.target");o.memory_session_id===void 0&&o.content_session_id===void 0&&U("set_title target requires a session identifier");for(let _ of["memory_session_id","content_session_id","platform_source"])o[_]!==void 0&&B(o[_],_);let a=re(i.fields,["custom_title"],"set_title.fields");B(a.custom_title,"custom_title");return}if(e.op==="set_prompt_session"){let i=re(e,["fields","op","target"],"set_prompt_session"),o=re(i.target,["origin_device_id","origin_local_id"],"set_prompt_session.target");nn(o.origin_device_id),Re(o.origin_local_id);let a=fe(i.fields,["content_session_id","memory_session_id","platform_source","project"],"set_prompt_session.fields");B(a.memory_session_id,"memory_session_id");for(let _ of["content_session_id","platform_source","project"])a[_]!==void 0&&B(a[_],_);return}let t=re(e,["fields","op","where"],"remap_project"),s=fe(t.where,["memory_session_id","merged_into_project_is_null","project"],"remap_project.where");s.project!==void 0&&B(s.project,"project"),s.memory_session_id!==void 0&&B(s.memory_session_id,"memory_session_id"),s.merged_into_project_is_null!==void 0&&s.merged_into_project_is_null!==!0&&U("merged_into_project_is_null may only be true"),Object.keys(s).length===0&&U("remap_project where is empty");let n=fe(t.fields,["merged_into_project","project"],"remap_project.fields");n.project!==void 0&&B(n.project,"project"),n.merged_into_project!==void 0&&B(n.merged_into_project,"merged_into_project"),Object.keys(n).length===0&&U("remap_project fields are empty")}function Ke(r){sn(r)}function nn(r){return typeof r!="string"||r.length===0||Buffer.byteLength(r,"utf8")>128?U("origin_device_id must be a non-empty string of at most 128 UTF-8 bytes"):r}function B(r,e){return typeof r!="string"||r.length===0||r.trim().length===0||Buffer.byteLength(r,"utf8")>Zt?U(`${e} must be a non-blank string of at most ${Zt} UTF-8 bytes`):r}function re(r,e,t){if(r===null||typeof r!="object"||Array.isArray(r))return U(`${t} must be an object`);let s=r,n=Object.keys(s).sort(),i=[...e].sort();return(n.length!==i.length||n.some((o,a)=>o!==i[a]))&&U(`${t} must contain exactly: ${i.join(", ")}`),s}function fe(r,e,t){if(r===null||typeof r!="object"||Array.isArray(r))return U(`${t} must be an object`);let s=r,n=new Set(e),i=Object.keys(s).find(o=>!n.has(o));return i&&U(`${t} contains unknown field ${i}`),s}var ts=5*6e4,R=r=>typeof r=="object"&&r!==null?JSON.stringify(r):r??null;function ss(r){let e=[],t=[],s=new Set,n=new Set;for(let i of r){for(let o of i.files_read??[])!o||s.has(o)||(s.add(o),e.push(o));for(let o of i.files_modified??[])!o||n.has(o)||(n.add(o),t.push(o))}return{files_read:e,files_edited:t}}var rn=200,on=1e3,an=56,_n=57;function Ye(r){let e=Number(r);return Number.isSafeInteger(e)&&e>0?e:void 0}var qe=class{db;syncOpsEnabled;statementCache=new Map;constructor(e=Ee,t={}){this.syncOpsEnabled=t.syncOpsEnabled??!0,e instanceof Ve.Database?this.db=e:(e!==":memory:"&&de(M),this.db=new Ve.Database(e)),Se(this.db),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(),this.ensureSyncedAtColumns(),this.ensureSyncOriginColumns(),this.ensureSyncOutbox(),this.ensureSyncEntityLedger(),this.ensureSyncRevisionTextAffinity(),this.initializeSyncHubLaunchBaseline(),this.normalizeConceptTags(),this.ensureSDKSessionsObservedColumns(),this.ensureToolUsesTable(),this.ensureTelegramWrapupsTable(),this.addDedupTables(),this.ensureReinforcementColumns(),this.ensureSessionCwdColumn(),this.dropWriteOnlyUserPromptsFtsAndScopeFtsUpdateTriggers(),this.ensureProjectNocaseIndexes(),this.ensureAdvisorCallsTable(),this.ensureSessionProjectKeySourceColumn(),this.requeuePromptsDeadLetteredForSize(),this.ensureWorkStateTable(),this.ensureHookSpoolConsumedTable(),this.ensureProjectRecencyIndexes(),this.ensureMergedIntoProjectCoveringIndexes(),this.ensureNativePromptIdentity()}ensureNativePromptIdentity(){this.db.transaction(()=>{let e=this.db.query("PRAGMA table_info(user_prompts)").all();for(let t of["native_prompt_id","native_prompt_hash"])e.some(s=>s.name===t)||this.db.run(`ALTER TABLE user_prompts ADD COLUMN ${t} TEXT`);this.db.run(`CREATE UNIQUE INDEX IF NOT EXISTS idx_user_prompts_native_identity
284
- ON user_prompts(session_db_id, native_prompt_id) WHERE native_prompt_id IS NOT NULL`)}).immediate()}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(n=>{if(n.unique!==1)return!1;let i=this.getIndexColumns(n.name);return i.length===t.length&&i.every((o,a)=>o===t[a])})}resolvePromptSessionDbId(e,t,s){if(t!==void 0)return t;let n=s?b(s):void 0;return n?this.db.prepare(`
286
+ `;return s.push(n,i),this.db.prepare(p).all(...s)}close(){this.db.close()}};var _s=4096;var un=new Set(["set_title","set_prompt_session","remap_project"]),ln=/^(?:0|[1-9][0-9]*)$/,Es=18446744073709551615n;function U(o){throw c.debug("CLOUD_SYNC","Rejected invalid canonical content",{reason:o}),new Error(`canonical content: ${o}`)}function Ie(o,e={}){return typeof o!="string"||!ln.test(o)?U("decimal values must be unsigned base-10 strings without leading zeroes"):(BigInt(o)>Es&&U("decimal value exceeds uint64"),e.positive&&o==="0"&&U("decimal value must be positive"),o)}function ze(o){let e=Ie(o);return BigInt(e)===Es&&U("uint64 sequence overflow"),(BigInt(e)+1n).toString(10)}function pn(o){(o===null||typeof o!="object"||Array.isArray(o))&&U("mutation must be an object");let e=o;if((typeof e.op!="string"||!un.has(e.op))&&U("unsupported mutation op"),e.op==="set_title"){let i=Ee(e,["fields","op","target"],"set_title"),r=Le(i.target,["content_session_id","memory_session_id","platform_source"],"set_title.target");r.memory_session_id===void 0&&r.content_session_id===void 0&&U("set_title target requires a session identifier");for(let _ of["memory_session_id","content_session_id","platform_source"])r[_]!==void 0&&B(r[_],_);let a=Ee(i.fields,["custom_title"],"set_title.fields");B(a.custom_title,"custom_title");return}if(e.op==="set_prompt_session"){let i=Ee(e,["fields","op","target"],"set_prompt_session"),r=Ee(i.target,["origin_device_id","origin_local_id"],"set_prompt_session.target");mn(r.origin_device_id),Ie(r.origin_local_id);let a=Le(i.fields,["content_session_id","memory_session_id","platform_source","project"],"set_prompt_session.fields");B(a.memory_session_id,"memory_session_id");for(let _ of["content_session_id","platform_source","project"])a[_]!==void 0&&B(a[_],_);return}let t=Ee(e,["fields","op","where"],"remap_project"),s=Le(t.where,["memory_session_id","merged_into_project_is_null","project"],"remap_project.where");s.project!==void 0&&B(s.project,"project"),s.memory_session_id!==void 0&&B(s.memory_session_id,"memory_session_id"),s.merged_into_project_is_null!==void 0&&s.merged_into_project_is_null!==!0&&U("merged_into_project_is_null may only be true"),Object.keys(s).length===0&&U("remap_project where is empty");let n=Le(t.fields,["merged_into_project","project"],"remap_project.fields");n.project!==void 0&&B(n.project,"project"),n.merged_into_project!==void 0&&B(n.merged_into_project,"merged_into_project"),Object.keys(n).length===0&&U("remap_project fields are empty")}function Qe(o){pn(o)}function mn(o){return typeof o!="string"||o.length===0||Buffer.byteLength(o,"utf8")>128?U("origin_device_id must be a non-empty string of at most 128 UTF-8 bytes"):o}function B(o,e){return typeof o!="string"||o.length===0||o.trim().length===0||Buffer.byteLength(o,"utf8")>_s?U(`${e} must be a non-blank string of at most ${_s} UTF-8 bytes`):o}function Ee(o,e,t){if(o===null||typeof o!="object"||Array.isArray(o))return U(`${t} must be an object`);let s=o,n=Object.keys(s).sort(),i=[...e].sort();return(n.length!==i.length||n.some((r,a)=>r!==i[a]))&&U(`${t} must contain exactly: ${i.join(", ")}`),s}function Le(o,e,t){if(o===null||typeof o!="object"||Array.isArray(o))return U(`${t} must be an object`);let s=o,n=new Set(e),i=Object.keys(s).find(r=>!n.has(r));return i&&U(`${t} contains unknown field ${i}`),s}var ds=5*6e4,N=o=>typeof o=="object"&&o!==null?JSON.stringify(o):o??null;function cs(o){let e=[],t=[],s=new Set,n=new Set;for(let i of o){for(let r of i.files_read??[])!r||s.has(r)||(s.add(r),e.push(r));for(let r of i.files_modified??[])!r||n.has(r)||(n.add(r),t.push(r))}return{files_read:e,files_edited:t}}var Tn=200,Sn=1e3,An=56,gn=57;function Ze(o){let e=Number(o);return Number.isSafeInteger(e)&&e>0?e:void 0}var tt=class{db;syncOpsEnabled;statementCache=new Map;constructor(e=me,t={}){this.syncOpsEnabled=t.syncOpsEnabled??!0,e instanceof et.Database?this.db=e:(e!==":memory:"&&Te(M),this.db=new et.Database(e)),Re(this.db,q),be(this.db),Ne(this.db,q),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(),this.ensureSyncedAtColumns(),this.ensureSyncOriginColumns(),this.ensureSyncOutbox(),this.ensureSyncEntityLedger(),this.ensureSyncRevisionTextAffinity(),this.initializeSyncHubLaunchBaseline(),this.normalizeConceptTags(),this.ensureSDKSessionsObservedColumns(),this.ensureToolUsesTable(),this.ensureTelegramWrapupsTable(),this.addDedupTables(),this.refreshUnicodeTitleNormKeys(),this.ensureReinforcementColumns(),this.ensureSessionCwdColumn(),this.dropWriteOnlyUserPromptsFtsAndScopeFtsUpdateTriggers(),this.ensureProjectNocaseIndexes(),this.ensureAdvisorCallsTable(),this.ensureSessionProjectKeySourceColumn(),this.requeuePromptsDeadLetteredForSize(),this.ensureWorkStateTable(),this.ensureHookSpoolConsumedTable(),this.ensureProjectRecencyIndexes(),this.ensureMergedIntoProjectCoveringIndexes(),this.ensureNativePromptIdentity()}ensureNativePromptIdentity(){this.db.transaction(()=>{let e=this.db.query("PRAGMA table_info(user_prompts)").all();for(let t of["native_prompt_id","native_prompt_hash"])e.some(s=>s.name===t)||this.db.run(`ALTER TABLE user_prompts ADD COLUMN ${t} TEXT`);this.db.run(`CREATE UNIQUE INDEX IF NOT EXISTS idx_user_prompts_native_identity
287
+ ON user_prompts(session_db_id, native_prompt_id) WHERE native_prompt_id IS NOT NULL`)}).immediate()}refreshUnicodeTitleNormKeys(){this.db.transaction(()=>{if(this.db.query("SELECT version FROM schema_versions WHERE version = 65").get())return;let e=this.db.prepare(`SELECT o.id, o.project, o.title, o.agent_id, o.agent_type,
288
+ s.platform_source FROM observations o LEFT JOIN sdk_sessions s
289
+ ON s.memory_session_id = o.memory_session_id ORDER BY o.id`),t=this.db.prepare("UPDATE observations SET title_norm_key = ? WHERE id = ?");try{for(let s of Ce(e)){let n=s;t.run(ge(n.project,n.platform_source,n.title,ne(n.agent_id,n.agent_type)),n.id)}this.db.prepare("INSERT INTO schema_versions (version, applied_at) VALUES (?, ?)").run(65,new Date().toISOString())}finally{e.finalize(),t.finalize()}}).immediate()}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(n=>{if(n.unique!==1)return!1;let i=this.getIndexColumns(n.name);return i.length===t.length&&i.every((r,a)=>r===t[a])})}resolvePromptSessionDbId(e,t,s){if(t!==void 0)return t;let n=s?b(s):void 0;return n?this.db.prepare(`
285
290
  SELECT id
286
291
  FROM sdk_sessions
287
292
  WHERE COALESCE(NULLIF(platform_source, ''), ?) = ?
288
293
  AND content_session_id = ?
289
294
  LIMIT 1
290
- `).get(p,n,e)?.id??null:this.db.prepare(`
295
+ `).get(T,n,e)?.id??null:this.db.prepare(`
291
296
  SELECT id
292
297
  FROM sdk_sessions
293
298
  WHERE content_session_id = ?
294
- ORDER BY CASE COALESCE(NULLIF(platform_source, ''), '${p}')
295
- WHEN '${p}' THEN 0
299
+ ORDER BY CASE COALESCE(NULLIF(platform_source, ''), '${T}')
300
+ WHEN '${T}' THEN 0
296
301
  ELSE 1
297
302
  END, id
298
303
  LIMIT 1
@@ -327,17 +332,17 @@ ${L.stack??""}
327
332
  FOREIGN KEY (duplicate_of_id) REFERENCES observations(id) ON DELETE CASCADE,
328
333
  UNIQUE(observation_id, duplicate_of_id)
329
334
  )
330
- `),this.db.run("CREATE INDEX IF NOT EXISTS idx_token_df_project ON token_df(project)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_dedup_candidates_project ON observation_dedup_candidates(project, status)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_dedup_candidates_obs ON observation_dedup_candidates(observation_id)"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(an,new Date().toISOString())}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(n=>n.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"),u.debug("DB","Dropped worker_pid column and its index from pending_messages")}catch(n){u.warn("DB","Failed to drop worker_pid column from pending_messages",{},n instanceof Error?n:new Error(String(n)));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"]),i=this.db.query("PRAGMA table_info(sdk_sessions)").all().some(o=>o.name==="platform_source");if(!(e&&!t&&s&&i)){if(i||this.db.run(`ALTER TABLE sdk_sessions ADD COLUMN platform_source TEXT NOT NULL DEFAULT '${p}'`),this.db.run(`
335
+ `),this.db.run("CREATE INDEX IF NOT EXISTS idx_token_df_project ON token_df(project)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_dedup_candidates_project ON observation_dedup_candidates(project, status)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_dedup_candidates_obs ON observation_dedup_candidates(observation_id)"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(An,new Date().toISOString())}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(n=>n.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"),c.debug("DB","Dropped worker_pid column and its index from pending_messages")}catch(n){c.warn("DB","Failed to drop worker_pid column from pending_messages",{},n instanceof Error?n:new Error(String(n)));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"]),i=this.db.query("PRAGMA table_info(sdk_sessions)").all().some(r=>r.name==="platform_source");if(!(e&&!t&&s&&i)){if(i||this.db.run(`ALTER TABLE sdk_sessions ADD COLUMN platform_source TEXT NOT NULL DEFAULT '${T}'`),this.db.run(`
331
336
  UPDATE sdk_sessions
332
- SET platform_source = '${p}'
337
+ SET platform_source = '${T}'
333
338
  WHERE platform_source IS NULL OR platform_source = ''
334
- `),t){this.db.run("PRAGMA foreign_keys = OFF"),this.db.run("BEGIN TRANSACTION");try{this.rebuildSdkSessionsWithCompositeIdentity(e),this.db.run("COMMIT")}catch(o){this.db.run("ROLLBACK");let a=o instanceof Error?o:new Error(String(o));throw u.error("DB","Failed to rebuild sdk_sessions with composite identity, rolled back",{},a),o}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(`
339
+ `),t){this.db.run("PRAGMA foreign_keys = OFF"),this.db.run("BEGIN TRANSACTION");try{this.rebuildSdkSessionsWithCompositeIdentity(e),this.db.run("COMMIT")}catch(r){this.db.run("ROLLBACK");let a=r instanceof Error?r:new Error(String(r));throw c.error("DB","Failed to rebuild sdk_sessions with composite identity, rolled back",{},a),r}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(`
335
340
  CREATE TABLE sdk_sessions_new (
336
341
  id INTEGER PRIMARY KEY AUTOINCREMENT,
337
342
  content_session_id TEXT NOT NULL,
338
343
  memory_session_id TEXT UNIQUE,
339
344
  project TEXT NOT NULL,
340
- platform_source TEXT NOT NULL DEFAULT '${p}',
345
+ platform_source TEXT NOT NULL DEFAULT '${T}',
341
346
  user_prompt TEXT,
342
347
  started_at TEXT NOT NULL,
343
348
  started_at_epoch INTEGER NOT NULL,
@@ -356,27 +361,27 @@ ${L.stack??""}
356
361
  )
357
362
  SELECT
358
363
  id, content_session_id, memory_session_id, project,
359
- COALESCE(NULLIF(platform_source, ''), '${p}'),
364
+ COALESCE(NULLIF(platform_source, ''), '${T}'),
360
365
  user_prompt, started_at, started_at_epoch, completed_at, completed_at_epoch,
361
366
  status, worker_port, prompt_counter, custom_title
362
367
  FROM sdk_sessions
363
- `),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 n=this.db.query("PRAGMA table_info(user_prompts)").all().some(_=>_.name==="session_db_id"),o=this.db.query("PRAGMA foreign_key_list(user_prompts)").all().some(_=>_.table==="sdk_sessions"&&_.from==="content_session_id");if(e&&n&&!o)return;let a=n?`COALESCE(up.session_db_id, (
368
+ `),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 n=this.db.query("PRAGMA table_info(user_prompts)").all().some(_=>_.name==="session_db_id"),r=this.db.query("PRAGMA foreign_key_list(user_prompts)").all().some(_=>_.table==="sdk_sessions"&&_.from==="content_session_id");if(e&&n&&!r)return;let a=n?`COALESCE(up.session_db_id, (
364
369
  SELECT s.id FROM sdk_sessions s
365
370
  WHERE s.content_session_id = up.content_session_id
366
- ORDER BY CASE COALESCE(NULLIF(s.platform_source, ''), '${p}')
367
- WHEN '${p}' THEN 0
371
+ ORDER BY CASE COALESCE(NULLIF(s.platform_source, ''), '${T}')
372
+ WHEN '${T}' THEN 0
368
373
  ELSE 1
369
374
  END, s.id
370
375
  LIMIT 1
371
376
  ))`:`(
372
377
  SELECT s.id FROM sdk_sessions s
373
378
  WHERE s.content_session_id = up.content_session_id
374
- ORDER BY CASE COALESCE(NULLIF(s.platform_source, ''), '${p}')
375
- WHEN '${p}' THEN 0
379
+ ORDER BY CASE COALESCE(NULLIF(s.platform_source, ''), '${T}')
380
+ WHEN '${T}' THEN 0
376
381
  ELSE 1
377
382
  END, s.id
378
383
  LIMIT 1
379
- )`;this.db.run("PRAGMA foreign_keys = OFF"),this.db.run("BEGIN TRANSACTION");try{this.rebuildUserPromptsWithSessionDbId(e,a),this.db.run("COMMIT")}catch(_){this.db.run("ROLLBACK");let E=_ instanceof Error?_:new Error(String(_));throw u.error("DB","Failed to rebuild user_prompts with session_db_id, rolled back",{},E),_}finally{this.db.run("PRAGMA foreign_keys = ON")}}rebuildUserPromptsWithSessionDbId(e,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(`
384
+ )`;this.db.run("PRAGMA foreign_keys = OFF"),this.db.run("BEGIN TRANSACTION");try{this.rebuildUserPromptsWithSessionDbId(e,a),this.db.run("COMMIT")}catch(_){this.db.run("ROLLBACK");let E=_ instanceof Error?_:new Error(String(_));throw c.error("DB","Failed to rebuild user_prompts with session_db_id, rolled back",{},E),_}finally{this.db.run("PRAGMA foreign_keys = ON")}}rebuildUserPromptsWithSessionDbId(e,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(`
380
385
  CREATE TABLE user_prompts_new (
381
386
  id INTEGER PRIMARY KEY AUTOINCREMENT,
382
387
  session_db_id INTEGER,
@@ -401,7 +406,7 @@ ${L.stack??""}
401
406
  up.created_at,
402
407
  up.created_at_epoch
403
408
  FROM user_prompts up
404
- `),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)"),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 s=this.hasUniqueIndexOnColumns("pending_messages",["session_db_id","tool_use_id"]);if(!(e&&s)){this.db.run("BEGIN TRANSACTION");try{this.recreatePendingSessionToolUniqueIndex(e),this.db.run("COMMIT")}catch(n){this.db.run("ROLLBACK");let i=n instanceof Error?n:new Error(String(n));throw u.error("DB","Failed to recreate ux_pending_session_tool index, rolled back",{},i),n}}}recreatePendingSessionToolUniqueIndex(e){this.db.run("DROP INDEX IF EXISTS ux_pending_session_tool"),this.db.run(`
409
+ `),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)"),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 s=this.hasUniqueIndexOnColumns("pending_messages",["session_db_id","tool_use_id"]);if(!(e&&s)){this.db.run("BEGIN TRANSACTION");try{this.recreatePendingSessionToolUniqueIndex(e),this.db.run("COMMIT")}catch(n){this.db.run("ROLLBACK");let i=n instanceof Error?n:new Error(String(n));throw c.error("DB","Failed to recreate ux_pending_session_tool index, rolled back",{},i),n}}}recreatePendingSessionToolUniqueIndex(e){this.db.run("DROP INDEX IF EXISTS ux_pending_session_tool"),this.db.run(`
405
410
  DELETE FROM pending_messages
406
411
  WHERE id IN (
407
412
  SELECT id
@@ -424,7 +429,7 @@ ${L.stack??""}
424
429
  CREATE UNIQUE INDEX IF NOT EXISTS ux_pending_session_tool
425
430
  ON pending_messages(session_db_id, tool_use_id)
426
431
  WHERE tool_use_id IS NOT NULL
427
- `),e||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(35,new Date().toISOString())}ensureSyncedAtColumns(){for(let e of["observations","session_summaries","user_prompts"])this.db.query(`PRAGMA table_info(${e})`).all().some(n=>n.name==="synced_at")||(this.db.run(`ALTER TABLE ${e} ADD COLUMN synced_at INTEGER`),u.debug("DB",`Added synced_at column to ${e} table`)),this.db.run(`CREATE INDEX IF NOT EXISTS idx_${e}_unsynced ON ${e}(id) WHERE synced_at IS NULL`);this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(39,new Date().toISOString())}ensureSyncOriginColumns(){for(let e of["observations","session_summaries","user_prompts"]){let t=this.db.query(`PRAGMA table_info(${e})`).all(),s=new Set(t.map(n=>n.name));s.has("origin_device_id")||(this.db.run(`ALTER TABLE ${e} ADD COLUMN origin_device_id TEXT`),u.debug("DB",`Added origin_device_id column to ${e} table`)),s.has("origin_local_id")||(this.db.run(`ALTER TABLE ${e} ADD COLUMN origin_local_id TEXT`),u.debug("DB",`Added origin_local_id column to ${e} table`)),s.has("sync_rev")||(this.db.run(`ALTER TABLE ${e} ADD COLUMN sync_rev TEXT NOT NULL DEFAULT '1'`),u.debug("DB",`Added sync_rev column to ${e} table`)),this.db.run(`
432
+ `),e||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(35,new Date().toISOString())}ensureSyncedAtColumns(){for(let e of["observations","session_summaries","user_prompts"])this.db.query(`PRAGMA table_info(${e})`).all().some(n=>n.name==="synced_at")||(this.db.run(`ALTER TABLE ${e} ADD COLUMN synced_at INTEGER`),c.debug("DB",`Added synced_at column to ${e} table`)),this.db.run(`CREATE INDEX IF NOT EXISTS idx_${e}_unsynced ON ${e}(id) WHERE synced_at IS NULL`);this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(39,new Date().toISOString())}ensureSyncOriginColumns(){for(let e of["observations","session_summaries","user_prompts"]){let t=this.db.query(`PRAGMA table_info(${e})`).all(),s=new Set(t.map(n=>n.name));s.has("origin_device_id")||(this.db.run(`ALTER TABLE ${e} ADD COLUMN origin_device_id TEXT`),c.debug("DB",`Added origin_device_id column to ${e} table`)),s.has("origin_local_id")||(this.db.run(`ALTER TABLE ${e} ADD COLUMN origin_local_id TEXT`),c.debug("DB",`Added origin_local_id column to ${e} table`)),s.has("sync_rev")||(this.db.run(`ALTER TABLE ${e} ADD COLUMN sync_rev TEXT NOT NULL DEFAULT '1'`),c.debug("DB",`Added sync_rev column to ${e} table`)),this.db.run(`
428
433
  CREATE UNIQUE INDEX IF NOT EXISTS ux_${e}_origin
429
434
  ON ${e}(origin_device_id, origin_local_id)
430
435
  WHERE origin_device_id IS NOT NULL
@@ -443,17 +448,17 @@ ${L.stack??""}
443
448
  operation_sha256 TEXT,
444
449
  created_at_epoch INTEGER NOT NULL
445
450
  )
446
- `);let e=new Set(this.db.query("PRAGMA table_info(sync_outbox)").all().map(t=>t.name));e.has("canonical_body")||this.db.run("ALTER TABLE sync_outbox ADD COLUMN canonical_body TEXT"),e.has("operation_sha256")||this.db.run("ALTER TABLE sync_outbox ADD COLUMN operation_sha256 TEXT"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(42,new Date().toISOString())}ensureSyncRevisionTextAffinity(){let e=[{table:"observations",column:"sync_rev",temporary:"sync_rev_text_v46"},{table:"session_summaries",column:"sync_rev",temporary:"sync_rev_text_v46"},{table:"user_prompts",column:"sync_rev",temporary:"sync_rev_text_v46"},{table:"sync_outbox",column:"rev",temporary:"rev_text_v46"}],t=(o,a)=>this.db.query(`PRAGMA table_info(${o})`).all().find(_=>_.name===a),s=o=>o?.type.trim().toUpperCase()==="TEXT";if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(46)&&e.every(o=>s(t(o.table,o.column))))return;this.db.transaction(()=>{for(let o of e){let a=this.db.query(`PRAGMA table_info(${o.table})`).all(),_=a.find(c=>c.name===o.column);if(!_)throw new Error(`schema v46: missing ${o.table}.${o.column}`);for(let c of Xe(this.db.query(`
451
+ `);let e=new Set(this.db.query("PRAGMA table_info(sync_outbox)").all().map(t=>t.name));e.has("canonical_body")||this.db.run("ALTER TABLE sync_outbox ADD COLUMN canonical_body TEXT"),e.has("operation_sha256")||this.db.run("ALTER TABLE sync_outbox ADD COLUMN operation_sha256 TEXT"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(42,new Date().toISOString())}ensureSyncRevisionTextAffinity(){let e=[{table:"observations",column:"sync_rev",temporary:"sync_rev_text_v46"},{table:"session_summaries",column:"sync_rev",temporary:"sync_rev_text_v46"},{table:"user_prompts",column:"sync_rev",temporary:"sync_rev_text_v46"},{table:"sync_outbox",column:"rev",temporary:"rev_text_v46"}],t=(r,a)=>this.db.query(`PRAGMA table_info(${r})`).all().find(_=>_.name===a),s=r=>r?.type.trim().toUpperCase()==="TEXT";if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(46)&&e.every(r=>s(t(r.table,r.column))))return;this.db.transaction(()=>{for(let r of e){let a=this.db.query(`PRAGMA table_info(${r.table})`).all(),_=a.find(d=>d.name===r.column);if(!_)throw new Error(`schema v46: missing ${r.table}.${r.column}`);for(let d of Ce(this.db.query(`
447
452
  SELECT CAST(id AS TEXT) AS row_id,
448
- typeof(${o.column}) AS storage_type,
449
- CAST(${o.column} AS TEXT) AS revision
450
- FROM ${o.table}
451
- `))){let d=c;if(d.storage_type==="real")throw new Error(`schema v46: ${o.table}.${o.column} row ${d.row_id} is REAL and unrecoverably rounded`);if(d.storage_type!=="integer"&&d.storage_type!=="text")throw new Error(`schema v46: ${o.table}.${o.column} row ${d.row_id} has unsupported ${d.storage_type} storage`);try{Re(d.revision,{positive:!0})}catch{throw new Error(`schema v46: ${o.table}.${o.column} row ${d.row_id} is not a positive canonical uint64 revision`)}}if(s(_))continue;if(a.some(c=>c.name===o.temporary))throw new Error(`schema v46: unexpected temporary column ${o.table}.${o.temporary}`);this.db.run(`ALTER TABLE ${o.table} ADD COLUMN ${o.temporary} TEXT NOT NULL DEFAULT '1'`),this.db.run(`UPDATE ${o.table} SET ${o.temporary} = CAST(${o.column} AS TEXT)`);let E=this.db.prepare(`
453
+ typeof(${r.column}) AS storage_type,
454
+ CAST(${r.column} AS TEXT) AS revision
455
+ FROM ${r.table}
456
+ `))){let u=d;if(u.storage_type==="real")throw new Error(`schema v46: ${r.table}.${r.column} row ${u.row_id} is REAL and unrecoverably rounded`);if(u.storage_type!=="integer"&&u.storage_type!=="text")throw new Error(`schema v46: ${r.table}.${r.column} row ${u.row_id} has unsupported ${u.storage_type} storage`);try{Ie(u.revision,{positive:!0})}catch{throw new Error(`schema v46: ${r.table}.${r.column} row ${u.row_id} is not a positive canonical uint64 revision`)}}if(s(_))continue;if(a.some(d=>d.name===r.temporary))throw new Error(`schema v46: unexpected temporary column ${r.table}.${r.temporary}`);this.db.run(`ALTER TABLE ${r.table} ADD COLUMN ${r.temporary} TEXT NOT NULL DEFAULT '1'`),this.db.run(`UPDATE ${r.table} SET ${r.temporary} = CAST(${r.column} AS TEXT)`);let E=this.db.prepare(`
452
457
  SELECT CAST(id AS TEXT) AS row_id
453
- FROM ${o.table}
454
- WHERE ${o.temporary} <> CAST(${o.column} AS TEXT)
458
+ FROM ${r.table}
459
+ WHERE ${r.temporary} <> CAST(${r.column} AS TEXT)
455
460
  LIMIT 1
456
- `).get();if(E)throw new Error(`schema v46: failed to copy ${o.table}.${o.column} row ${E.row_id} exactly`);this.db.run(`ALTER TABLE ${o.table} DROP COLUMN ${o.column}`),this.db.run(`ALTER TABLE ${o.table} RENAME COLUMN ${o.temporary} TO ${o.column}`)}this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(46,new Date().toISOString())})()}ensureSyncEntityLedger(){this.db.run(`
461
+ `).get();if(E)throw new Error(`schema v46: failed to copy ${r.table}.${r.column} row ${E.row_id} exactly`);this.db.run(`ALTER TABLE ${r.table} DROP COLUMN ${r.column}`),this.db.run(`ALTER TABLE ${r.table} RENAME COLUMN ${r.temporary} TO ${r.column}`)}this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(46,new Date().toISOString())})()}ensureSyncEntityLedger(){this.db.run(`
457
462
  CREATE TABLE IF NOT EXISTS sync_entity_heads (
458
463
  entity_id TEXT PRIMARY KEY,
459
464
  kind TEXT NOT NULL CHECK (kind IN ('observation', 'summary', 'prompt')),
@@ -520,13 +525,13 @@ ${L.stack??""}
520
525
  through_rev TEXT NOT NULL,
521
526
  PRIMARY KEY (kind, origin_local_id)
522
527
  )
523
- `);let s=this.db.prepare("SELECT version, applied_at FROM schema_versions WHERE version = ?").get(47);if(!s){let a=Date.now();this.db.transaction(()=>{this.db.run("DELETE FROM sync_launch_exclusions");for(let{table:c,kind:d}of e)this.db.prepare(`
528
+ `);let s=this.db.prepare("SELECT version, applied_at FROM schema_versions WHERE version = ?").get(47);if(!s){let a=Date.now();this.db.transaction(()=>{this.db.run("DELETE FROM sync_launch_exclusions");for(let{table:d,kind:u}of e)this.db.prepare(`
524
529
  INSERT INTO sync_launch_exclusions (kind, origin_local_id, through_rev)
525
530
  SELECT ?, CAST(id AS TEXT), CAST(sync_rev AS TEXT)
526
- FROM ${c}
531
+ FROM ${d}
527
532
  WHERE origin_device_id IS NULL
528
- `).run(d),this.db.prepare(`
529
- UPDATE ${c} SET synced_at = ?
533
+ `).run(u),this.db.prepare(`
534
+ UPDATE ${d} SET synced_at = ?
530
535
  WHERE synced_at IS NULL AND origin_device_id IS NULL
531
536
  `).run(a);this.db.run("DELETE FROM sync_outbox"),this.db.run("DELETE FROM sync_content_outbox"),this.db.run("DELETE FROM sync_dead_letter"),this.db.run("DELETE FROM sync_state");let E=new Date(a).toISOString();this.db.prepare("INSERT INTO schema_versions (version, applied_at) VALUES (?, ?)").run(47,E),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(48,E)})();return}if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(48)&&t)return;let i=Date.parse(s.applied_at);if(!Number.isSafeInteger(i)||i<0)throw new Error(`schema v48: invalid v47 applied_at ${s.applied_at}`);this.db.transaction(()=>{for(let{table:a,kind:_}of e)this.db.prepare(`
532
537
  INSERT OR IGNORE INTO sync_launch_exclusions (kind, origin_local_id, through_rev)
@@ -548,10 +553,10 @@ ${L.stack??""}
548
553
  ELSE value END)
549
554
  FROM json_each(observations.concepts))
550
555
  WHERE concepts LIKE '%:%' AND json_valid(concepts)
551
- `);for(let i of n){if(i.origin_device_id!==null)continue;let o=We(i.sync_rev);this.db.prepare(`
556
+ `);for(let i of n){if(i.origin_device_id!==null)continue;let r=ze(i.sync_rev);this.db.prepare(`
552
557
  UPDATE observations SET sync_rev = ?, synced_at = NULL
553
558
  WHERE id = ? AND origin_device_id IS NULL
554
- `).run(o,i.id)}this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(49,new Date().toISOString())})(),u.debug("DB",`Normalized prefixed concept tags in ${t} observations (v49)`)}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(o=>o.name)),i=["retry_count","failed_at_epoch","completed_at_epoch"].filter(o=>s.has(o));if(!(e&&i.length===0)){if(i.length>0){this.db.run("BEGIN TRANSACTION");try{this.db.run("DELETE FROM pending_messages WHERE status NOT IN ('pending', 'processing')");for(let o of i)this.db.run(`ALTER TABLE pending_messages DROP COLUMN ${o}`),u.debug("DB",`Dropped dead column ${o} 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(o){this.db.run("ROLLBACK"),u.warn("DB","Failed to drop dead columns from pending_messages",{},o instanceof Error?o:new Error(String(o)));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(`
559
+ `).run(r,i.id)}this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(49,new Date().toISOString())})(),c.debug("DB",`Normalized prefixed concept tags in ${t} observations (v49)`)}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(r=>r.name)),i=["retry_count","failed_at_epoch","completed_at_epoch"].filter(r=>s.has(r));if(!(e&&i.length===0)){if(i.length>0){this.db.run("BEGIN TRANSACTION");try{this.db.run("DELETE FROM pending_messages WHERE status NOT IN ('pending', 'processing')");for(let r of i)this.db.run(`ALTER TABLE pending_messages DROP COLUMN ${r}`),c.debug("DB",`Dropped dead column ${r} 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(r){this.db.run("ROLLBACK"),c.warn("DB","Failed to drop dead columns from pending_messages",{},r instanceof Error?r:new Error(String(r)));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(`
555
560
  CREATE TABLE IF NOT EXISTS schema_versions (
556
561
  id INTEGER PRIMARY KEY,
557
562
  version INTEGER UNIQUE NOT NULL,
@@ -614,7 +619,7 @@ ${L.stack??""}
614
619
  CREATE INDEX IF NOT EXISTS idx_session_summaries_sdk_session ON session_summaries(memory_session_id);
615
620
  CREATE INDEX IF NOT EXISTS idx_session_summaries_project ON session_summaries(project);
616
621
  CREATE INDEX IF NOT EXISTS idx_session_summaries_created ON session_summaries(created_at_epoch DESC);
617
- `),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"),u.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"),u.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"),u.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"),u.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())}repairOrphanedSessionParents(e){let t=this.db.prepare(`
622
+ `),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"),c.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"),c.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"),c.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"),c.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())}repairOrphanedSessionParents(e){let t=this.db.prepare(`
618
623
  SELECT COUNT(DISTINCT c.memory_session_id) AS n
619
624
  FROM ${e} c
620
625
  WHERE c.memory_session_id IS NOT NULL
@@ -634,7 +639,7 @@ ${L.stack??""}
634
639
  AND NOT EXISTS (SELECT 1 FROM sdk_sessions s WHERE s.memory_session_id = c.memory_session_id)
635
640
  GROUP BY c.memory_session_id
636
641
  ON CONFLICT DO NOTHING
637
- `),u.warn("DB",`Created ${t} stub sdk_sessions parent(s) for orphaned ${e} rows before rebuild (#3378)`))}hasMemorySessionIdOnUpdateCascade(e){return this.db.query(`PRAGMA foreign_key_list(${e})`).all().some(s=>s.table==="sdk_sessions"&&s.from==="memory_session_id"&&s.on_update==="CASCADE")}carryLiveColumnsOntoNewTable(e,t,s){let n=this.db.query(`PRAGMA table_info(${e})`).all(),i=n.filter(o=>!s.includes(o.name));for(let o of i){let a=o.type?` ${o.type}`:"",_=o.dflt_value===null||o.dflt_value===void 0?"":` DEFAULT ${o.dflt_value}`;this.db.run(`ALTER TABLE ${t} ADD COLUMN "${o.name}"${a}${_}`),u.debug("DB",`Carried ${o.name} over the ${e} rebuild (#3849)`)}return n.map(o=>o.name)}removeSessionSummariesUniqueConstraint(){if(!this.db.query("PRAGMA index_list(session_summaries)").all().some(a=>a.unique===1&&a.origin==="u")){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(7,new Date().toISOString());return}u.debug("DB","Removing UNIQUE constraint from session_summaries.memory_session_id"),this.db.run("BEGIN TRANSACTION"),this.repairOrphanedSessionParents("session_summaries");let s=["id","memory_session_id","project","request","investigated","learned","completed","next_steps","files_read","files_edited","notes","prompt_number","created_at","created_at_epoch"],i=this.db.query("PRAGMA table_info(session_summaries)").all().filter(a=>!s.includes(a.name));this.db.run("DROP TABLE IF EXISTS session_summaries_new"),this.db.run(`
642
+ `),c.warn("DB",`Created ${t} stub sdk_sessions parent(s) for orphaned ${e} rows before rebuild (#3378)`))}hasMemorySessionIdOnUpdateCascade(e){return this.db.query(`PRAGMA foreign_key_list(${e})`).all().some(s=>s.table==="sdk_sessions"&&s.from==="memory_session_id"&&s.on_update==="CASCADE")}carryLiveColumnsOntoNewTable(e,t,s){let n=this.db.query(`PRAGMA table_info(${e})`).all(),i=n.filter(r=>!s.includes(r.name));for(let r of i){let a=r.type?` ${r.type}`:"",_=r.dflt_value===null||r.dflt_value===void 0?"":` DEFAULT ${r.dflt_value}`;this.db.run(`ALTER TABLE ${t} ADD COLUMN "${r.name}"${a}${_}`),c.debug("DB",`Carried ${r.name} over the ${e} rebuild (#3849)`)}return n.map(r=>r.name)}removeSessionSummariesUniqueConstraint(){if(!this.db.query("PRAGMA index_list(session_summaries)").all().some(a=>a.unique===1&&a.origin==="u")){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(7,new Date().toISOString());return}c.debug("DB","Removing UNIQUE constraint from session_summaries.memory_session_id"),this.db.run("BEGIN TRANSACTION"),this.repairOrphanedSessionParents("session_summaries");let s=["id","memory_session_id","project","request","investigated","learned","completed","next_steps","files_read","files_edited","notes","prompt_number","created_at","created_at_epoch"],i=this.db.query("PRAGMA table_info(session_summaries)").all().filter(a=>!s.includes(a.name));this.db.run("DROP TABLE IF EXISTS session_summaries_new"),this.db.run(`
638
643
  CREATE TABLE session_summaries_new (
639
644
  id INTEGER PRIMARY KEY AUTOINCREMENT,
640
645
  memory_session_id TEXT NOT NULL,
@@ -652,15 +657,15 @@ ${L.stack??""}
652
657
  created_at_epoch INTEGER NOT NULL,
653
658
  FOREIGN KEY(memory_session_id) REFERENCES sdk_sessions(memory_session_id) ON DELETE CASCADE ON UPDATE CASCADE
654
659
  )
655
- `);for(let a of i){let _=a.type?` ${a.type}`:"",E=a.dflt_value===null||a.dflt_value===void 0?"":` DEFAULT ${a.dflt_value}`;this.db.run(`ALTER TABLE session_summaries_new ADD COLUMN "${a.name}"${_}${E}`),u.debug("DB",`Carried ${a.name} over the session_summaries UNIQUE-constraint rebuild (#3890)`)}let o=[...s,...i.map(a=>a.name)].map(a=>`"${a}"`).join(", ");this.db.run(`
656
- INSERT INTO session_summaries_new (${o})
657
- SELECT ${o}
660
+ `);for(let a of i){let _=a.type?` ${a.type}`:"",E=a.dflt_value===null||a.dflt_value===void 0?"":` DEFAULT ${a.dflt_value}`;this.db.run(`ALTER TABLE session_summaries_new ADD COLUMN "${a.name}"${_}${E}`),c.debug("DB",`Carried ${a.name} over the session_summaries UNIQUE-constraint rebuild (#3890)`)}let r=[...s,...i.map(a=>a.name)].map(a=>`"${a}"`).join(", ");this.db.run(`
661
+ INSERT INTO session_summaries_new (${r})
662
+ SELECT ${r}
658
663
  FROM session_summaries
659
664
  `),this.db.run("DROP TABLE session_summaries"),this.db.run("ALTER TABLE session_summaries_new RENAME TO session_summaries"),this.db.run(`
660
665
  CREATE INDEX idx_session_summaries_sdk_session ON session_summaries(memory_session_id);
661
666
  CREATE INDEX idx_session_summaries_project ON session_summaries(project);
662
667
  CREATE INDEX idx_session_summaries_created ON session_summaries(created_at_epoch DESC);
663
- `),this.db.run("COMMIT"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(7,new Date().toISOString()),u.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(n=>n.name==="title")){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(8,new Date().toISOString());return}u.debug("DB","Adding hierarchical fields to observations table"),this.db.run(`
668
+ `),this.recreateFtsTriggersIfIndexed("session_summaries"),this.db.run("COMMIT"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(7,new Date().toISOString()),c.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(n=>n.name==="title")){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(8,new Date().toISOString());return}c.debug("DB","Adding hierarchical fields to observations table"),this.db.run(`
664
669
  ALTER TABLE observations ADD COLUMN title TEXT;
665
670
  ALTER TABLE observations ADD COLUMN subtitle TEXT;
666
671
  ALTER TABLE observations ADD COLUMN facts TEXT;
@@ -668,7 +673,7 @@ ${L.stack??""}
668
673
  ALTER TABLE observations ADD COLUMN concepts TEXT;
669
674
  ALTER TABLE observations ADD COLUMN files_read TEXT;
670
675
  ALTER TABLE observations ADD COLUMN files_modified TEXT;
671
- `),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(8,new Date().toISOString()),u.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(n=>n.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}u.debug("DB","Making observations.text nullable"),this.db.run("BEGIN TRANSACTION"),this.repairOrphanedSessionParents("observations"),this.db.run("DROP TABLE IF EXISTS observations_new"),this.db.run(`
676
+ `),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(8,new Date().toISOString()),c.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(n=>n.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}c.debug("DB","Making observations.text nullable"),this.db.run("BEGIN TRANSACTION"),this.repairOrphanedSessionParents("observations"),this.db.run("DROP TABLE IF EXISTS observations_new"),this.db.run(`
672
677
  CREATE TABLE observations_new (
673
678
  id INTEGER PRIMARY KEY AUTOINCREMENT,
674
679
  memory_session_id TEXT NOT NULL,
@@ -698,7 +703,7 @@ ${L.stack??""}
698
703
  CREATE INDEX idx_observations_project ON observations(project);
699
704
  CREATE INDEX idx_observations_type ON observations(type);
700
705
  CREATE INDEX idx_observations_created ON observations(created_at_epoch DESC);
701
- `),this.db.run("COMMIT"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(9,new Date().toISOString()),u.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}u.debug("DB","Creating user_prompts table"),this.db.run("BEGIN TRANSACTION"),this.db.run(`
706
+ `),this.recreateFtsTriggersIfIndexed("observations"),this.db.run("COMMIT"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(9,new Date().toISOString()),c.debug("DB","Successfully made observations.text nullable")}recreateFtsTriggersIfIndexed(e){let t=`${e}_fts`;this.db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name = ?").all(t).length>0&&(this.db.run(`INSERT INTO ${t}(${t}) VALUES('rebuild')`),this.db.run(e==="observations"?ae:_e))}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}c.debug("DB","Creating user_prompts table"),this.db.run("BEGIN TRANSACTION"),this.db.run(`
702
707
  CREATE TABLE user_prompts (
703
708
  id INTEGER PRIMARY KEY AUTOINCREMENT,
704
709
  session_db_id INTEGER,
@@ -716,7 +721,7 @@ ${L.stack??""}
716
721
  CREATE INDEX idx_user_prompts_prompt_number ON user_prompts(prompt_number);
717
722
  CREATE INDEX idx_user_prompts_lookup ON user_prompts(session_db_id, prompt_number);
718
723
  CREATE INDEX idx_user_prompts_content_lookup ON user_prompts(content_session_id, prompt_number);
719
- `),this.db.run("COMMIT"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(10,new Date().toISOString()),u.debug("DB","Successfully created user_prompts table")}ensureDiscoveryTokensColumn(){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"),u.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"),u.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}u.debug("DB","Creating pending_messages table"),this.db.run(`
724
+ `),this.db.run("COMMIT"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(10,new Date().toISOString()),c.debug("DB","Successfully created user_prompts table")}ensureDiscoveryTokensColumn(){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"),c.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"),c.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}c.debug("DB","Creating pending_messages table"),this.db.run(`
720
725
  CREATE TABLE pending_messages (
721
726
  id INTEGER PRIMARY KEY AUTOINCREMENT,
722
727
  session_db_id INTEGER NOT NULL,
@@ -733,7 +738,7 @@ ${L.stack??""}
733
738
  created_at_epoch INTEGER NOT NULL,
734
739
  FOREIGN KEY (session_db_id) REFERENCES sdk_sessions(id) ON DELETE CASCADE
735
740
  )
736
- `),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()),u.debug("DB","pending_messages table created successfully")}renameSessionIdColumns(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(17))return;u.debug("DB","Checking session ID columns for semantic clarity rename");let t=0,s=(n,i,o)=>{let a=this.db.query(`PRAGMA table_info(${n})`).all(),_=a.some(c=>c.name===i);return a.some(c=>c.name===o)?!1:_?(this.db.run(`ALTER TABLE ${n} RENAME COLUMN ${i} TO ${o}`),u.debug("DB",`Renamed ${n}.${i} to ${o}`),!0):(u.warn("DB",`Column ${i} not found in ${n}, 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?u.debug("DB",`Successfully renamed ${t} session ID columns`):u.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(n=>n.name==="failed_at_epoch")||(this.db.run("ALTER TABLE pending_messages ADD COLUMN failed_at_epoch INTEGER"),u.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(){let e=!this.hasMemorySessionIdOnUpdateCascade("observations"),t=!this.hasMemorySessionIdOnUpdateCascade("session_summaries");if(!e&&!t){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(21,new Date().toISOString());return}u.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");let s=["id","memory_session_id","project","text","type","title","subtitle","facts","narrative","concepts","files_read","files_modified","prompt_number","discovery_tokens","created_at","created_at_epoch"],n=`
741
+ `),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()),c.debug("DB","pending_messages table created successfully")}renameSessionIdColumns(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(17))return;c.debug("DB","Checking session ID columns for semantic clarity rename");let t=0,s=(n,i,r)=>{let a=this.db.query(`PRAGMA table_info(${n})`).all(),_=a.some(d=>d.name===i);return a.some(d=>d.name===r)?!1:_?(this.db.run(`ALTER TABLE ${n} RENAME COLUMN ${i} TO ${r}`),c.debug("DB",`Renamed ${n}.${i} to ${r}`),!0):(c.warn("DB",`Column ${i} not found in ${n}, 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?c.debug("DB",`Successfully renamed ${t} session ID columns`):c.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(n=>n.name==="failed_at_epoch")||(this.db.run("ALTER TABLE pending_messages ADD COLUMN failed_at_epoch INTEGER"),c.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(){let e=!this.hasMemorySessionIdOnUpdateCascade("observations"),t=!this.hasMemorySessionIdOnUpdateCascade("session_summaries");if(!e&&!t){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(21,new Date().toISOString());return}c.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");let s=["id","memory_session_id","project","text","type","title","subtitle","facts","narrative","concepts","files_read","files_modified","prompt_number","discovery_tokens","created_at","created_at_epoch"],n=`
737
742
  CREATE TABLE observations_new (
738
743
  id INTEGER PRIMARY KEY AUTOINCREMENT,
739
744
  memory_session_id TEXT NOT NULL,
@@ -758,7 +763,7 @@ ${L.stack??""}
758
763
  CREATE INDEX idx_observations_project ON observations(project);
759
764
  CREATE INDEX idx_observations_type ON observations(type);
760
765
  CREATE INDEX idx_observations_created ON observations(created_at_epoch DESC);
761
- `,o=["id","memory_session_id","project","request","investigated","learned","completed","next_steps","files_read","files_edited","notes","prompt_number","discovery_tokens","created_at","created_at_epoch"],a=`
766
+ `,r=["id","memory_session_id","project","request","investigated","learned","completed","next_steps","files_read","files_edited","notes","prompt_number","discovery_tokens","created_at","created_at_epoch"],a=`
762
767
  CREATE TABLE session_summaries_new (
763
768
  id INTEGER PRIMARY KEY AUTOINCREMENT,
764
769
  memory_session_id TEXT NOT NULL,
@@ -781,11 +786,11 @@ ${L.stack??""}
781
786
  CREATE INDEX idx_session_summaries_sdk_session ON session_summaries(memory_session_id);
782
787
  CREATE INDEX idx_session_summaries_project ON session_summaries(project);
783
788
  CREATE INDEX idx_session_summaries_created ON session_summaries(created_at_epoch DESC);
784
- `;try{e&&(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"),this.recreateObservationsWithCascade(n,s,i,Oe)),t&&(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"),this.recreateSessionSummariesWithCascade(a,o,_,ge)),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"),u.debug("DB","Successfully added ON UPDATE CASCADE to FK constraints")}catch(E){throw this.db.run("ROLLBACK"),this.db.run("PRAGMA foreign_keys = ON"),E instanceof Error?E:new Error(String(E))}}recreateObservationsWithCascade(e,t,s,n){this.db.run(e);let o=this.carryLiveColumnsOntoNewTable("observations","observations_new",t).map(_=>`"${_}"`).join(", ");this.db.run(`INSERT INTO observations_new (${o}) SELECT ${o} FROM observations`),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(n)}recreateSessionSummariesWithCascade(e,t,s,n){this.db.run(e);let o=this.carryLiveColumnsOntoNewTable("session_summaries","session_summaries_new",t).map(_=>`"${_}"`).join(", ");this.db.run(`INSERT INTO session_summaries_new (${o}) SELECT ${o} FROM session_summaries`),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(n)}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)"),u.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(){let e=this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(23),s=this.db.query("PRAGMA table_info(sdk_sessions)").all().some(n=>n.name==="custom_title");e&&s||(s||(this.db.run("ALTER TABLE sdk_sessions ADD COLUMN custom_title TEXT"),u.debug("DB","Added custom_title column to sdk_sessions table")),e||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(o=>o.name==="platform_source"),n=this.db.query("PRAGMA index_list(sdk_sessions)").all().some(o=>o.name==="idx_sdk_sessions_platform_source");this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(24)&&t&&n||(t||(this.db.run(`ALTER TABLE sdk_sessions ADD COLUMN platform_source TEXT NOT NULL DEFAULT '${p}'`),u.debug("DB","Added platform_source column to sdk_sessions table")),this.db.run(`
789
+ `;try{e&&(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"),this.recreateObservationsWithCascade(n,s,i)),t&&(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"),this.recreateSessionSummariesWithCascade(a,r,_)),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"),c.debug("DB","Successfully added ON UPDATE CASCADE to FK constraints")}catch(E){throw this.db.run("ROLLBACK"),this.db.run("PRAGMA foreign_keys = ON"),E instanceof Error?E:new Error(String(E))}}recreateObservationsWithCascade(e,t,s){this.db.run(e);let i=this.carryLiveColumnsOntoNewTable("observations","observations_new",t).map(r=>`"${r}"`).join(", ");this.db.run(`INSERT INTO observations_new (${i}) SELECT ${i} FROM observations`),this.db.run("DROP TABLE observations"),this.db.run("ALTER TABLE observations_new RENAME TO observations"),this.db.run(s),this.recreateFtsTriggersIfIndexed("observations")}recreateSessionSummariesWithCascade(e,t,s){this.db.run(e);let i=this.carryLiveColumnsOntoNewTable("session_summaries","session_summaries_new",t).map(r=>`"${r}"`).join(", ");this.db.run(`INSERT INTO session_summaries_new (${i}) SELECT ${i} FROM session_summaries`),this.db.run("DROP TABLE session_summaries"),this.db.run("ALTER TABLE session_summaries_new RENAME TO session_summaries"),this.db.run(s),this.recreateFtsTriggersIfIndexed("session_summaries")}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)"),c.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(){let e=this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(23),s=this.db.query("PRAGMA table_info(sdk_sessions)").all().some(n=>n.name==="custom_title");e&&s||(s||(this.db.run("ALTER TABLE sdk_sessions ADD COLUMN custom_title TEXT"),c.debug("DB","Added custom_title column to sdk_sessions table")),e||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(r=>r.name==="platform_source"),n=this.db.query("PRAGMA index_list(sdk_sessions)").all().some(r=>r.name==="idx_sdk_sessions_platform_source");this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(24)&&t&&n||(t||(this.db.run(`ALTER TABLE sdk_sessions ADD COLUMN platform_source TEXT NOT NULL DEFAULT '${T}'`),c.debug("DB","Added platform_source column to sdk_sessions table")),this.db.run(`
785
790
  UPDATE sdk_sessions
786
- SET platform_source = '${p}'
791
+ SET platform_source = '${T}'
787
792
  WHERE platform_source IS NULL OR platform_source = ''
788
- `),n||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(n=>n.name==="generated_by_model"),s=e.some(n=>n.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()))}ensureSDKSessionsObservedColumns(){let e=this.db.query("PRAGMA table_info(sdk_sessions)").all(),t=e.some(n=>n.name==="observed_model"),s=e.some(n=>n.name==="observed_billing");t&&s||(t||this.db.run("ALTER TABLE sdk_sessions ADD COLUMN observed_model TEXT"),s||this.db.run("ALTER TABLE sdk_sessions ADD COLUMN observed_billing TEXT"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(50,new Date().toISOString()))}ensureToolUsesTable(){lt(this.db),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(51,new Date().toISOString())}ensureWorkStateTable(){gt(this.db),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(61,new Date().toISOString())}ensureProjectRecencyIndexes(){this.db.run("CREATE INDEX IF NOT EXISTS idx_observations_project_nocase_recent ON observations(project COLLATE NOCASE, created_at_epoch DESC)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_observations_merged_into_nocase_recent ON observations(merged_into_project COLLATE NOCASE, created_at_epoch DESC)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_summaries_project_nocase_recent ON session_summaries(project COLLATE NOCASE, created_at_epoch DESC)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_summaries_merged_into_nocase_recent ON session_summaries(merged_into_project COLLATE NOCASE, created_at_epoch DESC)"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(63,new Date().toISOString())}ensureMergedIntoProjectCoveringIndexes(){this.db.run("CREATE INDEX IF NOT EXISTS idx_observations_merged_into_nocase_project ON observations(merged_into_project COLLATE NOCASE, project)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_summaries_merged_into_nocase_project ON session_summaries(merged_into_project COLLATE NOCASE, project)"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(64,new Date().toISOString())}ensureHookSpoolConsumedTable(){this.db.run(`
793
+ `),n||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(n=>n.name==="generated_by_model"),s=e.some(n=>n.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()))}ensureSDKSessionsObservedColumns(){let e=this.db.query("PRAGMA table_info(sdk_sessions)").all(),t=e.some(n=>n.name==="observed_model"),s=e.some(n=>n.name==="observed_billing");t&&s||(t||this.db.run("ALTER TABLE sdk_sessions ADD COLUMN observed_model TEXT"),s||this.db.run("ALTER TABLE sdk_sessions ADD COLUMN observed_billing TEXT"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(50,new Date().toISOString()))}ensureToolUsesTable(){gt(this.db),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(51,new Date().toISOString())}ensureWorkStateTable(){Lt(this.db),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(61,new Date().toISOString())}ensureProjectRecencyIndexes(){this.db.run("CREATE INDEX IF NOT EXISTS idx_observations_project_nocase_recent ON observations(project COLLATE NOCASE, created_at_epoch DESC)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_observations_merged_into_nocase_recent ON observations(merged_into_project COLLATE NOCASE, created_at_epoch DESC)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_summaries_project_nocase_recent ON session_summaries(project COLLATE NOCASE, created_at_epoch DESC)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_summaries_merged_into_nocase_recent ON session_summaries(merged_into_project COLLATE NOCASE, created_at_epoch DESC)"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(63,new Date().toISOString())}ensureMergedIntoProjectCoveringIndexes(){this.db.run("CREATE INDEX IF NOT EXISTS idx_observations_merged_into_nocase_project ON observations(merged_into_project COLLATE NOCASE, project)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_summaries_merged_into_nocase_project ON session_summaries(merged_into_project COLLATE NOCASE, project)"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(64,new Date().toISOString())}ensureHookSpoolConsumedTable(){this.db.run(`
789
794
  CREATE TABLE IF NOT EXISTS hook_spool_consumed (
790
795
  entry_key TEXT PRIMARY KEY,
791
796
  consumed_at_epoch_ms INTEGER NOT NULL
@@ -803,7 +808,7 @@ ${L.stack??""}
803
808
  sent_at_epoch INTEGER,
804
809
  UNIQUE(platform_source, content_session_id, project, route_key)
805
810
  )
806
- `),this.db.run("CREATE INDEX IF NOT EXISTS idx_telegram_wrapups_platform_content ON telegram_wrapups(platform_source, content_session_id)"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(52,new Date().toISOString())}ensureReinforcementColumns(){let e=this.db.query("PRAGMA table_info(observations)").all();e.some(t=>t.name==="reinforcement_dates")||this.db.run("ALTER TABLE observations ADD COLUMN reinforcement_dates TEXT"),e.some(t=>t.name==="last_reinforced")||this.db.run("ALTER TABLE observations ADD COLUMN last_reinforced TEXT"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(_n,new Date().toISOString())}dropWriteOnlyUserPromptsFtsAndScopeFtsUpdateTriggers(){let e=this.db.prepare(`
811
+ `),this.db.run("CREATE INDEX IF NOT EXISTS idx_telegram_wrapups_platform_content ON telegram_wrapups(platform_source, content_session_id)"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(52,new Date().toISOString())}ensureReinforcementColumns(){let e=this.db.query("PRAGMA table_info(observations)").all();e.some(t=>t.name==="reinforcement_dates")||this.db.run("ALTER TABLE observations ADD COLUMN reinforcement_dates TEXT"),e.some(t=>t.name==="last_reinforced")||this.db.run("ALTER TABLE observations ADD COLUMN last_reinforced TEXT"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(gn,new Date().toISOString())}dropWriteOnlyUserPromptsFtsAndScopeFtsUpdateTriggers(){let e=this.db.prepare(`
807
812
  SELECT name FROM sqlite_master
808
813
  WHERE type = 'trigger'
809
814
  AND name IN ('observations_au', 'session_summaries_au')
@@ -811,7 +816,7 @@ ${L.stack??""}
811
816
  `).all().map(s=>s.name),t=this.db.prepare(`
812
817
  SELECT name FROM sqlite_master
813
818
  WHERE name IN ('user_prompts_fts', 'user_prompts_ai', 'user_prompts_ad', 'user_prompts_au')
814
- `).all();if(e.length>0||t.length>0){this.db.run("BEGIN TRANSACTION");try{e.includes("observations_au")&&(this.db.run("DROP TRIGGER observations_au"),this.db.run(Oe)),e.includes("session_summaries_au")&&(this.db.run("DROP TRIGGER session_summaries_au"),this.db.run(ge)),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_fts"),this.db.run("COMMIT")}catch(s){throw this.db.run("ROLLBACK"),u.error("DB","Failed to scope FTS update triggers / drop user_prompts_fts, rolled back",{},s instanceof Error?s:new Error(String(s))),s}u.info("DB","Scoped FTS update triggers to indexed columns and dropped the write-only user_prompts_fts",{rescopedTriggers:e,droppedUserPromptsFts:t.length>0})}this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(54,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)")}requeuePromptsDeadLetteredForSize(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(60))return;let t="canonical content: body exceeds % UTF-8 bytes";this.db.transaction(()=>{let s=this.db.prepare(`
819
+ `).all();if(e.length>0||t.length>0){this.db.run("BEGIN TRANSACTION");try{e.includes("observations_au")&&(this.db.run("DROP TRIGGER observations_au"),this.db.run(ae)),e.includes("session_summaries_au")&&(this.db.run("DROP TRIGGER session_summaries_au"),this.db.run(_e)),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_fts"),this.db.run("COMMIT")}catch(s){throw this.db.run("ROLLBACK"),c.error("DB","Failed to scope FTS update triggers / drop user_prompts_fts, rolled back",{},s instanceof Error?s:new Error(String(s))),s}c.info("DB","Scoped FTS update triggers to indexed columns and dropped the write-only user_prompts_fts",{rescopedTriggers:e,droppedUserPromptsFts:t.length>0})}this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(54,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)")}requeuePromptsDeadLetteredForSize(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(60))return;let t="canonical content: body exceeds % UTF-8 bytes";this.db.transaction(()=>{let s=this.db.prepare(`
815
820
  UPDATE user_prompts SET synced_at = NULL
816
821
  WHERE synced_at = -1 AND origin_device_id IS NULL
817
822
  AND CAST(id AS TEXT) IN (
@@ -820,7 +825,7 @@ ${L.stack??""}
820
825
  )
821
826
  `).run(t);this.db.prepare(`
822
827
  DELETE FROM sync_dead_letter WHERE lane = 'content' AND kind = 'prompt' AND reason LIKE ?
823
- `).run(t),s.changes>0&&u.info("DB","Re-queued prompts quarantined for size before the cloud-sync prompt clamp",{prompts:s.changes}),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(60,new Date().toISOString())})()}ensureSessionProjectKeySourceColumn(){this.db.query("PRAGMA table_info(sdk_sessions)").all().some(t=>t.name==="project_key_source")||(this.db.run("ALTER TABLE sdk_sessions ADD COLUMN project_key_source TEXT"),u.debug("DB","Added project_key_source column to sdk_sessions table")),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(59,new Date().toISOString())}ensureSessionCwdColumn(){this.db.query("PRAGMA table_info(sdk_sessions)").all().some(t=>t.name==="cwd")||(this.db.run("ALTER TABLE sdk_sessions ADD COLUMN cwd TEXT"),u.debug("DB","Added cwd column to sdk_sessions table (#2864)")),this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_cwd ON sdk_sessions(cwd)"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(53,new Date().toISOString())}ensureProjectNocaseIndexes(){this.db.run("CREATE INDEX IF NOT EXISTS idx_observations_project_nocase ON observations(project COLLATE NOCASE)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_observations_merged_into_nocase ON observations(merged_into_project COLLATE NOCASE)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_summaries_project_nocase ON session_summaries(project COLLATE NOCASE)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_summaries_merged_into_nocase ON session_summaries(merged_into_project COLLATE NOCASE)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_project_nocase ON sdk_sessions(project COLLATE NOCASE)"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(55,new Date().toISOString())}ensureAdvisorCallsTable(){this.db.run(`
828
+ `).run(t),s.changes>0&&c.info("DB","Re-queued prompts quarantined for size before the cloud-sync prompt clamp",{prompts:s.changes}),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(60,new Date().toISOString())})()}ensureSessionProjectKeySourceColumn(){this.db.query("PRAGMA table_info(sdk_sessions)").all().some(t=>t.name==="project_key_source")||(this.db.run("ALTER TABLE sdk_sessions ADD COLUMN project_key_source TEXT"),c.debug("DB","Added project_key_source column to sdk_sessions table")),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(59,new Date().toISOString())}ensureSessionCwdColumn(){this.db.query("PRAGMA table_info(sdk_sessions)").all().some(t=>t.name==="cwd")||(this.db.run("ALTER TABLE sdk_sessions ADD COLUMN cwd TEXT"),c.debug("DB","Added cwd column to sdk_sessions table (#2864)")),this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_cwd ON sdk_sessions(cwd)"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(53,new Date().toISOString())}ensureProjectNocaseIndexes(){this.db.run("CREATE INDEX IF NOT EXISTS idx_observations_project_nocase ON observations(project COLLATE NOCASE)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_observations_merged_into_nocase ON observations(merged_into_project COLLATE NOCASE)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_summaries_project_nocase ON session_summaries(project COLLATE NOCASE)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_summaries_merged_into_nocase ON session_summaries(merged_into_project COLLATE NOCASE)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_project_nocase ON sdk_sessions(project COLLATE NOCASE)"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(55,new Date().toISOString())}ensureAdvisorCallsTable(){this.db.run(`
824
829
  CREATE TABLE IF NOT EXISTS advisor_calls (
825
830
  id INTEGER PRIMARY KEY AUTOINCREMENT,
826
831
  session_db_id INTEGER NOT NULL,
@@ -843,7 +848,7 @@ ${L.stack??""}
843
848
  INSERT OR IGNORE INTO advisor_calls
844
849
  (session_db_id, content_session_id, project, platform_source, tool_use_id, advisor_model, cwd, last_user_message, transcript_path, transcript_byte_offset, advice, occurred_at_epoch, created_at, created_at_epoch)
845
850
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
846
- `).run(e.sessionDbId,e.contentSessionId,e.project,e.platformSource,e.toolUseId,e.advisorModel??null,e.cwd??null,e.lastUserMessage??null,e.transcriptPath??null,e.transcriptByteOffset??null,e.advice,e.occurredAtEpoch,t.toISOString(),t.getTime());return s.changes>0?{id:Number(s.lastInsertRowid),inserted:!0}:{id:this.db.prepare("SELECT id FROM advisor_calls WHERE tool_use_id = ?").get(e.toolUseId)?.id??0,inserted:!1}}getAdvisorCalls(e,t,s,n){let i="SELECT * FROM advisor_calls",o=[],a=[];s?(a.push("project = ?"),o.push(s)):(a.push("project != ?"),o.push(Q)),n&&(a.push("platform_source = ?"),o.push(n)),i+=` WHERE ${a.join(" AND ")}`,i+=" ORDER BY occurred_at_epoch DESC LIMIT ? OFFSET ?",o.push(t+1,e);let _=this.db.prepare(i).all(...o);return{items:_.slice(0,t),hasMore:_.length>t,offset:e,limit:t}}getAdvisorCallById(e){return this.db.prepare("SELECT * FROM advisor_calls WHERE id = ?").get(e)??null}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(o=>o.name==="agent_type"),n=t.some(o=>o.name==="agent_id");s||this.db.run("ALTER TABLE observations ADD COLUMN agent_type TEXT"),n||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 i=this.db.query("PRAGMA table_info(pending_messages)").all();if(i.length>0){let o=i.some(_=>_.name==="agent_type"),a=i.some(_=>_.name==="agent_id");o||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(n=>n.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(n){this.db.run("ROLLBACK");let i=n instanceof Error?n:new Error(String(n));throw u.error("DB","Failed to de-dupe pending_messages by tool_use_id, rolled back",{},i),n}}dedupePendingMessagesByToolUseId(){this.db.run(`
851
+ `).run(e.sessionDbId,e.contentSessionId,e.project,e.platformSource,e.toolUseId,e.advisorModel??null,e.cwd??null,e.lastUserMessage??null,e.transcriptPath??null,e.transcriptByteOffset??null,e.advice,e.occurredAtEpoch,t.toISOString(),t.getTime());return s.changes>0?{id:Number(s.lastInsertRowid),inserted:!0}:{id:this.db.prepare("SELECT id FROM advisor_calls WHERE tool_use_id = ?").get(e.toolUseId)?.id??0,inserted:!1}}getAdvisorCalls(e,t,s,n){let i="SELECT * FROM advisor_calls",r=[],a=[];s?(a.push("project = ?"),r.push(s)):(a.push("project != ?"),r.push(ee)),n&&(a.push("platform_source = ?"),r.push(n)),i+=` WHERE ${a.join(" AND ")}`,i+=" ORDER BY occurred_at_epoch DESC LIMIT ? OFFSET ?",r.push(t+1,e);let _=this.db.prepare(i).all(...r);return{items:_.slice(0,t),hasMore:_.length>t,offset:e,limit:t}}getAdvisorCallById(e){return this.db.prepare("SELECT * FROM advisor_calls WHERE id = ?").get(e)??null}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(r=>r.name==="agent_type"),n=t.some(r=>r.name==="agent_id");s||this.db.run("ALTER TABLE observations ADD COLUMN agent_type TEXT"),n||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 i=this.db.query("PRAGMA table_info(pending_messages)").all();if(i.length>0){let r=i.some(_=>_.name==="agent_type"),a=i.some(_=>_.name==="agent_id");r||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(n=>n.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(n){this.db.run("ROLLBACK");let i=n instanceof Error?n:new Error(String(n));throw c.error("DB","Failed to de-dupe pending_messages by tool_use_id, rolled back",{},i),n}}dedupePendingMessagesByToolUseId(){this.db.run(`
847
852
  DELETE FROM pending_messages
848
853
  WHERE id IN (
849
854
  SELECT id
@@ -868,7 +873,7 @@ ${L.stack??""}
868
873
  CREATE UNIQUE INDEX IF NOT EXISTS ux_pending_session_tool
869
874
  ON pending_messages(session_db_id, tool_use_id)
870
875
  WHERE tool_use_id IS NOT NULL
871
- `),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 t=this.db.query("PRAGMA table_info(observations)").all(),s=t.some(i=>i.name==="memory_session_id"),n=t.some(i=>i.name==="content_hash");if(!s||!n){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(i){this.db.run("ROLLBACK");let o=i instanceof Error?i:new Error(String(i));throw u.error("DB","Failed to de-dupe observations by content_hash, rolled back",{},o),i}}dedupeObservationsByContentHash(){this.db.run(`
876
+ `),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 t=this.db.query("PRAGMA table_info(observations)").all(),s=t.some(i=>i.name==="memory_session_id"),n=t.some(i=>i.name==="content_hash");if(!s||!n){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(i){this.db.run("ROLLBACK");let r=i instanceof Error?i:new Error(String(i));throw c.error("DB","Failed to de-dupe observations by content_hash, rolled back",{},r),i}}dedupeObservationsByContentHash(){this.db.run(`
872
877
  UPDATE observations
873
878
  SET content_hash = '__null_migration_' || id || '__'
874
879
  WHERE content_hash IS NULL
@@ -889,7 +894,7 @@ ${L.stack??""}
889
894
  `),this.db.run(`
890
895
  CREATE UNIQUE INDEX IF NOT EXISTS ux_observations_session_hash
891
896
  ON observations(memory_session_id, content_hash)
892
- `),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(s=>s.name==="metadata")||(this.db.run("ALTER TABLE observations ADD COLUMN metadata TEXT"),u.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){let s=this.db.prepare(`
897
+ `),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(s=>s.name==="metadata")||(this.db.run("ALTER TABLE observations ADD COLUMN metadata TEXT"),c.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){let s=this.db.prepare(`
893
898
  SELECT memory_session_id
894
899
  FROM sdk_sessions
895
900
  WHERE id = ?
@@ -901,7 +906,7 @@ ${L.stack??""}
901
906
  UPDATE tool_uses
902
907
  SET memory_session_id = ?
903
908
  WHERE session_db_id = ?
904
- `).run(t,e)})(),t&&this.requeuePromptSync(e))}enqueueMutationOp(e,t){if(!this.syncOpsEnabled)return;let s=JSON.parse(JSON.stringify(t));if(s.op==="set_prompt_session"){let n=s.target;n?.origin_device_id===null&&(n.origin_device_id="self")}Ke(s),t.op==="set_prompt_session"&&this.cachedStatement(`
909
+ `).run(t,e)})(),t&&this.requeuePromptSync(e))}enqueueMutationOp(e,t){if(!this.syncOpsEnabled)return;let s=JSON.parse(JSON.stringify(t));if(s.op==="set_prompt_session"){let n=s.target;n?.origin_device_id===null&&(n.origin_device_id="self")}Qe(s),t.op==="set_prompt_session"&&this.cachedStatement(`
905
910
  DELETE FROM sync_outbox
906
911
  WHERE json_valid(body)
907
912
  AND json_extract(body, '$.op') = 'set_prompt_session'
@@ -910,7 +915,7 @@ ${L.stack??""}
910
915
  `).run(t.target?.origin_device_id??null,String(t.target?.origin_local_id??"")),this.cachedStatement(`
911
916
  INSERT INTO sync_outbox (op_uuid, rev, body, created_at_epoch)
912
917
  VALUES (?, ?, ?, ?)
913
- `).run((0,Ne.randomUUID)(),String(e),JSON.stringify(t),Date.now())}requeuePromptSync(e){if(!this.syncOpsEnabled)return;let t=this.cachedStatement(`
918
+ `).run((0,he.randomUUID)(),String(e),JSON.stringify(t),Date.now())}requeuePromptSync(e){if(!this.syncOpsEnabled)return;let t=this.cachedStatement(`
914
919
  SELECT memory_session_id, project, content_session_id, platform_source
915
920
  FROM sdk_sessions WHERE id = ?
916
921
  `).get(e);if(!t?.memory_session_id)return;this.db.transaction(()=>{let n=this.cachedStatement(`
@@ -919,7 +924,7 @@ ${L.stack??""}
919
924
  `).all(e);if(n.length===0)return;let i=this.cachedStatement(`
920
925
  UPDATE user_prompts SET sync_rev = ?, synced_at = NULL
921
926
  WHERE id = ? AND origin_device_id IS NULL
922
- `);for(let o of n){let a=We(o.sync_rev);i.run(a,o.id),this.enqueueMutationOp(a,{op:"set_prompt_session",target:{origin_device_id:null,origin_local_id:o.id},fields:{memory_session_id:t.memory_session_id,project:t.project,content_session_id:t.content_session_id,platform_source:t.platform_source}})}})()}markSessionCompleted(e){let t=Date.now(),s=new Date(t).toISOString();this.db.prepare(`
927
+ `);for(let r of n){let a=ze(r.sync_rev);i.run(a,r.id),this.enqueueMutationOp(a,{op:"set_prompt_session",target:{origin_device_id:null,origin_local_id:r.id},fields:{memory_session_id:t.memory_session_id,project:t.project,content_session_id:t.content_session_id,platform_source:t.platform_source}})}})()}markSessionCompleted(e){let t=Date.now(),s=new Date(t).toISOString();this.db.prepare(`
923
928
  UPDATE sdk_sessions
924
929
  SET status = 'completed', completed_at = ?, completed_at_epoch = ?
925
930
  WHERE id = ?
@@ -931,28 +936,28 @@ ${L.stack??""}
931
936
  SELECT id, memory_session_id, worker_port FROM sdk_sessions WHERE id = ?
932
937
  `).get(e);if(!n)throw new Error(`Session ${e} not found in sdk_sessions`);return n.memory_session_id===null?(this.db.prepare(`
933
938
  UPDATE sdk_sessions SET memory_session_id = ? WHERE id = ?
934
- `).run(t,e),this.requeuePromptSync(e),u.info("DB","Registered memory_session_id before storage (FK fix)",{sessionDbId:e,newId:t})):n.memory_session_id!==t&&u.debug("DB","Keeping the registered memory_session_id",{sessionDbId:e,registered:n.memory_session_id,offered:t}),typeof s=="number"&&n.worker_port!==s&&this.db.prepare(`
939
+ `).run(t,e),this.requeuePromptSync(e),c.info("DB","Registered memory_session_id before storage (FK fix)",{sessionDbId:e,newId:t})):n.memory_session_id!==t&&c.debug("DB","Keeping the registered memory_session_id",{sessionDbId:e,registered:n.memory_session_id,offered:t}),typeof s=="number"&&n.worker_port!==s&&this.db.prepare(`
935
940
  UPDATE sdk_sessions SET worker_port = ? WHERE id = ?
936
- `).run(s,e),n.memory_session_id??t}getProjectReadKeys(e){return rt(this.db,e)}getAllProjects(e){let t=e?b(e):void 0,s=`
941
+ `).run(s,e),n.memory_session_id??t}getProjectReadKeys(e){return dt(this.db,e)}getAllProjects(e){let t=e?b(e):void 0,s=`
937
942
  SELECT DISTINCT project
938
943
  FROM sdk_sessions
939
944
  WHERE project IS NOT NULL AND project != ''
940
945
  AND project != ?
941
- `,n=[Q];return t&&(s+=" AND COALESCE(platform_source, ?) = ?",n.push(p,t)),s+=" ORDER BY project ASC",this.db.prepare(s).all(...n).map(o=>o.project)}getProjectCatalog(){let e=this.db.prepare(`
946
+ `,n=[ee];return t&&(s+=" AND COALESCE(platform_source, ?) = ?",n.push(T,t)),s+=" ORDER BY project ASC",this.db.prepare(s).all(...n).map(r=>r.project)}getProjectCatalog(){let e=this.db.prepare(`
942
947
  SELECT
943
- COALESCE(platform_source, '${p}') as platform_source,
948
+ COALESCE(platform_source, '${T}') as platform_source,
944
949
  project,
945
950
  MAX(started_at_epoch) as latest_epoch
946
951
  FROM sdk_sessions
947
952
  WHERE project IS NOT NULL AND project != ''
948
953
  AND project != ?
949
- GROUP BY COALESCE(platform_source, '${p}'), project
954
+ GROUP BY COALESCE(platform_source, '${T}'), project
950
955
  ORDER BY latest_epoch DESC
951
- `).all(Q),t=[],s=new Set,n={};for(let o of e){let a=b(o.platform_source);n[a]||(n[a]=[]),n[a].includes(o.project)||n[a].push(o.project),s.has(o.project)||(s.add(o.project),t.push(o.project))}let i=dt(Object.keys(n));return{projects:t,sources:i,projectsBySource:Object.fromEntries(i.map(o=>[o,n[o]||[]]))}}getSessionCatalog(e={}){let t=Math.min(Math.max(Math.trunc(e.limit??rn),1),on),s=Math.max(Math.trunc(e.offset??0),0),n=`
956
+ `).all(ee),t=[],s=new Set,n={};for(let r of e){let a=b(r.platform_source);n[a]||(n[a]=[]),n[a].includes(r.project)||n[a].push(r.project),s.has(r.project)||(s.add(r.project),t.push(r.project))}let i=Tt(Object.keys(n));return{projects:t,sources:i,projectsBySource:Object.fromEntries(i.map(r=>[r,n[r]||[]]))}}getSessionCatalog(e={}){let t=Math.min(Math.max(Math.trunc(e.limit??Tn),1),Sn),s=Math.max(Math.trunc(e.offset??0),0),n=`
952
957
  SELECT
953
958
  s.content_session_id,
954
959
  s.project,
955
- COALESCE(s.platform_source, '${p}') as platform_source,
960
+ COALESCE(s.platform_source, '${T}') as platform_source,
956
961
  s.custom_title,
957
962
  s.started_at_epoch,
958
963
  (
@@ -963,16 +968,16 @@ ${L.stack??""}
963
968
  FROM sdk_sessions s
964
969
  WHERE s.project IS NOT NULL AND s.project != ''
965
970
  AND s.project != ?
966
- `,i=[Q];e.project&&(n+=" AND s.project = ?",i.push(e.project)),e.platformSource&&(n+=` AND COALESCE(s.platform_source, '${p}') = ?`,i.push(b(e.platformSource))),n+=" ORDER BY s.started_at_epoch DESC, s.id DESC LIMIT ? OFFSET ?",i.push(t+1,s);let o=this.db.prepare(n).all(...i);return{sessions:o.slice(0,t),hasMore:o.length>t}}getUserPromptById(e){return this.db.prepare(`
971
+ `,i=[ee];e.project&&(n+=" AND s.project = ?",i.push(e.project)),e.platformSource&&(n+=` AND COALESCE(s.platform_source, '${T}') = ?`,i.push(b(e.platformSource))),n+=" ORDER BY s.started_at_epoch DESC, s.id DESC LIMIT ? OFFSET ?",i.push(t+1,s);let r=this.db.prepare(n).all(...i);return{sessions:r.slice(0,t),hasMore:r.length>t}}getUserPromptById(e){return this.db.prepare(`
967
972
  SELECT
968
973
  up.*,
969
974
  s.memory_session_id,
970
975
  s.project,
971
- COALESCE(s.platform_source, '${p}') as platform_source
976
+ COALESCE(s.platform_source, '${T}') as platform_source
972
977
  FROM user_prompts up
973
978
  JOIN sdk_sessions s ON up.session_db_id = s.id
974
979
  WHERE up.id = ?
975
- `).get(e)}findRecentDuplicateUserPrompt(e,t,s,n){return jt(this.db,e,ne(t),s,this.resolvePromptSessionDbId(e,n)??void 0)}getRecentSessionsWithStatus(e,t=3,s){let n=[e],i="";return s&&(i=`AND COALESCE(NULLIF(s.platform_source, ''), '${p}') = ?`,n.push(b(s))),n.push(t),this.db.prepare(`
980
+ `).get(e)}findRecentDuplicateUserPrompt(e,t,s,n){return Jt(this.db,e,ie(t),s,this.resolvePromptSessionDbId(e,n)??void 0)}getRecentSessionsWithStatus(e,t=3,s){let n=[e],i="";return s&&(i=`AND COALESCE(NULLIF(s.platform_source, ''), '${T}') = ?`,n.push(b(s))),n.push(t),this.db.prepare(`
976
981
  SELECT * FROM (
977
982
  SELECT
978
983
  s.memory_session_id,
@@ -995,7 +1000,7 @@ ${L.stack??""}
995
1000
  SELECT 1
996
1001
  FROM sdk_sessions s
997
1002
  WHERE s.memory_session_id = observations.memory_session_id
998
- AND COALESCE(NULLIF(s.platform_source, ''), '${p}') = ?
1003
+ AND COALESCE(NULLIF(s.platform_source, ''), '${T}') = ?
999
1004
  )
1000
1005
  `,s.push(b(t))),this.db.prepare(`
1001
1006
  SELECT title, subtitle, type, prompt_number
@@ -1008,24 +1013,24 @@ ${L.stack??""}
1008
1013
  FROM observations o
1009
1014
  LEFT JOIN sdk_sessions s ON s.memory_session_id = o.memory_session_id
1010
1015
  WHERE o.id = ?
1011
- AND COALESCE(NULLIF(s.platform_source, ''), '${p}') = ?
1016
+ AND COALESCE(NULLIF(s.platform_source, ''), '${T}') = ?
1012
1017
  `).get(e,b(t))||null:this.db.prepare(`
1013
1018
  SELECT *
1014
1019
  FROM observations
1015
1020
  WHERE id = ?
1016
- `).get(e)||null}upsertToolUse(e){return pt(this.db,e)}linkToolUsesToObservation(e){return mt(this.db,e)}getToolUsesByIds(e,t={}){return St(this.db,e,t)}queryToolUses(e={}){return At(this.db,e)}appendWorkStateEntry(e){let t=ft(this.db,e);return $({projects:[e.project]},"appendWorkStateEntry"),t}getWorkStateEntries(e,t){let s=Rt(this.db,this.getProjectReadKeys(e),t),n=a=>a.replace(/[A-Z]/g,_=>_.toLowerCase()),i=new Set(e.map(n)),o=e.at(-1);return s.map(a=>o&&i.has(n(a.project))?{...a,scope_project:o}:a)}countToolUses(e={}){return Ot(this.db,e)}getObservationsByIds(e,t={}){if(e.length===0)return[];let{orderBy:s="date_desc",platformSource:n,type:i,concepts:o,files:a}=t,_=Ye(t.limit),E=w(t),c=s==="relevance",d=s==="date_asc"?"ASC":"DESC",l=c?"":`ORDER BY o.created_at_epoch ${d}, o.id ${d}`,O=_&&!c?"LIMIT ?":"",L=e.map(()=>"?").join(","),I=[...e],f=[];if(E.length>0){let T=x("o",E,{includeMerged:!0});f.push(T.sql),I.push(...T.params)}if(n&&(f.push(`COALESCE(NULLIF(s.platform_source, ''), '${p}') = ?`),I.push(b(n))),i)if(Array.isArray(i)){let T=i.map(()=>"?").join(",");f.push(`o.type IN (${T})`),I.push(...i)}else f.push("o.type = ?"),I.push(i);if(o){let T=Array.isArray(o)?o:[o],S=T.map(()=>"EXISTS (SELECT 1 FROM json_each(o.concepts) WHERE value = ?)");I.push(...T),f.push(`(${S.join(" OR ")})`)}if(a){let T=Array.isArray(a)?a:[a],S=T.map(()=>"(EXISTS (SELECT 1 FROM json_each(o.files_read) WHERE value LIKE ? ESCAPE '\\') OR EXISTS (SELECT 1 FROM json_each(o.files_modified) WHERE value LIKE ? ESCAPE '\\'))");T.forEach(D=>{let v=D.replace(/[\\%_]/g,"\\$&");I.push(`%${v}%`,`%${v}%`)}),f.push(`(${S.join(" OR ")})`)}let g=f.length>0?`WHERE o.id IN (${L}) AND ${f.join(" AND ")}`:`WHERE o.id IN (${L})`;O&&I.push(_);let N=this.db.prepare(`
1021
+ `).get(e)||null}upsertToolUse(e){return Ot(this.db,e)}linkToolUsesToObservation(e){return ft(this.db,e)}getToolUsesByIds(e,t={}){return Nt(this.db,e,t)}queryToolUses(e={}){return bt(this.db,e)}appendWorkStateEntry(e){let t=It(this.db,e);return j({projects:[e.project]},"appendWorkStateEntry"),t}getWorkStateEntries(e,t){let s=ht(this.db,this.getProjectReadKeys(e),t),n=a=>a.replace(/[A-Z]/g,_=>_.toLowerCase()),i=new Set(e.map(n)),r=e.at(-1);return s.map(a=>r&&i.has(n(a.project))?{...a,scope_project:r}:a)}countToolUses(e={}){return Ct(this.db,e)}getObservationsByIds(e,t={}){if(e.length===0)return[];let{orderBy:s="date_desc",platformSource:n,type:i,concepts:r,files:a}=t,_=Ze(t.limit),E=w(t),d=s==="relevance",u=s==="date_asc"?"ASC":"DESC",l=d?"":`ORDER BY o.created_at_epoch ${u}, o.id ${u}`,p=_&&!d?"LIMIT ?":"",S=e.map(()=>"?").join(","),h=[...e],f=[];if(E.length>0){let g=x("o",E,{includeMerged:!0});f.push(g.sql),h.push(...g.params)}if(n&&(f.push(`COALESCE(NULLIF(s.platform_source, ''), '${T}') = ?`),h.push(b(n))),i)if(Array.isArray(i)){let g=i.map(()=>"?").join(",");f.push(`o.type IN (${g})`),h.push(...i)}else f.push("o.type = ?"),h.push(i);if(r){let g=Array.isArray(r)?r:[r],D=g.map(()=>"EXISTS (SELECT 1 FROM json_each(o.concepts) WHERE value = ?)");h.push(...g),f.push(`(${D.join(" OR ")})`)}if(a){let g=Array.isArray(a)?a:[a],D=g.map(()=>"(EXISTS (SELECT 1 FROM json_each(o.files_read) WHERE value LIKE ? ESCAPE '\\') OR EXISTS (SELECT 1 FROM json_each(o.files_modified) WHERE value LIKE ? ESCAPE '\\'))");g.forEach(O=>{let v=O.replace(/[\\%_]/g,"\\$&");h.push(`%${v}%`,`%${v}%`)}),f.push(`(${D.join(" OR ")})`)}let C=f.length>0?`WHERE o.id IN (${S}) AND ${f.join(" AND ")}`:`WHERE o.id IN (${S})`;p&&h.push(_);let m=this.db.prepare(`
1017
1022
  SELECT o.*
1018
1023
  FROM observations o
1019
1024
  LEFT JOIN sdk_sessions s ON s.memory_session_id = o.memory_session_id
1020
- ${g}
1025
+ ${C}
1021
1026
  ${l}
1022
- ${O}
1023
- `).all(...I);if(!c)return N;let A=new Map(N.map(T=>[T.id,T])),y=e.map(T=>A.get(T)).filter(T=>!!T);return _?y.slice(0,_):y}getSummaryForSession(e,t){let s=[e],n="";return t&&(n=`
1027
+ ${p}
1028
+ `).all(...h);if(!d)return m;let A=new Map(m.map(g=>[g.id,g])),y=e.map(g=>A.get(g)).filter(g=>!!g);return _?y.slice(0,_):y}getSummaryForSession(e,t){let s=[e],n="";return t&&(n=`
1024
1029
  AND EXISTS (
1025
1030
  SELECT 1
1026
1031
  FROM sdk_sessions sdk
1027
1032
  WHERE sdk.memory_session_id = session_summaries.memory_session_id
1028
- AND COALESCE(NULLIF(sdk.platform_source, ''), '${p}') = ?
1033
+ AND COALESCE(NULLIF(sdk.platform_source, ''), '${T}') = ?
1029
1034
  )
1030
1035
  `,s.push(b(t))),this.db.prepare(`
1031
1036
  SELECT
@@ -1039,7 +1044,7 @@ ${L.stack??""}
1039
1044
  LIMIT 1
1040
1045
  `).get(...s)||null}getSessionById(e){return this.db.prepare(`
1041
1046
  SELECT id, content_session_id, memory_session_id, project,
1042
- COALESCE(platform_source, '${p}') as platform_source,
1047
+ COALESCE(platform_source, '${T}') as platform_source,
1043
1048
  user_prompt, custom_title, status,
1044
1049
  observed_model, observed_billing
1045
1050
  FROM sdk_sessions
@@ -1051,11 +1056,11 @@ ${L.stack??""}
1051
1056
  WHERE COALESCE(NULLIF(platform_source, ''), ?) = ?
1052
1057
  AND content_session_id = ?
1053
1058
  LIMIT 1
1054
- `).get(p,b(t),e)?.id??null}claimTelegramWrapup({platformSource:e,contentSessionId:t,project:s,routeKey:n,summaryCreatedAtEpoch:i}){let o=Date.now();return this.db.prepare(`
1059
+ `).get(T,b(t),e)?.id??null}claimTelegramWrapup({platformSource:e,contentSessionId:t,project:s,routeKey:n,summaryCreatedAtEpoch:i}){let r=Date.now();return this.db.prepare(`
1055
1060
  INSERT OR IGNORE INTO telegram_wrapups
1056
1061
  (platform_source, content_session_id, project, route_key, summary_created_at_epoch, status, claimed_at_epoch, sent_at_epoch)
1057
1062
  VALUES (?, ?, ?, ?, ?, 'claimed', ?, NULL)
1058
- `).run(b(e),t,s,n,i,o).changes===1?!0:this.db.prepare(`
1063
+ `).run(b(e),t,s,n,i,r).changes===1?!0:this.db.prepare(`
1059
1064
  UPDATE telegram_wrapups
1060
1065
  SET summary_created_at_epoch = ?, claimed_at_epoch = ?, sent_at_epoch = NULL
1061
1066
  WHERE platform_source = ?
@@ -1064,7 +1069,7 @@ ${L.stack??""}
1064
1069
  AND route_key = ?
1065
1070
  AND status = 'claimed'
1066
1071
  AND claimed_at_epoch <= ?
1067
- `).run(i,o,b(e),t,s,n,o-ts).changes===1}markTelegramWrapupSent({platformSource:e,contentSessionId:t,project:s,routeKey:n}){this.db.prepare(`
1072
+ `).run(i,r,b(e),t,s,n,r-ds).changes===1}markTelegramWrapupSent({platformSource:e,contentSessionId:t,project:s,routeKey:n}){this.db.prepare(`
1068
1073
  UPDATE telegram_wrapups
1069
1074
  SET status = 'sent', sent_at_epoch = ?
1070
1075
  WHERE platform_source = ?
@@ -1084,19 +1089,19 @@ ${L.stack??""}
1084
1089
  SET observed_model = COALESCE(?, observed_model),
1085
1090
  observed_billing = COALESCE(?, observed_billing)
1086
1091
  WHERE id = ?
1087
- `).run(t||null,s||null,e)}getSdkSessionsBySessionIds(e,t=[]){if(e.length===0&&t.length===0)return[];let s=[...new Set(e),...new Set(t)],n=new Map;for(let i=0;i<s.length;i+=500){let o=s.slice(i,i+500),a=o.filter(d=>typeof d=="string"),_=o.filter(d=>typeof d=="number"),E=[];a.length&&E.push(`memory_session_id IN (${a.map(()=>"?").join(",")})`),_.length&&E.push(`id IN (SELECT session_db_id FROM user_prompts WHERE id IN (${_.map(()=>"?").join(",")}))`);let c=this.db.prepare(`
1092
+ `).run(t||null,s||null,e)}getSdkSessionsBySessionIds(e,t=[]){if(e.length===0&&t.length===0)return[];let s=[...new Set(e),...new Set(t)],n=new Map;for(let i=0;i<s.length;i+=500){let r=s.slice(i,i+500),a=r.filter(u=>typeof u=="string"),_=r.filter(u=>typeof u=="number"),E=[];a.length&&E.push(`memory_session_id IN (${a.map(()=>"?").join(",")})`),_.length&&E.push(`id IN (SELECT session_db_id FROM user_prompts WHERE id IN (${_.map(()=>"?").join(",")}))`);let d=this.db.prepare(`
1088
1093
  SELECT id, content_session_id, memory_session_id, project,
1089
- COALESCE(platform_source, '${p}') as platform_source,
1094
+ COALESCE(platform_source, '${T}') as platform_source,
1090
1095
  user_prompt, custom_title,
1091
1096
  started_at, started_at_epoch, completed_at, completed_at_epoch, status
1092
1097
  FROM sdk_sessions
1093
1098
  WHERE ${E.join(" OR ")}
1094
1099
  ORDER BY started_at_epoch DESC
1095
- `);for(let d of c.all(...o))n.set(d.id,d)}return[...n.values()].sort((i,o)=>o.started_at_epoch-i.started_at_epoch)}getPromptNumberFromUserPrompts(e,t,s){let n=this.resolvePromptSessionDbId(e,t),i=n!==null?"session_db_id = ?":"content_session_id = ?",o=n!==null?n:e;return s!==void 0?this.db.prepare(`
1096
- SELECT COUNT(*) as count FROM user_prompts WHERE ${i} AND created_at_epoch <= ?
1097
- `).get(o,s).count:this.db.prepare(`
1098
- SELECT COUNT(*) as count FROM user_prompts WHERE ${i}
1099
- `).get(o).count}getLatestPromptTextFromUserPrompts(e,t){let s=this.resolvePromptSessionDbId(e,t),n=s!==null?"session_db_id = ?":"content_session_id = ?",i=s!==null?s:e;return this.db.prepare(`
1100
+ `);for(let u of d.all(...r))n.set(u.id,u)}return[...n.values()].sort((i,r)=>r.started_at_epoch-i.started_at_epoch)}getPromptNumberFromUserPrompts(e,t,s){let n=this.resolvePromptSessionDbId(e,t),i=n!==null?"session_db_id = ?":"content_session_id = ?",r=n!==null?n:e;return s!==void 0?this.db.prepare(`
1101
+ SELECT COALESCE(MAX(prompt_number), 0) as count FROM user_prompts WHERE ${i} AND created_at_epoch <= ?
1102
+ `).get(r,s).count:this.db.prepare(`
1103
+ SELECT COALESCE(MAX(prompt_number), 0) as count FROM user_prompts WHERE ${i}
1104
+ `).get(r).count}getLatestPromptTextFromUserPrompts(e,t){let s=this.resolvePromptSessionDbId(e,t),n=s!==null?"session_db_id = ?":"content_session_id = ?",i=s!==null?s:e;return this.db.prepare(`
1100
1105
  SELECT prompt_text
1101
1106
  FROM user_prompts
1102
1107
  WHERE ${n}
@@ -1104,30 +1109,30 @@ ${L.stack??""}
1104
1109
  AND length(trim(prompt_text)) > 0
1105
1110
  ORDER BY prompt_number DESC, created_at_epoch DESC
1106
1111
  LIMIT 1
1107
- `).get(i)?.prompt_text??null}createSDKSession(e,t,s,n,i){let o=new Date,a=o.getTime(),_=i?b(i):p,E=ne(s);n&&this.validateSetTitleMutation(e,_,n);let c=this.db.prepare(`
1112
+ `).get(i)?.prompt_text??null}createSDKSession(e,t,s,n,i){let r=new Date,a=r.getTime(),_=i?b(i):T,E=ie(s);n&&this.validateSetTitleMutation(e,_,n);let d=this.db.prepare(`
1108
1113
  SELECT id, platform_source
1109
1114
  FROM sdk_sessions
1110
1115
  WHERE COALESCE(NULLIF(platform_source, ''), ?) = ?
1111
1116
  AND content_session_id = ?
1112
- `).get(p,_,e);if(c){if(t&&this.db.prepare(`
1117
+ `).get(T,_,e);if(d){if(t&&this.db.prepare(`
1113
1118
  UPDATE sdk_sessions SET project = ?
1114
1119
  WHERE id = ? AND (project IS NULL OR project = '')
1115
- `).run(t,c.id),E&&E!==Be&&this.db.prepare(`
1120
+ `).run(t,d.id),E&&E!==We&&this.db.prepare(`
1116
1121
  UPDATE sdk_sessions SET user_prompt = ?
1117
1122
  WHERE id = ? AND (user_prompt IS NULL OR user_prompt = '' OR user_prompt = ?)
1118
- `).run(E,c.id,Be),n){let l=this.db.prepare("SELECT custom_title FROM sdk_sessions WHERE id = ?").get(c.id);l&&l.custom_title===null&&(this.db.prepare(`
1123
+ `).run(E,d.id,We),n){let l=this.db.prepare("SELECT custom_title FROM sdk_sessions WHERE id = ?").get(d.id);l&&l.custom_title===null&&(this.db.prepare(`
1119
1124
  UPDATE sdk_sessions SET custom_title = ?
1120
1125
  WHERE id = ? AND custom_title IS NULL
1121
- `).run(n,c.id),this.enqueueSetTitleOp(e,_,n))}return c.id}let d=this.db.prepare(`
1126
+ `).run(n,d.id),this.enqueueSetTitleOp(e,_,n))}return d.id}let u=this.db.prepare(`
1122
1127
  INSERT INTO sdk_sessions
1123
1128
  (content_session_id, memory_session_id, project, platform_source, user_prompt, custom_title, started_at, started_at_epoch, status)
1124
1129
  VALUES (?, NULL, ?, ?, ?, ?, ?, ?, 'active')
1125
- `).run(e,t,_,E,n||null,o.toISOString(),a);return n&&this.enqueueSetTitleOp(e,_,n),Number(d.lastInsertRowid)}setSessionCwd(e,t,s){t.trim()&&this.db.prepare("UPDATE sdk_sessions SET cwd = ?, project_key_source = ? WHERE id = ? AND cwd IS NULL").run(t,s??null,e)}getSessionCwd(e){return this.db.prepare("SELECT cwd FROM sdk_sessions WHERE id = ?").get(e)?.cwd??null}enqueueSetTitleOp(e,t,s){let n=this.validateSetTitleMutation(e,t,s);this.enqueueMutationOp("1",n)}validateSetTitleMutation(e,t,s){let n={op:"set_title",target:{content_session_id:e,platform_source:t},fields:{custom_title:s}};return Ke(n),n}saveUserPrompt(e,t,s,n,i,o){let a=new Date,_=a.getTime(),E=ne(s),c=this.resolvePromptSessionDbId(e,n);return this.db.prepare(`
1130
+ `).run(e,t,_,E,n||null,r.toISOString(),a);return n&&this.enqueueSetTitleOp(e,_,n),Number(u.lastInsertRowid)}setSessionCwd(e,t,s){t.trim()&&this.db.prepare("UPDATE sdk_sessions SET cwd = ?, project_key_source = ? WHERE id = ? AND cwd IS NULL").run(t,s??null,e)}getSessionCwd(e){return this.db.prepare("SELECT cwd FROM sdk_sessions WHERE id = ?").get(e)?.cwd??null}enqueueSetTitleOp(e,t,s){let n=this.validateSetTitleMutation(e,t,s);this.enqueueMutationOp("1",n)}validateSetTitleMutation(e,t,s){let n={op:"set_title",target:{content_session_id:e,platform_source:t},fields:{custom_title:s}};return Qe(n),n}saveUserPrompt(e,t,s,n,i,r){let a=new Date,_=a.getTime(),E=ie(s),d=this.resolvePromptSessionDbId(e,n);return this.db.prepare(`
1126
1131
  INSERT INTO user_prompts
1127
1132
  (session_db_id, content_session_id, prompt_number, prompt_text, created_at, created_at_epoch, native_prompt_id, native_prompt_hash)
1128
1133
  VALUES (?, ?, ?, ?, ?, ?, ?, ?)
1129
- `).run(c,e,t,E,a.toISOString(),_,i??null,o??null).lastInsertRowid}saveNativeUserPrompt(e,t,s,n,i=n){if(!s||s.length>256||/[\s\x00-\x1f\x7f]/.test(s))throw new Error("Invalid native prompt identity");let o=ne(n),a=(0,Ne.createHash)("sha256").update(Te(i).trim()).digest("hex");return this.db.transaction(()=>{let _=this.db.prepare(`SELECT id, prompt_number, native_prompt_hash FROM user_prompts
1130
- WHERE session_db_id = ? AND native_prompt_id = ?`).get(t,s);if(_){if(_.native_prompt_hash!==a)throw new Error("Native prompt identity was reused with different text");return{id:_.id,promptNumber:_.prompt_number,duplicate:!0}}let E=this.getPromptNumberFromUserPrompts(e,t)+1;return this.reopenCompletedSession(t),{id:this.saveUserPrompt(e,E,o,t,s,a),promptNumber:E,duplicate:!1}}).immediate()}getUserPrompt(e,t,s){let n=this.resolvePromptSessionDbId(e,s);return n!==null?this.db.prepare(`
1134
+ `).run(d,e,t,E,a.toISOString(),_,i??null,r??null).lastInsertRowid}saveNativeUserPrompt(e,t,s,n,i=n){if(!s||s.length>256||/[\s\x00-\x1f\x7f]/.test(s))throw new Error("Invalid native prompt identity");let r=ie(n),a=(0,he.createHash)("sha256").update(fe(i).trim()).digest("hex");return this.db.transaction(()=>{let _=this.db.prepare(`SELECT id, prompt_number, native_prompt_hash FROM user_prompts
1135
+ WHERE session_db_id = ? AND native_prompt_id = ?`).get(t,s);if(_){if(_.native_prompt_hash!==a)throw new Error("Native prompt identity was reused with different text");return{id:_.id,promptNumber:_.prompt_number,duplicate:!0}}let E=this.getPromptNumberFromUserPrompts(e,t)+1;return this.reopenCompletedSession(t),{id:this.saveUserPrompt(e,E,r,t,s,a),promptNumber:E,duplicate:!1}}).immediate()}getUserPrompt(e,t,s){let n=this.resolvePromptSessionDbId(e,s);return n!==null?this.db.prepare(`
1131
1136
  SELECT prompt_text
1132
1137
  FROM user_prompts
1133
1138
  WHERE session_db_id = ? AND prompt_number = ?
@@ -1137,12 +1142,12 @@ ${L.stack??""}
1137
1142
  FROM user_prompts
1138
1143
  WHERE content_session_id = ? AND prompt_number = ?
1139
1144
  LIMIT 1
1140
- `).get(e,t)?.prompt_text??null}dedupConfig(){let e=Y.loadFromFile(_e),t=(n,i)=>{let o=Number(e[n]);return Number.isFinite(o)?o:i},s=(n,i)=>Math.trunc(t(n,i));return{enabled:e.CLAUDE_MEM_DEDUP_ENABLED==="true",cosineThreshold:t("CLAUDE_MEM_DEDUP_COSINE_THRESHOLD",.8),idfVetoDf:s("CLAUDE_MEM_DEDUP_IDF_VETO_DF",10),minSharedTokens:s("CLAUDE_MEM_DEDUP_MIN_SHARED_TOKENS",2),maxScan:s("CLAUDE_MEM_DEDUP_MAX_SCAN",2e3),maxBackfillRows:s("CLAUDE_MEM_DEDUP_MAX_BACKFILL_ROWS",5e4),minProjectDocs:s("CLAUDE_MEM_DEDUP_MIN_PROJECT_DOCS",10)}}listDedupCandidates(e,t=100){let s="SELECT c.id, c.project, c.method, c.score, c.status, c.created_at_epoch, c.observation_id, o1.title AS observation_title, c.duplicate_of_id, o2.title AS duplicate_of_title FROM observation_dedup_candidates c JOIN observations o1 ON o1.id = c.observation_id JOIN observations o2 ON o2.id = c.duplicate_of_id ",n="ORDER BY c.score DESC, c.id DESC LIMIT ?";return e?this.db.prepare(`${s}WHERE c.project = ? ${n}`).all(e,t):this.db.prepare(`${s}${n}`).all(t)}isDedupEnabled(){return this.dedupConfig().enabled}runDedupScan(){return Gt(this.db,this.dedupConfig())}maintainDedupOnInsert(e,t,s,n){Pt(this.db,e,s),Xt(this.db,e,n.minProjectDocs)&&Ht(this.db,e,t,s,n)}storeObservation(e,t,s,n,i=0,o,a){if(!ve(s.title))throw new Error("storeObservation requires a non-empty title");let _=this.storeObservations(e,t,[s],null,n,i,o,a);return{id:_.observationIds[0],createdAtEpoch:_.createdAtEpoch,mergedIntoExisting:_.mergedIntoExisting[0]??!1}}storeSummary(e,t,s,n,i=0,o){let a=o??Date.now(),_=new Date(a).toISOString(),c=this.db.prepare(`
1145
+ `).get(e,t)?.prompt_text??null}dedupConfig(){let e=Y.loadFromFile(pe),t=(n,i)=>{let r=Number(e[n]);return Number.isFinite(r)?r:i},s=(n,i)=>Math.trunc(t(n,i));return{enabled:e.CLAUDE_MEM_DEDUP_ENABLED==="true",cosineThreshold:t("CLAUDE_MEM_DEDUP_COSINE_THRESHOLD",.8),idfVetoDf:s("CLAUDE_MEM_DEDUP_IDF_VETO_DF",10),minSharedTokens:s("CLAUDE_MEM_DEDUP_MIN_SHARED_TOKENS",2),maxScan:s("CLAUDE_MEM_DEDUP_MAX_SCAN",2e3),maxBackfillRows:s("CLAUDE_MEM_DEDUP_MAX_BACKFILL_ROWS",5e4),minProjectDocs:s("CLAUDE_MEM_DEDUP_MIN_PROJECT_DOCS",10)}}listDedupCandidates(e,t=100,s){let n="SELECT c.id, c.project, c.method, c.score, c.status, c.created_at_epoch, c.observation_id, o1.title AS observation_title, c.duplicate_of_id, o2.title AS duplicate_of_title FROM observation_dedup_candidates c JOIN observations o1 ON o1.id = c.observation_id JOIN observations o2 ON o2.id = c.duplicate_of_id ",i="(? IS NULL OR c.status = ?) ",r="ORDER BY c.score DESC, c.id DESC LIMIT ?",a=s??null;return e?this.db.prepare(`${n}WHERE c.project = ? AND ${i}${r}`).all(e,a,a,t):this.db.prepare(`${n}WHERE ${i}${r}`).all(a,a,t)}resolveDedupCandidate(e,t){return this.db.prepare("UPDATE observation_dedup_candidates SET status = ? WHERE id = ?").run(t,e).changes>0}isDedupEnabled(){return this.dedupConfig().enabled}runDedupScan(){return Vt(this.db,this.dedupConfig())}maintainDedupOnInsert(e,t,s,n){Ht(this.db,e,s),Yt(this.db,e,n.minProjectDocs)&&qt(this.db,e,t,s,n)}storeObservation(e,t,s,n,i=0,r,a,_={}){if(!ke(s.title))throw new Error("storeObservation requires a non-empty title");let E=this.storeObservations(e,t,[s],null,n,i,r,a,_);return{id:E.observationIds[0],createdAtEpoch:E.createdAtEpoch,mergedIntoExisting:E.mergedIntoExisting[0]??!1}}storeSummary(e,t,s,n,i=0,r){let a=r??Date.now(),_=new Date(a).toISOString(),d=this.db.prepare(`
1141
1146
  INSERT INTO session_summaries
1142
1147
  (memory_session_id, project, request, investigated, learned, completed,
1143
1148
  next_steps, files_read, files_edited, notes, prompt_number, discovery_tokens, created_at, created_at_epoch)
1144
1149
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
1145
- `).run(e,t,s.request,s.investigated,s.learned,s.completed,s.next_steps,JSON.stringify(s.files_read??[]),JSON.stringify(s.files_edited??[]),s.notes,n||null,i,_,a);return $({projects:[t]},"storeSummary"),{id:Number(c.lastInsertRowid),createdAtEpoch:a}}storeObservations(e,t,s,n,i,o=0,a,_){let E=a??Date.now(),c=new Date(E).toISOString(),d=Et(E),l=new Date(E),O=this.dedupConfig(),L=b(this.db.prepare("SELECT platform_source FROM sdk_sessions WHERE memory_session_id = ? LIMIT 1").get(e)?.platform_source),f=this.db.transaction(()=>{let g=[],m=[],N=[],A=this.db.prepare(`
1150
+ `).run(e,t,s.request,s.investigated,s.learned,s.completed,s.next_steps,JSON.stringify(s.files_read??[]),JSON.stringify(s.files_edited??[]),s.notes,n||null,i,_,a);return j({projects:[t]},"storeSummary"),{id:Number(d.lastInsertRowid),createdAtEpoch:a}}storeObservations(e,t,s,n,i,r=0,a,_,E={}){let d=a??Date.now(),u=new Date(d).toISOString(),l=mt(d),p=new Date(d),S=this.dedupConfig(),h=b(this.db.prepare("SELECT platform_source FROM sdk_sessions WHERE memory_session_id = ? LIMIT 1").get(e)?.platform_source),C=this.db.transaction(()=>{let R=[],m=[],A=[],y=this.db.prepare(`
1146
1151
  INSERT INTO observations
1147
1152
  (memory_session_id, project, type, title, subtitle, facts, narrative, concepts,
1148
1153
  files_read, files_modified, prompt_number, discovery_tokens, agent_type, agent_id, content_hash, created_at, created_at_epoch,
@@ -1150,30 +1155,30 @@ ${L.stack??""}
1150
1155
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
1151
1156
  ON CONFLICT(memory_session_id, content_hash) DO NOTHING
1152
1157
  RETURNING id
1153
- `),y=this.db.prepare("SELECT id FROM observations WHERE memory_session_id = ? AND content_hash = ?");for(let S of s){if(!ve(S.title)){u.debug("DB","Skipping observation with empty title");continue}let D=it(e,S.title,S.narrative),v=xe(t,L,S.title,pe(S.agent_id,S.agent_type));if(O.enabled){let be=y.get(e,D);if(be){ce(this.db,be.id,l),g.push(be.id),m.push(!1);continue}let oe=wt(this.db,t,v);if(oe){this.db.prepare("UPDATE observations SET occurrence_count = occurrence_count + 1 WHERE id = ?").run(oe.id),ce(this.db,oe.id,l),g.push(oe.id),m.push(!0);continue}}let q=A.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),i||null,o,S.agent_type??null,S.agent_id??null,D,c,E,_||null,S.metadata??null,v,d.dates,d.lastReinforced);if(q){O.enabled&&this.maintainDedupOnInsert(t,q.id,S.title,O),g.push(q.id),m.push(!1),N.push(q.id);continue}let J=y.get(e,D);if(!J)throw new Error(`storeObservations: ON CONFLICT without existing row for content_hash=${D}`);ce(this.db,J.id,l),g.push(J.id),m.push(!1)}let T=null;if(n){let S=ss(s),D=n.files_read??S.files_read,v=n.files_edited??S.files_edited,J=this.db.prepare(`
1158
+ `),g=this.db.prepare("SELECT id FROM observations WHERE memory_session_id = ? AND content_hash = ?");for(let O of s){if(!ke(O.title)){c.debug("DB","Skipping observation with empty title");continue}let v=ut(e,O.title,O.narrative),de=ge(t,h,O.title,ne(O.agent_id,O.agent_type));if(S.enabled){let De=g.get(e,v);if(De){Se(this.db,De.id,p),R.push(De.id),m.push(!1);continue}let ce=E.skipTitleDedup?null:Gt(this.db,t,de);if(ce){this.db.prepare("UPDATE observations SET occurrence_count = occurrence_count + 1 WHERE id = ?").run(ce.id),Se(this.db,ce.id,p),R.push(ce.id),m.push(!0);continue}}let z=y.get(e,t,O.type,O.title,O.subtitle,JSON.stringify(O.facts),O.narrative,JSON.stringify(O.concepts),JSON.stringify(O.files_read),JSON.stringify(O.files_modified),i||null,r,O.agent_type??null,O.agent_id??null,v,u,d,_||null,O.metadata??null,de,l.dates,l.lastReinforced);if(z){S.enabled&&this.maintainDedupOnInsert(t,z.id,O.title,S),R.push(z.id),m.push(!1),A.push(z.id);continue}let Q=g.get(e,v);if(!Q)throw new Error(`storeObservations: ON CONFLICT without existing row for content_hash=${v}`);Se(this.db,Q.id,p),R.push(Q.id),m.push(!1)}let D=null;if(n){let O=cs(s),v=n.files_read??O.files_read,de=n.files_edited??O.files_edited,Q=this.db.prepare(`
1154
1159
  INSERT INTO session_summaries
1155
1160
  (memory_session_id, project, request, investigated, learned, completed,
1156
1161
  next_steps, files_read, files_edited, notes, prompt_number, discovery_tokens, created_at, created_at_epoch)
1157
1162
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
1158
- `).run(e,t,n.request,n.investigated,n.learned,n.completed,n.next_steps,JSON.stringify(D),JSON.stringify(v),n.notes,i||null,o,c,E);T=Number(J.lastInsertRowid)}return{observationIds:g,mergedIntoExisting:m,insertedObservationIds:N,summaryId:T,createdAtEpoch:E}})();return $({projects:[t]},"storeObservations"),f}updateDiscoveryTokens(e,t,s){e.length===0&&t===null||this.db.transaction(()=>{let n=this.db.prepare("UPDATE observations SET discovery_tokens = ? WHERE id = ?");for(let i of e)n.run(s,i);t!==null&&this.db.prepare("UPDATE session_summaries SET discovery_tokens = ? WHERE id = ?").run(s,t)})()}getSessionSummariesByIds(e,t={}){if(e.length===0)return[];let{orderBy:s="date_desc",platformSource:n}=t,i=Ye(t.limit),o=w(t),a=s==="relevance",_=a?"":`ORDER BY ss.created_at_epoch ${s==="date_asc"?"ASC":"DESC"}`,E=i&&!a?"LIMIT ?":"",c=e.map(()=>"?").join(","),d=[...e],l=[];if(o.length>0){let m=x("ss",o,{includeMerged:!0});l.push(m.sql),d.push(...m.params)}n&&(l.push(`COALESCE(NULLIF(s.platform_source, ''), '${p}') = ?`),d.push(b(n)));let O=l.length>0?`AND ${l.join(" AND ")}`:"";E&&d.push(i);let I=this.db.prepare(`
1163
+ `).run(e,t,n.request,n.investigated,n.learned,n.completed,n.next_steps,JSON.stringify(v),JSON.stringify(de),n.notes,i||null,r,u,d);D=Number(Q.lastInsertRowid)}return{observationIds:R,mergedIntoExisting:m,insertedObservationIds:A,summaryId:D,createdAtEpoch:d}})();return j({projects:[t]},"storeObservations"),C}updateDiscoveryTokens(e,t,s){e.length===0&&t===null||this.db.transaction(()=>{let n=this.db.prepare("UPDATE observations SET discovery_tokens = ? WHERE id = ?");for(let i of e)n.run(s,i);t!==null&&this.db.prepare("UPDATE session_summaries SET discovery_tokens = ? WHERE id = ?").run(s,t)})()}getSessionSummariesByIds(e,t={}){if(e.length===0)return[];let{orderBy:s="date_desc",platformSource:n}=t,i=Ze(t.limit),r=w(t),a=s==="relevance",_=s==="date_asc"?"ASC":"DESC",E=a?"":`ORDER BY ss.created_at_epoch ${_}, ss.id ${_}`,d=i&&!a?"LIMIT ?":"",u=e.map(()=>"?").join(","),l=[...e],p=[];if(r.length>0){let m=x("ss",r,{includeMerged:!0});p.push(m.sql),l.push(...m.params)}n&&(p.push(`COALESCE(NULLIF(s.platform_source, ''), '${T}') = ?`),l.push(b(n)));let S=p.length>0?`AND ${p.join(" AND ")}`:"";d&&l.push(i);let f=this.db.prepare(`
1159
1164
  SELECT ss.*
1160
1165
  FROM session_summaries ss
1161
1166
  LEFT JOIN sdk_sessions s ON s.memory_session_id = ss.memory_session_id
1162
- WHERE ss.id IN (${c}) ${O}
1163
- ${_}
1167
+ WHERE ss.id IN (${u}) ${S}
1164
1168
  ${E}
1165
- `).all(...d);if(!a)return I;let f=new Map(I.map(m=>[m.id,m])),g=e.map(m=>f.get(m)).filter(m=>!!m);return i?g.slice(0,i):g}getUserPromptsByIds(e,t={}){if(e.length===0)return[];let{orderBy:s="date_desc",platformSource:n}=t,i=Ye(t.limit),o=w(t),a=s==="relevance",_=a?"":`ORDER BY up.created_at_epoch ${s==="date_asc"?"ASC":"DESC"}`,E=i&&!a?"LIMIT ?":"",c=e.map(()=>"?").join(","),d=[...e],l=[];if(o.length>0){let m=x("s",o,{includeMerged:!1});l.push(m.sql),d.push(...m.params)}n&&(l.push(`COALESCE(NULLIF(s.platform_source, ''), '${p}') = ?`),d.push(b(n)));let O=l.length>0?`AND ${l.join(" AND ")}`:"";E&&d.push(i);let I=this.db.prepare(`
1169
+ ${d}
1170
+ `).all(...l);if(!a)return f;let C=new Map(f.map(m=>[m.id,m])),R=e.map(m=>C.get(m)).filter(m=>!!m);return i?R.slice(0,i):R}getUserPromptsByIds(e,t={}){if(e.length===0)return[];let{orderBy:s="date_desc",platformSource:n}=t,i=Ze(t.limit),r=w(t),a=s==="relevance",_=s==="date_asc"?"ASC":"DESC",E=a?"":`ORDER BY up.created_at_epoch ${_}, up.id ${_}`,d=i&&!a?"LIMIT ?":"",u=e.map(()=>"?").join(","),l=[...e],p=[];if(r.length>0){let m=x("s",r,{includeMerged:!1});p.push(m.sql),l.push(...m.params)}n&&(p.push(`COALESCE(NULLIF(s.platform_source, ''), '${T}') = ?`),l.push(b(n)));let S=p.length>0?`AND ${p.join(" AND ")}`:"";d&&l.push(i);let f=this.db.prepare(`
1166
1171
  SELECT
1167
1172
  up.*,
1168
1173
  s.project,
1169
1174
  s.memory_session_id,
1170
- COALESCE(NULLIF(s.platform_source, ''), '${p}') as platform_source
1175
+ COALESCE(NULLIF(s.platform_source, ''), '${T}') as platform_source
1171
1176
  FROM user_prompts up
1172
1177
  JOIN sdk_sessions s ON up.session_db_id = s.id
1173
- WHERE up.id IN (${c}) ${O}
1174
- ${_}
1178
+ WHERE up.id IN (${u}) ${S}
1175
1179
  ${E}
1176
- `).all(...d);if(!a)return I;let f=new Map(I.map(m=>[m.id,m])),g=e.map(m=>f.get(m)).filter(m=>!!m);return i?g.slice(0,i):g}getTimelineAroundTimestamp(e,t=10,s=10,n,i){return this.getTimelineAroundObservation(null,e,t,s,n,i)}getTimelineAroundObservation(e,t,s=10,n=10,i,o){let a=o?b(o):void 0,_=(A,y,T=!1)=>{let S=[],D=[];return i&&(T?(S.push(`(${A}.project COLLATE NOCASE = ? OR ${A}.merged_into_project COLLATE NOCASE = ?)`),D.push(i,i)):(S.push(`${A}.project COLLATE NOCASE = ?`),D.push(i))),a&&(S.push(`COALESCE(NULLIF(${y}.platform_source, ''), '${p}') = ?`),D.push(a)),{clause:S.length>0?`AND ${S.join(" AND ")}`:"",params:D}},E=_("o","src",!0),c=_("ss","src",!0),d=_("s","s"),l,O;if(e!==null){let A=`
1180
+ ${d}
1181
+ `).all(...l);if(!a)return f;let C=new Map(f.map(m=>[m.id,m])),R=e.map(m=>C.get(m)).filter(m=>!!m);return i?R.slice(0,i):R}getTimelineAroundTimestamp(e,t=10,s=10,n,i){return this.getTimelineAroundObservation(null,e,t,s,n,i)}getTimelineAroundObservation(e,t,s=10,n=10,i,r){let a=r?b(r):void 0,_=(A,y,g=!1)=>{let D=[],O=[];return i&&(g?(D.push(`(${A}.project COLLATE NOCASE = ? OR ${A}.merged_into_project COLLATE NOCASE = ?)`),O.push(i,i)):(D.push(`${A}.project COLLATE NOCASE = ?`),O.push(i))),a&&(D.push(`COALESCE(NULLIF(${y}.platform_source, ''), '${T}') = ?`),O.push(a)),{clause:D.length>0?`AND ${D.join(" AND ")}`:"",params:O}},E=_("o","src",!0),d=_("ss","src",!0),u=_("s","s"),l,p;if(e!==null){let A=`
1177
1182
  SELECT o.id, o.created_at_epoch
1178
1183
  FROM observations o
1179
1184
  LEFT JOIN sdk_sessions src ON src.memory_session_id = o.memory_session_id
@@ -1187,7 +1192,7 @@ ${L.stack??""}
1187
1192
  WHERE (o.created_at_epoch, o.id) >= (?, ?) ${E.clause}
1188
1193
  ORDER BY o.created_at_epoch ASC
1189
1194
  LIMIT ?
1190
- `;try{let T=this.db.prepare(A).all(t,e,...E.params,s+1),S=this.db.prepare(y).all(t,e,...E.params,n+1);if(T.length===0&&S.length===0)return{observations:[],sessions:[],prompts:[]};l=T.length>0?T[T.length-1].created_at_epoch:t,O=S.length>0?S[S.length-1].created_at_epoch:t}catch(T){return T instanceof Error?u.error("DB","Error getting boundary observations",{project:i},T):u.error("DB","Error getting boundary observations with non-Error",{},new Error(String(T))),{observations:[],sessions:[],prompts:[]}}}else{let A=`
1195
+ `;try{let g=this.db.prepare(A).all(t,e,...E.params,s+1),D=this.db.prepare(y).all(t,e,...E.params,n+1);if(g.length===0&&D.length===0)return{observations:[],sessions:[],prompts:[]};l=g.length>0?g[g.length-1].created_at_epoch:t,p=D.length>0?D[D.length-1].created_at_epoch:t}catch(g){return g instanceof Error?c.error("DB","Error getting boundary observations",{project:i},g):c.error("DB","Error getting boundary observations with non-Error",{},new Error(String(g))),{observations:[],sessions:[],prompts:[]}}}else{let A=`
1191
1196
  SELECT o.created_at_epoch
1192
1197
  FROM observations o
1193
1198
  LEFT JOIN sdk_sessions src ON src.memory_session_id = o.memory_session_id
@@ -1201,58 +1206,58 @@ ${L.stack??""}
1201
1206
  WHERE o.created_at_epoch > ? ${E.clause}
1202
1207
  ORDER BY o.created_at_epoch ASC
1203
1208
  LIMIT ?
1204
- `;try{let T=this.db.prepare(A).all(t,...E.params,s),S=this.db.prepare(y).all(t,...E.params,n);l=T.length>0?T[T.length-1].created_at_epoch:t,O=S.length>0?S[S.length-1].created_at_epoch:t}catch(T){return T instanceof Error?u.error("DB","Error getting boundary timestamps",{project:i},T):u.error("DB","Error getting boundary timestamps with non-Error",{},new Error(String(T))),{observations:[],sessions:[],prompts:[]}}}let L=`
1209
+ `;try{let g=this.db.prepare(A).all(t,...E.params,s),D=this.db.prepare(y).all(t,...E.params,n);l=g.length>0?g[g.length-1].created_at_epoch:t,p=D.length>0?D[D.length-1].created_at_epoch:t}catch(g){return g instanceof Error?c.error("DB","Error getting boundary timestamps",{project:i},g):c.error("DB","Error getting boundary timestamps with non-Error",{},new Error(String(g))),{observations:[],sessions:[],prompts:[]}}}let S=`
1205
1210
  SELECT o.*
1206
1211
  FROM observations o
1207
1212
  LEFT JOIN sdk_sessions src ON src.memory_session_id = o.memory_session_id
1208
1213
  WHERE o.created_at_epoch >= ? AND o.created_at_epoch <= ? ${E.clause}
1209
1214
  ORDER BY o.created_at_epoch ASC, o.id ASC
1210
- `,I=`
1215
+ `,h=`
1211
1216
  SELECT ss.*
1212
1217
  FROM session_summaries ss
1213
1218
  LEFT JOIN sdk_sessions src ON src.memory_session_id = ss.memory_session_id
1214
- WHERE ss.created_at_epoch >= ? AND ss.created_at_epoch <= ? ${c.clause}
1219
+ WHERE ss.created_at_epoch >= ? AND ss.created_at_epoch <= ? ${d.clause}
1215
1220
  ORDER BY ss.created_at_epoch ASC, ss.id ASC
1216
1221
  `,f=`
1217
- SELECT up.*, s.project, s.memory_session_id, COALESCE(NULLIF(s.platform_source, ''), '${p}') as platform_source
1222
+ SELECT up.*, s.project, s.memory_session_id, COALESCE(NULLIF(s.platform_source, ''), '${T}') as platform_source
1218
1223
  FROM user_prompts up
1219
1224
  JOIN sdk_sessions s ON up.session_db_id = s.id
1220
- WHERE up.created_at_epoch >= ? AND up.created_at_epoch <= ? ${d.clause}
1225
+ WHERE up.created_at_epoch >= ? AND up.created_at_epoch <= ? ${u.clause}
1221
1226
  ORDER BY up.created_at_epoch ASC, up.id ASC
1222
- `,g=this.db.prepare(L).all(l,O,...E.params),m=this.db.prepare(I).all(l,O,...c.params),N=this.db.prepare(f).all(l,O,...d.params);return{observations:g,sessions:m.map(A=>({id:A.id,memory_session_id:A.memory_session_id,project:A.project,request:A.request,completed:A.completed,next_steps:A.next_steps,created_at:A.created_at,created_at_epoch:A.created_at_epoch})),prompts:N.map(A=>({id:A.id,content_session_id:A.content_session_id,prompt_number:A.prompt_number,prompt_text:A.prompt_text,project:A.project,platform_source:A.platform_source,created_at:A.created_at,created_at_epoch:A.created_at_epoch}))}}getOrCreateManualSession(e,t=p){let s=`manual-${e}`,n=`manual-content-${e}`;if(this.db.prepare("SELECT memory_session_id FROM sdk_sessions WHERE memory_session_id = ?").get(s))return t&&t!==p&&this.db.prepare("UPDATE sdk_sessions SET platform_source = ? WHERE memory_session_id = ?").run(t,s),s;let o=new Date;return this.db.prepare(`
1227
+ `,C=this.db.prepare(S).all(l,p,...E.params),R=this.db.prepare(h).all(l,p,...d.params),m=this.db.prepare(f).all(l,p,...u.params);return{observations:C,sessions:R.map(A=>({id:A.id,memory_session_id:A.memory_session_id,project:A.project,request:A.request,completed:A.completed,next_steps:A.next_steps,created_at:A.created_at,created_at_epoch:A.created_at_epoch})),prompts:m.map(A=>({id:A.id,content_session_id:A.content_session_id,prompt_number:A.prompt_number,prompt_text:A.prompt_text,project:A.project,platform_source:A.platform_source,created_at:A.created_at,created_at_epoch:A.created_at_epoch}))}}getOrCreateManualSession(e,t=T){let s=`manual-${e}`,n=`manual-content-${e}`;if(this.db.prepare("SELECT memory_session_id FROM sdk_sessions WHERE memory_session_id = ?").get(s))return t&&t!==T&&this.db.prepare("UPDATE sdk_sessions SET platform_source = ? WHERE memory_session_id = ?").run(t,s),s;let r=new Date;return this.db.prepare(`
1223
1228
  INSERT INTO sdk_sessions (memory_session_id, content_session_id, project, platform_source, started_at, started_at_epoch, status)
1224
1229
  VALUES (?, ?, ?, ?, ?, ?, 'active')
1225
- `).run(s,n,e,p,o.toISOString(),o.getTime()),u.info("SESSION","Created manual session",{memorySessionId:s,project:e}),s}close(){this.db.close()}cachedStatement(e){let t=this.statementCache.get(e);return t||(t=this.db.prepare(e),this.statementCache.set(e,t)),t}importSdkSession(e){let t=b(e.platform_source),s=this.db.prepare(`SELECT id FROM sdk_sessions
1230
+ `).run(s,n,e,T,r.toISOString(),r.getTime()),c.info("SESSION","Created manual session",{memorySessionId:s,project:e}),s}close(){this.db.close()}cachedStatement(e){let t=this.statementCache.get(e);return t||(t=this.db.prepare(e),this.statementCache.set(e,t)),t}importSdkSession(e){let t=b(e.platform_source),s=this.db.prepare(`SELECT id FROM sdk_sessions
1226
1231
  WHERE platform_source = ? AND content_session_id = ?`).get(t,e.content_session_id);if(s)return{imported:!1,id:s.id};let n=e.custom_title??null;if(n!==null&&typeof n!="string")throw new TypeError("Imported custom_title must be a string or null");let i=this.db.prepare(`
1227
1232
  INSERT INTO sdk_sessions (
1228
1233
  content_session_id, memory_session_id, project, platform_source, user_prompt, custom_title,
1229
1234
  started_at, started_at_epoch, completed_at, completed_at_epoch, status
1230
1235
  ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
1231
- `);return this.db.transaction(()=>({imported:!0,id:i.run(e.content_session_id,e.memory_session_id,e.project,t,e.user_prompt,n,e.started_at,e.started_at_epoch,e.completed_at,e.completed_at_epoch,e.status).lastInsertRowid}))()}importSessionSummary(e){if(typeof e?.memory_session_id!="string"||e.memory_session_id.trim()==="")return u.warn("DB","Skipping imported session summary without memory_session_id",{project:typeof e?.project=="string"?e.project:null}),{imported:!1,id:0};let t=this.db.prepare(`SELECT id FROM session_summaries WHERE memory_session_id = ?
1236
+ `);return this.db.transaction(()=>({imported:!0,id:i.run(e.content_session_id,e.memory_session_id,e.project,t,e.user_prompt,n,e.started_at,e.started_at_epoch,e.completed_at,e.completed_at_epoch,e.status).lastInsertRowid}))()}importSessionSummary(e){if(typeof e?.memory_session_id!="string"||e.memory_session_id.trim()==="")return c.warn("DB","Skipping imported session summary without memory_session_id",{project:typeof e?.project=="string"?e.project:null}),{imported:!1,id:0};let t=this.db.prepare(`SELECT id FROM session_summaries WHERE memory_session_id = ?
1232
1237
  AND request IS ? AND investigated IS ? AND learned IS ? AND completed IS ?
1233
1238
  AND next_steps IS ? AND files_read IS ? AND files_edited IS ? AND notes IS ?
1234
- AND prompt_number IS ? AND created_at_epoch = ?`).get(e.memory_session_id,R(e.request),R(e.investigated),R(e.learned),R(e.completed),R(e.next_steps),R(e.files_read),R(e.files_edited),R(e.notes),e.prompt_number??null,e.created_at_epoch);if(t)return{imported:!1,id:t.id};let n=this.db.prepare(`
1239
+ AND prompt_number IS ? AND created_at_epoch = ?`).get(e.memory_session_id,N(e.request),N(e.investigated),N(e.learned),N(e.completed),N(e.next_steps),N(e.files_read),N(e.files_edited),N(e.notes),e.prompt_number??null,e.created_at_epoch);if(t)return{imported:!1,id:t.id};let n=this.db.prepare(`
1235
1240
  INSERT INTO session_summaries (
1236
1241
  memory_session_id, project, request, investigated, learned,
1237
1242
  completed, next_steps, files_read, files_edited, notes,
1238
1243
  prompt_number, discovery_tokens, created_at, created_at_epoch
1239
1244
  ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
1240
- `).run(e.memory_session_id,e.project,R(e.request),R(e.investigated),R(e.learned),R(e.completed),R(e.next_steps),R(e.files_read),R(e.files_edited),R(e.notes),e.prompt_number,e.discovery_tokens||0,e.created_at,e.created_at_epoch);return $({projects:[e.project]},"importSessionSummary"),{imported:!0,id:n.lastInsertRowid}}importObservation(e){if(typeof e?.memory_session_id!="string"||e.memory_session_id.trim()==="")return u.warn("DB","Skipping imported observation without memory_session_id",{title:typeof e?.title=="string"?e.title:null,type:typeof e?.type=="string"?e.type:null}),{imported:!1,id:0};let t=this.db.prepare(`
1245
+ `).run(e.memory_session_id,e.project,N(e.request),N(e.investigated),N(e.learned),N(e.completed),N(e.next_steps),N(e.files_read),N(e.files_edited),N(e.notes),e.prompt_number,e.discovery_tokens||0,e.created_at,e.created_at_epoch);return j({projects:[e.project]},"importSessionSummary"),{imported:!0,id:n.lastInsertRowid}}importObservation(e){if(typeof e?.memory_session_id!="string"||e.memory_session_id.trim()==="")return c.warn("DB","Skipping imported observation without memory_session_id",{title:typeof e?.title=="string"?e.title:null,type:typeof e?.type=="string"?e.type:null}),{imported:!1,id:0};let t=this.db.prepare(`
1241
1246
  SELECT id FROM observations
1242
1247
  WHERE memory_session_id = ? AND text IS ? AND type = ?
1243
1248
  AND title IS ? AND subtitle IS ? AND facts IS ? AND narrative IS ?
1244
1249
  AND concepts IS ? AND files_read IS ? AND files_modified IS ?
1245
1250
  AND prompt_number IS ? AND agent_type IS ?
1246
1251
  AND agent_id IS ? AND created_at_epoch = ?
1247
- `).get(e.memory_session_id,R(e.text),e.type,R(e.title),R(e.subtitle),R(e.facts),R(e.narrative),R(e.concepts),R(e.files_read),R(e.files_modified),e.prompt_number??null,e.agent_type??null,e.agent_id??null,e.created_at_epoch);if(t)return{imported:!1,id:t.id};let n=this.db.prepare(`
1252
+ `).get(e.memory_session_id,N(e.text),e.type,N(e.title),N(e.subtitle),N(e.facts),N(e.narrative),N(e.concepts),N(e.files_read),N(e.files_modified),e.prompt_number??null,e.agent_type??null,e.agent_id??null,e.created_at_epoch);if(t)return{imported:!1,id:t.id};let n=this.db.prepare(`
1248
1253
  INSERT INTO observations (
1249
1254
  memory_session_id, project, text, type, title, subtitle,
1250
1255
  facts, narrative, concepts, files_read, files_modified,
1251
1256
  prompt_number, discovery_tokens, agent_type, agent_id,
1252
1257
  created_at, created_at_epoch
1253
1258
  ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
1254
- `).run(e.memory_session_id,e.project,R(e.text),e.type,R(e.title),R(e.subtitle),R(e.facts),R(e.narrative),R(e.concepts),R(e.files_read),R(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);return $({projects:[e.project]},"importObservation"),{imported:!0,id:n.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?b(e.platform_source):void 0;if(typeof e.session_db_id=="number"){let a=this.db.prepare(`
1255
- SELECT id, content_session_id, COALESCE(NULLIF(platform_source, ''), '${p}') as platform_source
1259
+ `).run(e.memory_session_id,e.project,N(e.text),e.type,N(e.title),N(e.subtitle),N(e.facts),N(e.narrative),N(e.concepts),N(e.files_read),N(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);return j({projects:[e.project]},"importObservation"),{imported:!0,id:n.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?b(e.platform_source):void 0;if(typeof e.session_db_id=="number"){let a=this.db.prepare(`
1260
+ SELECT id, content_session_id, COALESCE(NULLIF(platform_source, ''), '${T}') as platform_source
1256
1261
  FROM sdk_sessions
1257
1262
  WHERE id = ?
1258
1263
  LIMIT 1
@@ -1264,5 +1269,5 @@ ${L.stack??""}
1264
1269
  session_db_id, content_session_id, prompt_number, prompt_text,
1265
1270
  created_at, created_at_epoch
1266
1271
  ) VALUES (?, ?, ?, ?, ?, ?)
1267
- `).run(t,e.content_session_id,e.prompt_number,R(e.prompt_text),e.created_at,e.created_at_epoch).lastInsertRowid}}};0&&(module.exports={SessionStore,TELEGRAM_WRAPUP_CLAIM_STALE_AFTER_MS,rollupObservationFileLists});
1272
+ `).run(t,e.content_session_id,e.prompt_number,N(e.prompt_text),e.created_at,e.created_at_epoch).lastInsertRowid}}};0&&(module.exports={SessionStore,TELEGRAM_WRAPUP_CLAIM_STALE_AFTER_MS,rollupObservationFileLists});
1268
1273
  //# sourceMappingURL=SessionStore.js.map