claude-mem 12.4.4 → 12.4.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/npx-cli/index.js +156 -153
- package/dist/opencode-plugin/index.js +2 -2
- package/package.json +1 -1
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/hooks/hooks.json +8 -8
- package/plugin/package.json +2 -1
- package/plugin/scripts/context-generator.cjs +79 -66
- package/plugin/scripts/mcp-server.cjs +36 -74
- package/plugin/scripts/smart-install.js +2 -57
- package/plugin/scripts/worker-service.cjs +211 -191
- package/plugin/skills/timeline-report/SKILL.md +15 -7
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
"use strict";var yt=Object.create;var P=Object.defineProperty;var Mt=Object.getOwnPropertyDescriptor;var Dt=Object.getOwnPropertyNames;var vt=Object.getPrototypeOf,Ut=Object.prototype.hasOwnProperty;var xt=(r,e)=>{for(var t in e)P(r,t,{get:e[t],enumerable:!0})},be=(r,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of Dt(e))!Ut.call(r,n)&&n!==t&&P(r,n,{get:()=>e[n],enumerable:!(s=Mt(e,n))||s.enumerable});return r};var L=(r,e,t)=>(t=r!=null?yt(vt(r)):{},be(e||!r||!r.__esModule?P(t,"default",{value:r,enumerable:!0}):t,r)),kt=r=>be(P({},"__esModule",{value:!0}),r);var os={};xt(os,{generateContext:()=>Te});module.exports=kt(os);var Ct=L(require("path"),1),It=require("os"),Lt=require("fs");var ne=require("bun:sqlite");var S=require("path"),ee=require("os"),
|
|
2
|
-
${e.stack}`:e.message;if(Array.isArray(e))return`[${e.length} items]`;let t=Object.keys(e);return t.length===0?"{}":t.length<=3?JSON.stringify(e):`{${t.length} keys: ${t.slice(0,3).join(", ")}...}`}return String(e)}formatTool(e,t){if(!t)return e;let s=t;if(typeof t=="string")try{s=JSON.parse(t)}catch{s=t}if(e==="Bash"&&s.command)return`${e}(${s.command})`;if(s.file_path)return`${e}(${s.file_path})`;if(s.notebook_path)return`${e}(${s.notebook_path})`;if(e==="Glob"&&s.pattern)return`${e}(${s.pattern})`;if(e==="Grep"&&s.pattern)return`${e}(${s.pattern})`;if(s.url)return`${e}(${s.url})`;if(s.query)return`${e}(${s.query})`;if(e==="Task"){if(s.subagent_type)return`${e}(${s.subagent_type})`;if(s.description)return`${e}(${s.description})`}return e==="Skill"&&s.skill?`${e}(${s.skill})`:e==="LSP"&&s.operation?`${e}(${s.operation})`:e}formatTimestamp(e){let t=e.getFullYear(),s=String(e.getMonth()+1).padStart(2,"0"),n=String(e.getDate()).padStart(2,"0"),o=String(e.getHours()).padStart(2,"0"),i=String(e.getMinutes()).padStart(2,"0"),a=String(e.getSeconds()).padStart(2,"0"),d=String(e.getMilliseconds()).padStart(3,"0");return`${t}-${s}-${n} ${o}:${i}:${a}.${d}`}log(e,t,s,n,o){if(e<this.getLevel())return;this.ensureLogFileInitialized();let i=this.formatTimestamp(new Date),a=z[e].padEnd(5),d=t.padEnd(6),m="";n?.correlationId?m=`[${n.correlationId}] `:n?.sessionId&&(m=`[session-${n.sessionId}] `);let
|
|
1
|
+
"use strict";var yt=Object.create;var P=Object.defineProperty;var Mt=Object.getOwnPropertyDescriptor;var Dt=Object.getOwnPropertyNames;var vt=Object.getPrototypeOf,Ut=Object.prototype.hasOwnProperty;var xt=(r,e)=>{for(var t in e)P(r,t,{get:e[t],enumerable:!0})},be=(r,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of Dt(e))!Ut.call(r,n)&&n!==t&&P(r,n,{get:()=>e[n],enumerable:!(s=Mt(e,n))||s.enumerable});return r};var L=(r,e,t)=>(t=r!=null?yt(vt(r)):{},be(e||!r||!r.__esModule?P(t,"default",{value:r,enumerable:!0}):t,r)),kt=r=>be(P({},"__esModule",{value:!0}),r);var os={};xt(os,{generateContext:()=>Te});module.exports=kt(os);var Ct=L(require("path"),1),It=require("os"),Lt=require("fs");var ne=require("bun:sqlite");var S=require("path"),ee=require("os"),G=require("fs");var Ae=require("url");var I=require("fs"),v=require("path"),Oe=require("os"),z=(o=>(o[o.DEBUG=0]="DEBUG",o[o.INFO=1]="INFO",o[o.WARN=2]="WARN",o[o.ERROR=3]="ERROR",o[o.SILENT=4]="SILENT",o))(z||{}),he=(0,v.join)((0,Oe.homedir)(),".claude-mem"),Z=class{level=null;useColor;logFilePath=null;logFileInitialized=!1;constructor(){this.useColor=process.stdout.isTTY??!1}ensureLogFileInitialized(){if(!this.logFileInitialized){this.logFileInitialized=!0;try{let e=(0,v.join)(he,"logs");(0,I.existsSync)(e)||(0,I.mkdirSync)(e,{recursive:!0});let t=new Date().toISOString().split("T")[0];this.logFilePath=(0,v.join)(e,`claude-mem-${t}.log`)}catch(e){console.error("[LOGGER] Failed to initialize log file:",e instanceof Error?e.message:String(e)),this.logFilePath=null}}}getLevel(){if(this.level===null)try{let e=(0,v.join)(he,"settings.json");if((0,I.existsSync)(e)){let t=(0,I.readFileSync)(e,"utf-8"),n=(JSON.parse(t).CLAUDE_MEM_LOG_LEVEL||"INFO").toUpperCase();this.level=z[n]??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}correlationId(e,t){return`obs-${e}-${t}`}sessionId(e){return`session-${e}`}formatData(e){if(e==null)return"";if(typeof e=="string")return e;if(typeof e=="number"||typeof e=="boolean")return e.toString();if(typeof e=="object"){if(e instanceof Error)return this.getLevel()===0?`${e.message}
|
|
2
|
+
${e.stack}`:e.message;if(Array.isArray(e))return`[${e.length} items]`;let t=Object.keys(e);return t.length===0?"{}":t.length<=3?JSON.stringify(e):`{${t.length} keys: ${t.slice(0,3).join(", ")}...}`}return String(e)}formatTool(e,t){if(!t)return e;let s=t;if(typeof t=="string")try{s=JSON.parse(t)}catch{s=t}if(e==="Bash"&&s.command)return`${e}(${s.command})`;if(s.file_path)return`${e}(${s.file_path})`;if(s.notebook_path)return`${e}(${s.notebook_path})`;if(e==="Glob"&&s.pattern)return`${e}(${s.pattern})`;if(e==="Grep"&&s.pattern)return`${e}(${s.pattern})`;if(s.url)return`${e}(${s.url})`;if(s.query)return`${e}(${s.query})`;if(e==="Task"){if(s.subagent_type)return`${e}(${s.subagent_type})`;if(s.description)return`${e}(${s.description})`}return e==="Skill"&&s.skill?`${e}(${s.skill})`:e==="LSP"&&s.operation?`${e}(${s.operation})`:e}formatTimestamp(e){let t=e.getFullYear(),s=String(e.getMonth()+1).padStart(2,"0"),n=String(e.getDate()).padStart(2,"0"),o=String(e.getHours()).padStart(2,"0"),i=String(e.getMinutes()).padStart(2,"0"),a=String(e.getSeconds()).padStart(2,"0"),d=String(e.getMilliseconds()).padStart(3,"0");return`${t}-${s}-${n} ${o}:${i}:${a}.${d}`}log(e,t,s,n,o){if(e<this.getLevel())return;this.ensureLogFileInitialized();let i=this.formatTimestamp(new Date),a=z[e].padEnd(5),d=t.padEnd(6),m="";n?.correlationId?m=`[${n.correlationId}] `:n?.sessionId&&(m=`[session-${n.sessionId}] `);let c="";o!=null&&(o instanceof Error?c=this.getLevel()===0?`
|
|
3
3
|
${o.message}
|
|
4
|
-
${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?
|
|
5
|
-
`+JSON.stringify(o,null,2):
|
|
4
|
+
${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?c=`
|
|
5
|
+
`+JSON.stringify(o,null,2):c=" "+this.formatData(o));let E="";if(n){let{sessionId:g,memorySessionId:b,correlationId:N,...l}=n;Object.keys(l).length>0&&(E=` {${Object.entries(l).map(([f,T])=>`${f}=${T}`).join(", ")}}`)}let p=`[${i}] [${a}] [${d}] ${m}${s}${E}${c}`;if(this.logFilePath)try{(0,I.appendFileSync)(this.logFilePath,p+`
|
|
6
6
|
`,"utf8")}catch(g){process.stderr.write(`[LOGGER] Failed to write to log file: ${g instanceof Error?g.message:String(g)}
|
|
7
7
|
`)}else process.stderr.write(p+`
|
|
8
8
|
`)}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)}error(e,t,s,n){this.log(3,e,t,s,n)}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)}timing(e,t,s,n){this.info(e,`\u23F1 ${t}`,n,{duration:`${s}ms`})}happyPathError(e,t,s,n,o=""){let m=((new Error().stack||"").split(`
|
|
9
|
-
`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),
|
|
9
|
+
`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),c=m?`${m[1].split("/").pop()}:${m[2]}`:"unknown",E={...s,location:c};return this.warn(e,`[HAPPY-PATH] ${t}`,E,n),o}},u=new Z;var Gt={};function wt(){return typeof __dirname<"u"?__dirname:(0,S.dirname)((0,Ae.fileURLToPath)(Gt.url))}var Ft=wt();function $t(){if(process.env.CLAUDE_MEM_DATA_DIR)return process.env.CLAUDE_MEM_DATA_DIR;let r=(0,S.join)((0,ee.homedir)(),".claude-mem"),e=(0,S.join)(r,"settings.json");try{if((0,G.existsSync)(e)){let{readFileSync:t}=require("fs"),s=JSON.parse(t(e,"utf-8")),n=s.env??s;if(n.CLAUDE_MEM_DATA_DIR)return n.CLAUDE_MEM_DATA_DIR}}catch{}return r}var R=$t(),y=process.env.CLAUDE_CONFIG_DIR||(0,S.join)((0,ee.homedir)(),".claude"),us=(0,S.join)(y,"plugins","marketplaces","thedotmack"),ms=(0,S.join)(R,"archives"),cs=(0,S.join)(R,"logs"),ls=(0,S.join)(R,"trash"),ps=(0,S.join)(R,"backups"),Es=(0,S.join)(R,"modes"),gs=(0,S.join)(R,"settings.json"),Re=(0,S.join)(R,"claude-mem.db"),Ts=(0,S.join)(R,"vector-db"),Pt=(0,S.join)(R,"observer-sessions"),te=(0,S.basename)(Pt),fs=(0,S.join)(y,"settings.json"),Ss=(0,S.join)(y,"commands"),bs=(0,S.join)(y,"CLAUDE.md");function Ne(r){(0,G.mkdirSync)(r,{recursive:!0})}function Ce(){return(0,S.join)(Ft,"..")}var De=require("crypto");var Le=require("os"),ye=L(require("path"),1);var X=require("fs"),H=L(require("path"),1),U={isWorktree:!1,worktreeName:null,parentRepoPath:null,parentProjectName:null};function Ie(r){let e=H.default.join(r,".git"),t;try{t=(0,X.statSync)(e)}catch(c){return c instanceof Error&&c.code!=="ENOENT"&&console.warn("[worktree] Unexpected error checking .git:",c),U}if(!t.isFile())return U;let s;try{s=(0,X.readFileSync)(e,"utf-8").trim()}catch(c){return console.warn("[worktree] Failed to read .git file:",c instanceof Error?c.message:String(c)),U}let n=s.match(/^gitdir:\s*(.+)$/);if(!n)return U;let i=n[1].match(/^(.+)[/\\]\.git[/\\]worktrees[/\\]([^/\\]+)$/);if(!i)return U;let a=i[1],d=H.default.basename(r),m=H.default.basename(a);return{isWorktree:!0,worktreeName:d,parentRepoPath:a,parentProjectName:m}}function Me(r){return r==="~"||r.startsWith("~/")?r.replace(/^~/,(0,Le.homedir)()):r}function Ht(r){if(!r||r.trim()==="")return u.warn("PROJECT_NAME","Empty cwd provided, using fallback",{cwd:r}),"unknown-project";let e=Me(r),t=ye.default.basename(e);if(t===""){if(process.platform==="win32"){let n=r.match(/^([A-Z]):\\/i);if(n){let i=`drive-${n[1].toUpperCase()}`;return u.info("PROJECT_NAME","Drive root detected",{cwd:r,projectName:i}),i}}return u.warn("PROJECT_NAME","Root directory detected, using fallback",{cwd:r}),"unknown-project"}return t}function se(r){let e=Ht(r);if(!r)return{primary:e,parent:null,isWorktree:!1,allProjects:[e]};let t=Me(r),s=Ie(t);if(s.isWorktree&&s.parentProjectName){let n=`${s.parentProjectName}/${e}`;return{primary:n,parent:s.parentProjectName,isWorktree:!0,allProjects:[s.parentProjectName,n]}}return{primary:e,parent:null,isWorktree:!1,allProjects:[e]}}function j(r,e,t){return(0,De.createHash)("sha256").update([r||"",e||"",t||""].join("\0")).digest("hex").slice(0,16)}function re(r){if(!r)return[];try{let e=JSON.parse(r);return Array.isArray(e)?e:[String(e)]}catch{return[r]}}var O="claude";function Xt(r){return r.trim().toLowerCase().replace(/\s+/g,"-")}function M(r){if(!r)return O;let e=Xt(r);return e?e==="transcript"||e.includes("codex")?"codex":e.includes("cursor")?"cursor":e.includes("claude")?"claude":e:O}function ve(r){let e=["claude","codex","cursor"];return[...r].sort((t,s)=>{let n=e.indexOf(t),o=e.indexOf(s);return n!==-1||o!==-1?n===-1?1:o===-1?-1:n-o:t.localeCompare(s)})}function jt(r,e){return{customTitle:r,platformSource:e?M(e):void 0}}var B=class{db;constructor(e=Re){e instanceof ne.Database?this.db=e:(e!==":memory:"&&Ne(R),this.db=new ne.Database(e),this.db.run("PRAGMA journal_mode = WAL"),this.db.run("PRAGMA synchronous = NORMAL"),this.db.run("PRAGMA foreign_keys = ON"),this.db.run("PRAGMA journal_size_limit = 4194304")),this.initializeSchema(),this.ensureWorkerPortColumn(),this.ensurePromptTrackingColumns(),this.removeSessionSummariesUniqueConstraint(),this.addObservationHierarchicalFields(),this.makeObservationsTextNullable(),this.createUserPromptsTable(),this.ensureDiscoveryTokensColumn(),this.createPendingMessagesTable(),this.renameSessionIdColumns(),this.repairSessionIdColumnRename(),this.addFailedAtEpochColumn(),this.addOnUpdateCascadeToForeignKeys(),this.addObservationContentHashColumn(),this.addSessionCustomTitleColumn(),this.addSessionPlatformSourceColumn(),this.addObservationModelColumns(),this.ensureMergedIntoProjectColumns(),this.addObservationSubagentColumns(),this.addPendingMessagesToolUseIdAndWorkerPidColumns(),this.addObservationsUniqueContentHashIndex(),this.addObservationsMetadataColumn()}initializeSchema(){this.db.run(`
|
|
10
10
|
CREATE TABLE IF NOT EXISTS schema_versions (
|
|
11
11
|
id INTEGER PRIMARY KEY,
|
|
12
12
|
version INTEGER UNIQUE NOT NULL,
|
|
@@ -69,7 +69,7 @@ ${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?u=`
|
|
|
69
69
|
CREATE INDEX IF NOT EXISTS idx_session_summaries_sdk_session ON session_summaries(memory_session_id);
|
|
70
70
|
CREATE INDEX IF NOT EXISTS idx_session_summaries_project ON session_summaries(project);
|
|
71
71
|
CREATE INDEX IF NOT EXISTS idx_session_summaries_created ON session_summaries(created_at_epoch DESC);
|
|
72
|
-
`),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"),
|
|
72
|
+
`),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())}removeSessionSummariesUniqueConstraint(){if(!this.db.query("PRAGMA index_list(session_summaries)").all().some(s=>s.unique===1&&s.origin!=="pk")){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(7,new Date().toISOString());return}u.debug("DB","Removing UNIQUE constraint from session_summaries.memory_session_id"),this.db.run("BEGIN TRANSACTION"),this.db.run("DROP TABLE IF EXISTS session_summaries_new"),this.db.run(`
|
|
73
73
|
CREATE TABLE session_summaries_new (
|
|
74
74
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
75
75
|
memory_session_id TEXT NOT NULL,
|
|
@@ -97,7 +97,7 @@ ${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?u=`
|
|
|
97
97
|
CREATE INDEX idx_session_summaries_sdk_session ON session_summaries(memory_session_id);
|
|
98
98
|
CREATE INDEX idx_session_summaries_project ON session_summaries(project);
|
|
99
99
|
CREATE INDEX idx_session_summaries_created ON session_summaries(created_at_epoch DESC);
|
|
100
|
-
`),this.db.run("COMMIT"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(7,new Date().toISOString()),
|
|
100
|
+
`),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(`
|
|
101
101
|
ALTER TABLE observations ADD COLUMN title TEXT;
|
|
102
102
|
ALTER TABLE observations ADD COLUMN subtitle TEXT;
|
|
103
103
|
ALTER TABLE observations ADD COLUMN facts TEXT;
|
|
@@ -105,7 +105,7 @@ ${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?u=`
|
|
|
105
105
|
ALTER TABLE observations ADD COLUMN concepts TEXT;
|
|
106
106
|
ALTER TABLE observations ADD COLUMN files_read TEXT;
|
|
107
107
|
ALTER TABLE observations ADD COLUMN files_modified TEXT;
|
|
108
|
-
`),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(8,new Date().toISOString()),
|
|
108
|
+
`),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.db.run("DROP TABLE IF EXISTS observations_new"),this.db.run(`
|
|
109
109
|
CREATE TABLE observations_new (
|
|
110
110
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
111
111
|
memory_session_id TEXT NOT NULL,
|
|
@@ -135,7 +135,7 @@ ${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?u=`
|
|
|
135
135
|
CREATE INDEX idx_observations_project ON observations(project);
|
|
136
136
|
CREATE INDEX idx_observations_type ON observations(type);
|
|
137
137
|
CREATE INDEX idx_observations_created ON observations(created_at_epoch DESC);
|
|
138
|
-
`),this.db.run("COMMIT"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(9,new Date().toISOString()),
|
|
138
|
+
`),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 with FTS5 support"),this.db.run("BEGIN TRANSACTION"),this.db.run(`
|
|
139
139
|
CREATE TABLE user_prompts (
|
|
140
140
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
141
141
|
content_session_id TEXT NOT NULL,
|
|
@@ -173,7 +173,7 @@ ${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?u=`
|
|
|
173
173
|
INSERT INTO user_prompts_fts(rowid, prompt_text)
|
|
174
174
|
VALUES (new.id, new.prompt_text);
|
|
175
175
|
END;
|
|
176
|
-
`;try{this.db.run(s),this.db.run(n)}catch(o){o instanceof Error?
|
|
176
|
+
`;try{this.db.run(s),this.db.run(n)}catch(o){o instanceof Error?u.warn("DB","FTS5 not available \u2014 user_prompts_fts skipped (search uses ChromaDB)",{},o):u.warn("DB","FTS5 not available \u2014 user_prompts_fts skipped (search uses ChromaDB)",{},new Error(String(o))),this.db.run("COMMIT"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(10,new Date().toISOString()),u.debug("DB","Created user_prompts table (without FTS5)");return}this.db.run("COMMIT"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(10,new Date().toISOString()),u.debug("DB","Successfully created user_prompts table")}ensureDiscoveryTokensColumn(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(11))return;this.db.query("PRAGMA table_info(observations)").all().some(i=>i.name==="discovery_tokens")||(this.db.run("ALTER TABLE observations ADD COLUMN discovery_tokens INTEGER DEFAULT 0"),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(`
|
|
177
177
|
CREATE TABLE pending_messages (
|
|
178
178
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
179
179
|
session_db_id INTEGER NOT NULL,
|
|
@@ -192,7 +192,8 @@ ${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?u=`
|
|
|
192
192
|
completed_at_epoch INTEGER,
|
|
193
193
|
FOREIGN KEY (session_db_id) REFERENCES sdk_sessions(id) ON DELETE CASCADE
|
|
194
194
|
)
|
|
195
|
-
`),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()),
|
|
195
|
+
`),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,o,i)=>{let a=this.db.query(`PRAGMA table_info(${n})`).all(),d=a.some(c=>c.name===o);return a.some(c=>c.name===i)?!1:d?(this.db.run(`ALTER TABLE ${n} RENAME COLUMN ${o} TO ${i}`),u.debug("DB",`Renamed ${n}.${o} to ${i}`),!0):(u.warn("DB",`Column ${o} 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)")}repairSessionIdColumnRename(){this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(19)||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(19,new Date().toISOString())}addFailedAtEpochColumn(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(20))return;this.db.query("PRAGMA table_info(pending_messages)").all().some(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(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(21))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"),this.db.run("DROP TRIGGER IF EXISTS observations_ai"),this.db.run("DROP TRIGGER IF EXISTS observations_ad"),this.db.run("DROP TRIGGER IF EXISTS observations_au"),this.db.run("DROP TABLE IF EXISTS observations_new");let s=this.db.query("PRAGMA table_info(observations)").all().some(b=>b.name==="metadata"),n=s?`,
|
|
196
|
+
metadata TEXT`:"",o=s?", metadata":"",i=`
|
|
196
197
|
CREATE TABLE observations_new (
|
|
197
198
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
198
199
|
memory_session_id TEXT NOT NULL,
|
|
@@ -209,21 +210,21 @@ ${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?u=`
|
|
|
209
210
|
prompt_number INTEGER,
|
|
210
211
|
discovery_tokens INTEGER DEFAULT 0,
|
|
211
212
|
created_at TEXT NOT NULL,
|
|
212
|
-
created_at_epoch INTEGER NOT NULL,
|
|
213
|
+
created_at_epoch INTEGER NOT NULL${n},
|
|
213
214
|
FOREIGN KEY(memory_session_id) REFERENCES sdk_sessions(memory_session_id) ON DELETE CASCADE ON UPDATE CASCADE
|
|
214
215
|
)
|
|
215
|
-
`,
|
|
216
|
+
`,a=`
|
|
216
217
|
INSERT INTO observations_new
|
|
217
218
|
SELECT id, memory_session_id, project, text, type, title, subtitle, facts,
|
|
218
219
|
narrative, concepts, files_read, files_modified, prompt_number,
|
|
219
|
-
discovery_tokens, created_at, created_at_epoch
|
|
220
|
+
discovery_tokens, created_at, created_at_epoch${o}
|
|
220
221
|
FROM observations
|
|
221
|
-
`,
|
|
222
|
+
`,d=`
|
|
222
223
|
CREATE INDEX idx_observations_sdk_session ON observations(memory_session_id);
|
|
223
224
|
CREATE INDEX idx_observations_project ON observations(project);
|
|
224
225
|
CREATE INDEX idx_observations_type ON observations(type);
|
|
225
226
|
CREATE INDEX idx_observations_created ON observations(created_at_epoch DESC);
|
|
226
|
-
`,
|
|
227
|
+
`,m=`
|
|
227
228
|
CREATE TRIGGER IF NOT EXISTS observations_ai AFTER INSERT ON observations BEGIN
|
|
228
229
|
INSERT INTO observations_fts(rowid, title, subtitle, narrative, text, facts, concepts)
|
|
229
230
|
VALUES (new.id, new.title, new.subtitle, new.narrative, new.text, new.facts, new.concepts);
|
|
@@ -240,7 +241,7 @@ ${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?u=`
|
|
|
240
241
|
INSERT INTO observations_fts(rowid, title, subtitle, narrative, text, facts, concepts)
|
|
241
242
|
VALUES (new.id, new.title, new.subtitle, new.narrative, new.text, new.facts, new.concepts);
|
|
242
243
|
END;
|
|
243
|
-
`;this.db.run("DROP TRIGGER IF EXISTS session_summaries_ai"),this.db.run("DROP TRIGGER IF EXISTS session_summaries_ad"),this.db.run("DROP TRIGGER IF EXISTS session_summaries_au"),this.db.run("DROP TABLE IF EXISTS session_summaries_new");let
|
|
244
|
+
`;this.db.run("DROP TRIGGER IF EXISTS session_summaries_ai"),this.db.run("DROP TRIGGER IF EXISTS session_summaries_ad"),this.db.run("DROP TRIGGER IF EXISTS session_summaries_au"),this.db.run("DROP TABLE IF EXISTS session_summaries_new");let c=`
|
|
244
245
|
CREATE TABLE session_summaries_new (
|
|
245
246
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
246
247
|
memory_session_id TEXT NOT NULL,
|
|
@@ -259,17 +260,17 @@ ${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?u=`
|
|
|
259
260
|
created_at_epoch INTEGER NOT NULL,
|
|
260
261
|
FOREIGN KEY(memory_session_id) REFERENCES sdk_sessions(memory_session_id) ON DELETE CASCADE ON UPDATE CASCADE
|
|
261
262
|
)
|
|
262
|
-
`,
|
|
263
|
+
`,E=`
|
|
263
264
|
INSERT INTO session_summaries_new
|
|
264
265
|
SELECT id, memory_session_id, project, request, investigated, learned,
|
|
265
266
|
completed, next_steps, files_read, files_edited, notes,
|
|
266
267
|
prompt_number, discovery_tokens, created_at, created_at_epoch
|
|
267
268
|
FROM session_summaries
|
|
268
|
-
`,
|
|
269
|
+
`,p=`
|
|
269
270
|
CREATE INDEX idx_session_summaries_sdk_session ON session_summaries(memory_session_id);
|
|
270
271
|
CREATE INDEX idx_session_summaries_project ON session_summaries(project);
|
|
271
272
|
CREATE INDEX idx_session_summaries_created ON session_summaries(created_at_epoch DESC);
|
|
272
|
-
`,
|
|
273
|
+
`,g=`
|
|
273
274
|
CREATE TRIGGER IF NOT EXISTS session_summaries_ai AFTER INSERT ON session_summaries BEGIN
|
|
274
275
|
INSERT INTO session_summaries_fts(rowid, request, investigated, learned, completed, next_steps, notes)
|
|
275
276
|
VALUES (new.id, new.request, new.investigated, new.learned, new.completed, new.next_steps, new.notes);
|
|
@@ -286,11 +287,23 @@ ${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?u=`
|
|
|
286
287
|
INSERT INTO session_summaries_fts(rowid, request, investigated, learned, completed, next_steps, notes)
|
|
287
288
|
VALUES (new.id, new.request, new.investigated, new.learned, new.completed, new.next_steps, new.notes);
|
|
288
289
|
END;
|
|
289
|
-
`;try{this.recreateObservationsWithCascade(
|
|
290
|
+
`;try{this.recreateObservationsWithCascade(i,a,d,m),this.recreateSessionSummariesWithCascade(c,E,p,g),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(21,new Date().toISOString()),this.db.run("COMMIT"),this.db.run("PRAGMA foreign_keys = ON"),u.debug("DB","Successfully added ON UPDATE CASCADE to FK constraints")}catch(b){throw this.db.run("ROLLBACK"),this.db.run("PRAGMA foreign_keys = ON"),b instanceof Error?b:new Error(String(b))}}recreateObservationsWithCascade(e,t,s,n){this.db.run(e),this.db.run(t),this.db.run("DROP TABLE observations"),this.db.run("ALTER TABLE observations_new RENAME TO observations"),this.db.run(s),this.db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='observations_fts'").all().length>0&&this.db.run(n)}recreateSessionSummariesWithCascade(e,t,s,n){this.db.run(e),this.db.run(t),this.db.run("DROP TABLE session_summaries"),this.db.run("ALTER TABLE session_summaries_new RENAME TO session_summaries"),this.db.run(s),this.db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='session_summaries_fts'").all().length>0&&this.db.run(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(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(23))return;this.db.query("PRAGMA table_info(sdk_sessions)").all().some(n=>n.name==="custom_title")||(this.db.run("ALTER TABLE sdk_sessions ADD COLUMN custom_title TEXT"),u.debug("DB","Added custom_title column to sdk_sessions table")),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(23,new Date().toISOString())}addSessionPlatformSourceColumn(){let t=this.db.query("PRAGMA table_info(sdk_sessions)").all().some(i=>i.name==="platform_source"),n=this.db.query("PRAGMA index_list(sdk_sessions)").all().some(i=>i.name==="idx_sdk_sessions_platform_source");this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(24)&&t&&n||(t||(this.db.run(`ALTER TABLE sdk_sessions ADD COLUMN platform_source TEXT NOT NULL DEFAULT '${O}'`),u.debug("DB","Added platform_source column to sdk_sessions table")),this.db.run(`
|
|
290
291
|
UPDATE sdk_sessions
|
|
291
|
-
SET platform_source = '${
|
|
292
|
+
SET platform_source = '${O}'
|
|
292
293
|
WHERE platform_source IS NULL OR platform_source = ''
|
|
293
|
-
`),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()))}ensureMergedIntoProjectColumns(){this.db.query("PRAGMA table_info(observations)").all().some(s=>s.name==="merged_into_project")||this.db.run("ALTER TABLE observations ADD COLUMN merged_into_project TEXT"),this.db.run("CREATE INDEX IF NOT EXISTS idx_observations_merged_into ON observations(merged_into_project)"),this.db.query("PRAGMA table_info(session_summaries)").all().some(s=>s.name==="merged_into_project")||this.db.run("ALTER TABLE session_summaries ADD COLUMN merged_into_project TEXT"),this.db.run("CREATE INDEX IF NOT EXISTS idx_summaries_merged_into ON session_summaries(merged_into_project)")}addObservationSubagentColumns(){let e=this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(27),t=this.db.query("PRAGMA table_info(observations)").all(),s=t.some(i=>i.name==="agent_type"),n=t.some(i=>i.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 o=this.db.query("PRAGMA table_info(pending_messages)").all();if(o.length>0){let i=o.some(d=>d.name==="agent_type"),a=o.some(d=>d.name==="agent_id");i||this.db.run("ALTER TABLE pending_messages ADD COLUMN agent_type TEXT"),a||this.db.run("ALTER TABLE pending_messages ADD COLUMN agent_id TEXT")}e||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(27,new Date().toISOString())}
|
|
294
|
+
`),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()))}ensureMergedIntoProjectColumns(){this.db.query("PRAGMA table_info(observations)").all().some(s=>s.name==="merged_into_project")||this.db.run("ALTER TABLE observations ADD COLUMN merged_into_project TEXT"),this.db.run("CREATE INDEX IF NOT EXISTS idx_observations_merged_into ON observations(merged_into_project)"),this.db.query("PRAGMA table_info(session_summaries)").all().some(s=>s.name==="merged_into_project")||this.db.run("ALTER TABLE session_summaries ADD COLUMN merged_into_project TEXT"),this.db.run("CREATE INDEX IF NOT EXISTS idx_summaries_merged_into ON session_summaries(merged_into_project)")}addObservationSubagentColumns(){let e=this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(27),t=this.db.query("PRAGMA table_info(observations)").all(),s=t.some(i=>i.name==="agent_type"),n=t.some(i=>i.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 o=this.db.query("PRAGMA table_info(pending_messages)").all();if(o.length>0){let i=o.some(d=>d.name==="agent_type"),a=o.some(d=>d.name==="agent_id");i||this.db.run("ALTER TABLE pending_messages ADD COLUMN agent_type TEXT"),a||this.db.run("ALTER TABLE pending_messages ADD COLUMN agent_id TEXT")}e||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(27,new Date().toISOString())}addPendingMessagesToolUseIdAndWorkerPidColumns(){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}let t=this.db.query("PRAGMA table_info(pending_messages)").all(),s=t.some(o=>o.name==="tool_use_id"),n=t.some(o=>o.name==="worker_pid");s||this.db.run("ALTER TABLE pending_messages ADD COLUMN tool_use_id TEXT"),n||this.db.run("ALTER TABLE pending_messages ADD COLUMN worker_pid INTEGER"),this.db.run("BEGIN TRANSACTION");try{this.db.run("CREATE INDEX IF NOT EXISTS idx_pending_messages_worker_pid ON pending_messages(worker_pid)"),this.db.run(`
|
|
295
|
+
DELETE FROM pending_messages
|
|
296
|
+
WHERE tool_use_id IS NOT NULL
|
|
297
|
+
AND id NOT IN (
|
|
298
|
+
SELECT MIN(id) FROM pending_messages
|
|
299
|
+
WHERE tool_use_id IS NOT NULL
|
|
300
|
+
GROUP BY content_session_id, tool_use_id
|
|
301
|
+
)
|
|
302
|
+
`),this.db.run(`
|
|
303
|
+
CREATE UNIQUE INDEX IF NOT EXISTS ux_pending_session_tool
|
|
304
|
+
ON pending_messages(content_session_id, tool_use_id)
|
|
305
|
+
WHERE tool_use_id IS NOT NULL
|
|
306
|
+
`),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(28,new Date().toISOString()),this.db.run("COMMIT")}catch(o){throw this.db.run("ROLLBACK"),o}}addObservationsUniqueContentHashIndex(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(29))return;let t=this.db.query("PRAGMA table_info(observations)").all(),s=t.some(o=>o.name==="memory_session_id"),n=t.some(o=>o.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.db.run(`
|
|
294
307
|
DELETE FROM observations
|
|
295
308
|
WHERE id NOT IN (
|
|
296
309
|
SELECT MIN(id) FROM observations
|
|
@@ -299,7 +312,7 @@ ${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?u=`
|
|
|
299
312
|
`),this.db.run(`
|
|
300
313
|
CREATE UNIQUE INDEX IF NOT EXISTS ux_observations_session_hash
|
|
301
314
|
ON observations(memory_session_id, content_hash)
|
|
302
|
-
`),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(29,new Date().toISOString()),this.db.run("COMMIT")}catch(o){throw this.db.run("ROLLBACK"),o}}updateMemorySessionId(e,t){this.db.prepare(`
|
|
315
|
+
`),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(29,new Date().toISOString()),this.db.run("COMMIT")}catch(o){throw this.db.run("ROLLBACK"),o}}addObservationsMetadataColumn(){this.db.query("PRAGMA table_info(observations)").all().some(s=>s.name==="metadata")||(this.db.run("ALTER TABLE observations ADD COLUMN metadata TEXT"),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){this.db.prepare(`
|
|
303
316
|
UPDATE sdk_sessions
|
|
304
317
|
SET memory_session_id = ?
|
|
305
318
|
WHERE id = ?
|
|
@@ -311,7 +324,7 @@ ${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?u=`
|
|
|
311
324
|
SELECT id, memory_session_id FROM sdk_sessions WHERE id = ?
|
|
312
325
|
`).get(e);if(!s)throw new Error(`Session ${e} not found in sdk_sessions`);s.memory_session_id!==t&&(this.db.prepare(`
|
|
313
326
|
UPDATE sdk_sessions SET memory_session_id = ? WHERE id = ?
|
|
314
|
-
`).run(t,e),
|
|
327
|
+
`).run(t,e),u.info("DB","Registered memory_session_id before storage (FK fix)",{sessionDbId:e,oldId:s.memory_session_id,newId:t}))}getRecentSummaries(e,t=10){return this.db.prepare(`
|
|
315
328
|
SELECT
|
|
316
329
|
request, investigated, learned, completed, next_steps,
|
|
317
330
|
files_read, files_edited, notes, prompt_number, created_at
|
|
@@ -341,7 +354,7 @@ ${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?u=`
|
|
|
341
354
|
o.subtitle,
|
|
342
355
|
o.text,
|
|
343
356
|
o.project,
|
|
344
|
-
COALESCE(s.platform_source, '${
|
|
357
|
+
COALESCE(s.platform_source, '${O}') as platform_source,
|
|
345
358
|
o.prompt_number,
|
|
346
359
|
o.created_at,
|
|
347
360
|
o.created_at_epoch
|
|
@@ -361,7 +374,7 @@ ${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?u=`
|
|
|
361
374
|
ss.files_edited,
|
|
362
375
|
ss.notes,
|
|
363
376
|
ss.project,
|
|
364
|
-
COALESCE(s.platform_source, '${
|
|
377
|
+
COALESCE(s.platform_source, '${O}') as platform_source,
|
|
365
378
|
ss.prompt_number,
|
|
366
379
|
ss.created_at,
|
|
367
380
|
ss.created_at_epoch
|
|
@@ -374,7 +387,7 @@ ${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?u=`
|
|
|
374
387
|
up.id,
|
|
375
388
|
up.content_session_id,
|
|
376
389
|
s.project,
|
|
377
|
-
COALESCE(s.platform_source, '${
|
|
390
|
+
COALESCE(s.platform_source, '${O}') as platform_source,
|
|
378
391
|
up.prompt_number,
|
|
379
392
|
up.prompt_text,
|
|
380
393
|
up.created_at,
|
|
@@ -388,22 +401,22 @@ ${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?u=`
|
|
|
388
401
|
FROM sdk_sessions
|
|
389
402
|
WHERE project IS NOT NULL AND project != ''
|
|
390
403
|
AND project != ?
|
|
391
|
-
`,n=[te];return t&&(s+=" AND COALESCE(platform_source, ?) = ?",n.push(
|
|
404
|
+
`,n=[te];return t&&(s+=" AND COALESCE(platform_source, ?) = ?",n.push(O,t)),s+=" ORDER BY project ASC",this.db.prepare(s).all(...n).map(i=>i.project)}getProjectCatalog(){let e=this.db.prepare(`
|
|
392
405
|
SELECT
|
|
393
|
-
COALESCE(platform_source, '${
|
|
406
|
+
COALESCE(platform_source, '${O}') as platform_source,
|
|
394
407
|
project,
|
|
395
408
|
MAX(started_at_epoch) as latest_epoch
|
|
396
409
|
FROM sdk_sessions
|
|
397
410
|
WHERE project IS NOT NULL AND project != ''
|
|
398
411
|
AND project != ?
|
|
399
|
-
GROUP BY COALESCE(platform_source, '${
|
|
412
|
+
GROUP BY COALESCE(platform_source, '${O}'), project
|
|
400
413
|
ORDER BY latest_epoch DESC
|
|
401
414
|
`).all(te),t=[],s=new Set,n={};for(let i of e){let a=M(i.platform_source);n[a]||(n[a]=[]),n[a].includes(i.project)||n[a].push(i.project),s.has(i.project)||(s.add(i.project),t.push(i.project))}let o=ve(Object.keys(n));return{projects:t,sources:o,projectsBySource:Object.fromEntries(o.map(i=>[i,n[i]||[]]))}}getLatestUserPrompt(e){return this.db.prepare(`
|
|
402
415
|
SELECT
|
|
403
416
|
up.*,
|
|
404
417
|
s.memory_session_id,
|
|
405
418
|
s.project,
|
|
406
|
-
COALESCE(s.platform_source, '${
|
|
419
|
+
COALESCE(s.platform_source, '${O}') as platform_source
|
|
407
420
|
FROM user_prompts up
|
|
408
421
|
JOIN sdk_sessions s ON up.content_session_id = s.content_session_id
|
|
409
422
|
WHERE up.content_session_id = ?
|
|
@@ -435,12 +448,12 @@ ${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?u=`
|
|
|
435
448
|
SELECT *
|
|
436
449
|
FROM observations
|
|
437
450
|
WHERE id = ?
|
|
438
|
-
`).get(e)||null}getObservationsByIds(e,t={}){if(e.length===0)return[];let{orderBy:s="date_desc",limit:n,project:o,type:i,concepts:a,files:d}=t,m=s==="date_asc"?"ASC":"DESC",
|
|
451
|
+
`).get(e)||null}getObservationsByIds(e,t={}){if(e.length===0)return[];let{orderBy:s="date_desc",limit:n,project:o,type:i,concepts:a,files:d}=t,m=s==="date_asc"?"ASC":"DESC",c=n?`LIMIT ${n}`:"",E=e.map(()=>"?").join(","),p=[...e],g=[];if(o&&(g.push("project = ?"),p.push(o)),i)if(Array.isArray(i)){let l=i.map(()=>"?").join(",");g.push(`type IN (${l})`),p.push(...i)}else g.push("type = ?"),p.push(i);if(a){let l=Array.isArray(a)?a:[a],h=l.map(()=>"EXISTS (SELECT 1 FROM json_each(concepts) WHERE value = ?)");p.push(...l),g.push(`(${h.join(" OR ")})`)}if(d){let l=Array.isArray(d)?d:[d],h=l.map(()=>"(EXISTS (SELECT 1 FROM json_each(files_read) WHERE value LIKE ?) OR EXISTS (SELECT 1 FROM json_each(files_modified) WHERE value LIKE ?))");l.forEach(f=>{p.push(`%${f}%`,`%${f}%`)}),g.push(`(${h.join(" OR ")})`)}let b=g.length>0?`WHERE id IN (${E}) AND ${g.join(" AND ")}`:`WHERE id IN (${E})`;return this.db.prepare(`
|
|
439
452
|
SELECT *
|
|
440
453
|
FROM observations
|
|
441
|
-
${
|
|
454
|
+
${b}
|
|
442
455
|
ORDER BY created_at_epoch ${m}
|
|
443
|
-
${
|
|
456
|
+
${c}
|
|
444
457
|
`).all(...p)}getSummaryForSession(e){return this.db.prepare(`
|
|
445
458
|
SELECT
|
|
446
459
|
request, investigated, learned, completed, next_steps,
|
|
@@ -456,14 +469,14 @@ ${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?u=`
|
|
|
456
469
|
WHERE memory_session_id = ?
|
|
457
470
|
`).all(e),n=new Set,o=new Set;for(let i of s)re(i.files_read).forEach(a=>n.add(a)),re(i.files_modified).forEach(a=>o.add(a));return{filesRead:Array.from(n),filesModified:Array.from(o)}}getSessionById(e){return this.db.prepare(`
|
|
458
471
|
SELECT id, content_session_id, memory_session_id, project,
|
|
459
|
-
COALESCE(platform_source, '${
|
|
472
|
+
COALESCE(platform_source, '${O}') as platform_source,
|
|
460
473
|
user_prompt, custom_title, status
|
|
461
474
|
FROM sdk_sessions
|
|
462
475
|
WHERE id = ?
|
|
463
476
|
LIMIT 1
|
|
464
477
|
`).get(e)||null}getSdkSessionsBySessionIds(e){if(e.length===0)return[];let t=e.map(()=>"?").join(",");return this.db.prepare(`
|
|
465
478
|
SELECT id, content_session_id, memory_session_id, project,
|
|
466
|
-
COALESCE(platform_source, '${
|
|
479
|
+
COALESCE(platform_source, '${O}') as platform_source,
|
|
467
480
|
user_prompt, custom_title,
|
|
468
481
|
started_at, started_at_epoch, completed_at, completed_at_epoch, status
|
|
469
482
|
FROM sdk_sessions
|
|
@@ -471,19 +484,19 @@ ${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?u=`
|
|
|
471
484
|
ORDER BY started_at_epoch DESC
|
|
472
485
|
`).all(...e)}getPromptNumberFromUserPrompts(e){return this.db.prepare(`
|
|
473
486
|
SELECT COUNT(*) as count FROM user_prompts WHERE content_session_id = ?
|
|
474
|
-
`).get(e).count}createSDKSession(e,t,s,n,o){let i=new Date,a=i.getTime(),d=
|
|
487
|
+
`).get(e).count}createSDKSession(e,t,s,n,o){let i=new Date,a=i.getTime(),d=jt(n,o),m=d.platformSource??O,c=this.db.prepare(`
|
|
475
488
|
SELECT id, platform_source FROM sdk_sessions WHERE content_session_id = ?
|
|
476
|
-
`).get(e);if(
|
|
489
|
+
`).get(e);if(c){if(t&&this.db.prepare(`
|
|
477
490
|
UPDATE sdk_sessions SET project = ?
|
|
478
491
|
WHERE content_session_id = ? AND (project IS NULL OR project = '')
|
|
479
492
|
`).run(t,e),d.customTitle&&this.db.prepare(`
|
|
480
493
|
UPDATE sdk_sessions SET custom_title = ?
|
|
481
494
|
WHERE content_session_id = ? AND custom_title IS NULL
|
|
482
|
-
`).run(d.customTitle,e),d.platformSource){let p=
|
|
495
|
+
`).run(d.customTitle,e),d.platformSource){let p=c.platform_source?.trim()?M(c.platform_source):void 0;if(!p)this.db.prepare(`
|
|
483
496
|
UPDATE sdk_sessions SET platform_source = ?
|
|
484
497
|
WHERE content_session_id = ?
|
|
485
498
|
AND COALESCE(platform_source, '') = ''
|
|
486
|
-
`).run(d.platformSource,e);else if(p!==d.platformSource)throw new Error(`Platform source conflict for session ${e}: existing=${p}, received=${d.platformSource}`)}return
|
|
499
|
+
`).run(d.platformSource,e);else if(p!==d.platformSource)throw new Error(`Platform source conflict for session ${e}: existing=${p}, received=${d.platformSource}`)}return c.id}return this.db.prepare(`
|
|
487
500
|
INSERT INTO sdk_sessions
|
|
488
501
|
(content_session_id, memory_session_id, project, platform_source, user_prompt, custom_title, started_at, started_at_epoch, status)
|
|
489
502
|
VALUES (?, NULL, ?, ?, ?, ?, ?, ?, 'active')
|
|
@@ -496,20 +509,20 @@ ${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?u=`
|
|
|
496
509
|
FROM user_prompts
|
|
497
510
|
WHERE content_session_id = ? AND prompt_number = ?
|
|
498
511
|
LIMIT 1
|
|
499
|
-
`).get(e,t)?.prompt_text??null}storeObservation(e,t,s,n,o=0,i,a){let d=i??Date.now(),m=new Date(d).toISOString(),
|
|
512
|
+
`).get(e,t)?.prompt_text??null}storeObservation(e,t,s,n,o=0,i,a){let d=i??Date.now(),m=new Date(d).toISOString(),c=j(e,s.title,s.narrative),p=this.db.prepare(`
|
|
500
513
|
INSERT INTO observations
|
|
501
514
|
(memory_session_id, project, type, title, subtitle, facts, narrative, concepts,
|
|
502
515
|
files_read, files_modified, prompt_number, discovery_tokens, agent_type, agent_id, content_hash, created_at, created_at_epoch,
|
|
503
|
-
generated_by_model)
|
|
504
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
516
|
+
generated_by_model, metadata)
|
|
517
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
505
518
|
ON CONFLICT(memory_session_id, content_hash) DO NOTHING
|
|
506
519
|
RETURNING id, created_at_epoch
|
|
507
|
-
`).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),n||null,o,s.agent_type??null,s.agent_id??null,
|
|
520
|
+
`).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),n||null,o,s.agent_type??null,s.agent_id??null,c,m,d,a||null,s.metadata??null);if(p)return{id:p.id,createdAtEpoch:p.created_at_epoch};let g=this.db.prepare("SELECT id, created_at_epoch FROM observations WHERE memory_session_id = ? AND content_hash = ?").get(e,c);if(!g)throw new Error(`storeObservation: ON CONFLICT without existing row for content_hash=${c}`);return{id:g.id,createdAtEpoch:g.created_at_epoch}}storeSummary(e,t,s,n,o=0,i){let a=i??Date.now(),d=new Date(a).toISOString(),c=this.db.prepare(`
|
|
508
521
|
INSERT INTO session_summaries
|
|
509
522
|
(memory_session_id, project, request, investigated, learned, completed,
|
|
510
523
|
next_steps, notes, prompt_number, discovery_tokens, created_at, created_at_epoch)
|
|
511
524
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
512
|
-
`).run(e,t,s.request,s.investigated,s.learned,s.completed,s.next_steps,s.notes,n||null,o,d,a);return{id:Number(
|
|
525
|
+
`).run(e,t,s.request,s.investigated,s.learned,s.completed,s.next_steps,s.notes,n||null,o,d,a);return{id:Number(c.lastInsertRowid),createdAtEpoch:a}}storeObservations(e,t,s,n,o,i=0,a,d){let m=a??Date.now(),c=new Date(m).toISOString();return this.db.transaction(()=>{let p=[],g=this.db.prepare(`
|
|
513
526
|
INSERT INTO observations
|
|
514
527
|
(memory_session_id, project, type, title, subtitle, facts, narrative, concepts,
|
|
515
528
|
files_read, files_modified, prompt_number, discovery_tokens, agent_type, agent_id, content_hash, created_at, created_at_epoch,
|
|
@@ -517,12 +530,12 @@ ${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?u=`
|
|
|
517
530
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
518
531
|
ON CONFLICT(memory_session_id, content_hash) DO NOTHING
|
|
519
532
|
RETURNING id
|
|
520
|
-
`),
|
|
533
|
+
`),b=this.db.prepare("SELECT id FROM observations WHERE memory_session_id = ? AND content_hash = ?");for(let l of s){let h=j(e,l.title,l.narrative),f=g.get(e,t,l.type,l.title,l.subtitle,JSON.stringify(l.facts),l.narrative,JSON.stringify(l.concepts),JSON.stringify(l.files_read),JSON.stringify(l.files_modified),o||null,i,l.agent_type??null,l.agent_id??null,h,c,m,d||null);if(f){p.push(f.id);continue}let T=b.get(e,h);if(!T)throw new Error(`storeObservations: ON CONFLICT without existing row for content_hash=${h}`);p.push(T.id)}let N=null;if(n){let h=this.db.prepare(`
|
|
521
534
|
INSERT INTO session_summaries
|
|
522
535
|
(memory_session_id, project, request, investigated, learned, completed,
|
|
523
536
|
next_steps, notes, prompt_number, discovery_tokens, created_at, created_at_epoch)
|
|
524
537
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
525
|
-
`).run(e,t,n.request,n.investigated,n.learned,n.completed,n.next_steps,n.notes,o||null,i,
|
|
538
|
+
`).run(e,t,n.request,n.investigated,n.learned,n.completed,n.next_steps,n.notes,o||null,i,c,m);N=Number(h.lastInsertRowid)}return{observationIds:p,summaryId:N,createdAtEpoch:m}})()}storeObservationsAndMarkComplete(e,t,s,n,o,i,a,d=0,m,c){let E=m??Date.now(),p=new Date(E).toISOString();return this.db.transaction(()=>{let b=[],N=this.db.prepare(`
|
|
526
539
|
INSERT INTO observations
|
|
527
540
|
(memory_session_id, project, type, title, subtitle, facts, narrative, concepts,
|
|
528
541
|
files_read, files_modified, prompt_number, discovery_tokens, agent_type, agent_id, content_hash, created_at, created_at_epoch,
|
|
@@ -530,12 +543,12 @@ ${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?u=`
|
|
|
530
543
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
531
544
|
ON CONFLICT(memory_session_id, content_hash) DO NOTHING
|
|
532
545
|
RETURNING id
|
|
533
|
-
`),l=this.db.prepare("SELECT id FROM observations WHERE memory_session_id = ? AND content_hash = ?");for(let T of s){let D=
|
|
546
|
+
`),l=this.db.prepare("SELECT id FROM observations WHERE memory_session_id = ? AND content_hash = ?");for(let T of s){let D=j(e,T.title,T.narrative),fe=N.get(e,t,T.type,T.title,T.subtitle,JSON.stringify(T.facts),T.narrative,JSON.stringify(T.concepts),JSON.stringify(T.files_read),JSON.stringify(T.files_modified),a||null,d,T.agent_type??null,T.agent_id??null,D,p,E,c||null);if(fe){b.push(fe.id);continue}let Se=l.get(e,D);if(!Se)throw new Error(`storeObservationsAndMarkComplete: ON CONFLICT without existing row for content_hash=${D}`);b.push(Se.id)}let h;if(n){let D=this.db.prepare(`
|
|
534
547
|
INSERT INTO session_summaries
|
|
535
548
|
(memory_session_id, project, request, investigated, learned, completed,
|
|
536
549
|
next_steps, notes, prompt_number, discovery_tokens, created_at, created_at_epoch)
|
|
537
550
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
538
|
-
`).run(e,t,n.request,n.investigated,n.learned,n.completed,n.next_steps,n.notes,a||null,d,p,E);
|
|
551
|
+
`).run(e,t,n.request,n.investigated,n.learned,n.completed,n.next_steps,n.notes,a||null,d,p,E);h=Number(D.lastInsertRowid)}return this.db.prepare(`
|
|
539
552
|
UPDATE pending_messages
|
|
540
553
|
SET
|
|
541
554
|
status = 'processed',
|
|
@@ -543,19 +556,19 @@ ${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?u=`
|
|
|
543
556
|
tool_input = NULL,
|
|
544
557
|
tool_response = NULL
|
|
545
558
|
WHERE id = ? AND status = 'processing'
|
|
546
|
-
`).run(E,o),{observationIds:
|
|
559
|
+
`).run(E,o),{observationIds:b,summaryId:h,createdAtEpoch:E}})()}getSessionSummariesByIds(e,t={}){if(e.length===0)return[];let{orderBy:s="date_desc",limit:n,project:o}=t,i=s==="date_asc"?"ASC":"DESC",a=n?`LIMIT ${n}`:"",d=e.map(()=>"?").join(","),m=[...e],c=o?`WHERE id IN (${d}) AND project = ?`:`WHERE id IN (${d})`;return o&&m.push(o),this.db.prepare(`
|
|
547
560
|
SELECT * FROM session_summaries
|
|
548
|
-
${
|
|
561
|
+
${c}
|
|
549
562
|
ORDER BY created_at_epoch ${i}
|
|
550
563
|
${a}
|
|
551
|
-
`).all(...m)}getUserPromptsByIds(e,t={}){if(e.length===0)return[];let{orderBy:s="date_desc",limit:n,project:o}=t,i=s==="date_asc"?"ASC":"DESC",a=n?`LIMIT ${n}`:"",d=e.map(()=>"?").join(","),m=[...e],
|
|
564
|
+
`).all(...m)}getUserPromptsByIds(e,t={}){if(e.length===0)return[];let{orderBy:s="date_desc",limit:n,project:o}=t,i=s==="date_asc"?"ASC":"DESC",a=n?`LIMIT ${n}`:"",d=e.map(()=>"?").join(","),m=[...e],c=o?"AND s.project = ?":"";return o&&m.push(o),this.db.prepare(`
|
|
552
565
|
SELECT
|
|
553
566
|
up.*,
|
|
554
567
|
s.project,
|
|
555
568
|
s.memory_session_id
|
|
556
569
|
FROM user_prompts up
|
|
557
570
|
JOIN sdk_sessions s ON up.content_session_id = s.content_session_id
|
|
558
|
-
WHERE up.id IN (${d}) ${
|
|
571
|
+
WHERE up.id IN (${d}) ${c}
|
|
559
572
|
ORDER BY up.created_at_epoch ${i}
|
|
560
573
|
${a}
|
|
561
574
|
`).all(...m)}getTimelineAroundTimestamp(e,t=10,s=10,n){return this.getTimelineAroundObservation(null,e,t,s,n)}getTimelineAroundObservation(e,t,s=10,n=10,o){let i=o?"AND project = ?":"",a=o?[o]:[],d,m;if(e!==null){let l=`
|
|
@@ -564,25 +577,25 @@ ${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?u=`
|
|
|
564
577
|
WHERE id <= ? ${i}
|
|
565
578
|
ORDER BY id DESC
|
|
566
579
|
LIMIT ?
|
|
567
|
-
`,
|
|
580
|
+
`,h=`
|
|
568
581
|
SELECT id, created_at_epoch
|
|
569
582
|
FROM observations
|
|
570
583
|
WHERE id >= ? ${i}
|
|
571
584
|
ORDER BY id ASC
|
|
572
585
|
LIMIT ?
|
|
573
|
-
`;try{let f=this.db.prepare(l).all(e,...a,s+1),T=this.db.prepare(
|
|
586
|
+
`;try{let f=this.db.prepare(l).all(e,...a,s+1),T=this.db.prepare(h).all(e,...a,n+1);if(f.length===0&&T.length===0)return{observations:[],sessions:[],prompts:[]};d=f.length>0?f[f.length-1].created_at_epoch:t,m=T.length>0?T[T.length-1].created_at_epoch:t}catch(f){return f instanceof Error?u.error("DB","Error getting boundary observations",{project:o},f):u.error("DB","Error getting boundary observations with non-Error",{},new Error(String(f))),{observations:[],sessions:[],prompts:[]}}}else{let l=`
|
|
574
587
|
SELECT created_at_epoch
|
|
575
588
|
FROM observations
|
|
576
589
|
WHERE created_at_epoch <= ? ${i}
|
|
577
590
|
ORDER BY created_at_epoch DESC
|
|
578
591
|
LIMIT ?
|
|
579
|
-
`,
|
|
592
|
+
`,h=`
|
|
580
593
|
SELECT created_at_epoch
|
|
581
594
|
FROM observations
|
|
582
595
|
WHERE created_at_epoch >= ? ${i}
|
|
583
596
|
ORDER BY created_at_epoch ASC
|
|
584
597
|
LIMIT ?
|
|
585
|
-
`;try{let f=this.db.prepare(l).all(t,...a,s),T=this.db.prepare(
|
|
598
|
+
`;try{let f=this.db.prepare(l).all(t,...a,s),T=this.db.prepare(h).all(t,...a,n+1);if(f.length===0&&T.length===0)return{observations:[],sessions:[],prompts:[]};d=f.length>0?f[f.length-1].created_at_epoch:t,m=T.length>0?T[T.length-1].created_at_epoch:t}catch(f){return f instanceof Error?u.error("DB","Error getting boundary timestamps",{project:o},f):u.error("DB","Error getting boundary timestamps with non-Error",{},new Error(String(f))),{observations:[],sessions:[],prompts:[]}}}let c=`
|
|
586
599
|
SELECT *
|
|
587
600
|
FROM observations
|
|
588
601
|
WHERE created_at_epoch >= ? AND created_at_epoch <= ? ${i}
|
|
@@ -598,7 +611,7 @@ ${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?u=`
|
|
|
598
611
|
JOIN sdk_sessions s ON up.content_session_id = s.content_session_id
|
|
599
612
|
WHERE up.created_at_epoch >= ? AND up.created_at_epoch <= ? ${i.replace("project","s.project")}
|
|
600
613
|
ORDER BY up.created_at_epoch ASC
|
|
601
|
-
`,g=this.db.prepare(
|
|
614
|
+
`,g=this.db.prepare(c).all(d,m,...a),b=this.db.prepare(E).all(d,m,...a),N=this.db.prepare(p).all(d,m,...a);return{observations:g,sessions:b.map(l=>({id:l.id,memory_session_id:l.memory_session_id,project:l.project,request:l.request,completed:l.completed,next_steps:l.next_steps,created_at:l.created_at,created_at_epoch:l.created_at_epoch})),prompts:N.map(l=>({id:l.id,content_session_id:l.content_session_id,prompt_number:l.prompt_number,prompt_text:l.prompt_text,project:l.project,created_at:l.created_at,created_at_epoch:l.created_at_epoch}))}}getPromptById(e){return this.db.prepare(`
|
|
602
615
|
SELECT
|
|
603
616
|
p.id,
|
|
604
617
|
p.content_session_id,
|
|
@@ -642,7 +655,7 @@ ${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?u=`
|
|
|
642
655
|
`).get(e)||null}getOrCreateManualSession(e){let t=`manual-${e}`,s=`manual-content-${e}`;if(this.db.prepare("SELECT memory_session_id FROM sdk_sessions WHERE memory_session_id = ?").get(t))return t;let o=new Date;return this.db.prepare(`
|
|
643
656
|
INSERT INTO sdk_sessions (memory_session_id, content_session_id, project, platform_source, started_at, started_at_epoch, status)
|
|
644
657
|
VALUES (?, ?, ?, ?, ?, ?, 'active')
|
|
645
|
-
`).run(t,s,e,
|
|
658
|
+
`).run(t,s,e,O,o.toISOString(),o.getTime()),u.info("SESSION","Created manual session",{memorySessionId:t,project:e}),t}close(){this.db.close()}importSdkSession(e){let t=this.db.prepare("SELECT id FROM sdk_sessions WHERE content_session_id = ?").get(e.content_session_id);return t?{imported:!1,id:t.id}:{imported:!0,id:this.db.prepare(`
|
|
646
659
|
INSERT INTO sdk_sessions (
|
|
647
660
|
content_session_id, memory_session_id, project, platform_source, user_prompt,
|
|
648
661
|
started_at, started_at_epoch, completed_at, completed_at_epoch, status
|
|
@@ -671,7 +684,7 @@ ${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?u=`
|
|
|
671
684
|
content_session_id, prompt_number, prompt_text,
|
|
672
685
|
created_at, created_at_epoch
|
|
673
686
|
) VALUES (?, ?, ?, ?, ?)
|
|
674
|
-
`).run(e.content_session_id,e.prompt_number,e.prompt_text,e.created_at,e.created_at_epoch).lastInsertRowid}}};var Ue=L(require("path"),1),xe=require("os");var C=require("fs"),x=require("path"),oe=require("os"),W=class{static DEFAULTS={CLAUDE_MEM_MODEL:"claude-sonnet-4-6",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_WORKER_PORT:String(37700+(process.getuid?.()??77)%100),CLAUDE_MEM_WORKER_HOST:"127.0.0.1",CLAUDE_MEM_SKIP_TOOLS:"ListMcpResourcesTool,SlashCommand,Skill,TodoWrite,AskUserQuestion",CLAUDE_MEM_PROVIDER:"claude",CLAUDE_MEM_CLAUDE_AUTH_METHOD:"cli",CLAUDE_MEM_GEMINI_API_KEY:"",CLAUDE_MEM_GEMINI_MODEL:"gemini-2.5-flash-lite",CLAUDE_MEM_GEMINI_RATE_LIMITING_ENABLED:"true",CLAUDE_MEM_GEMINI_MAX_CONTEXT_MESSAGES:"20",CLAUDE_MEM_GEMINI_MAX_TOKENS:"100000",CLAUDE_MEM_OPENROUTER_API_KEY:"",CLAUDE_MEM_OPENROUTER_MODEL:"xiaomi/mimo-v2-flash:free",CLAUDE_MEM_OPENROUTER_SITE_URL:"",CLAUDE_MEM_OPENROUTER_APP_NAME:"claude-mem",CLAUDE_MEM_OPENROUTER_MAX_CONTEXT_MESSAGES:"20",CLAUDE_MEM_OPENROUTER_MAX_TOKENS:"100000",CLAUDE_MEM_DATA_DIR:(0,x.join)((0,oe.homedir)(),".claude-mem"),CLAUDE_MEM_LOG_LEVEL:"INFO",CLAUDE_MEM_PYTHON_VERSION:"3.13",CLAUDE_CODE_PATH:"",CLAUDE_MEM_MODE:"code",CLAUDE_MEM_CONTEXT_SHOW_READ_TOKENS:"false",CLAUDE_MEM_CONTEXT_SHOW_WORK_TOKENS:"false",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT:"false",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT:"true",CLAUDE_MEM_CONTEXT_FULL_COUNT:"0",CLAUDE_MEM_CONTEXT_FULL_FIELD:"narrative",CLAUDE_MEM_CONTEXT_SESSION_COUNT:"10",CLAUDE_MEM_CONTEXT_SHOW_LAST_SUMMARY:"true",CLAUDE_MEM_CONTEXT_SHOW_LAST_MESSAGE:"false",CLAUDE_MEM_CONTEXT_SHOW_TERMINAL_OUTPUT:"true",CLAUDE_MEM_FOLDER_CLAUDEMD_ENABLED:"false",CLAUDE_MEM_FOLDER_USE_LOCAL_MD:"false",CLAUDE_MEM_TRANSCRIPTS_ENABLED:"true",CLAUDE_MEM_TRANSCRIPTS_CONFIG_PATH:(0,x.join)((0,oe.homedir)(),".claude-mem","transcript-watch.json"),CLAUDE_MEM_MAX_CONCURRENT_AGENTS:"2",CLAUDE_MEM_HOOK_FAIL_LOUD_THRESHOLD:"3",CLAUDE_MEM_EXCLUDED_PROJECTS:"",CLAUDE_MEM_FOLDER_MD_EXCLUDE:"[]",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_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_TELEGRAM_ENABLED:"true",CLAUDE_MEM_TELEGRAM_BOT_TOKEN:"",CLAUDE_MEM_TELEGRAM_CHAT_ID:"",CLAUDE_MEM_TELEGRAM_TRIGGER_TYPES:"security_alert",CLAUDE_MEM_TELEGRAM_TRIGGER_CONCEPTS:""};static getAllDefaults(){return{...this.DEFAULTS}}static get(e){return process.env[e]??this.DEFAULTS[e]}static getInt(e){let t=this.get(e);return parseInt(t,10)}static getBool(e){let t=this.get(e);return t==="true"||t===!0}static applyEnvOverrides(e){let t={...e};for(let s of Object.keys(this.DEFAULTS))process.env[s]!==void 0&&(t[s]=process.env[s]);return t}static loadFromFile(e){try{if(!(0,C.existsSync)(e)){let i=this.getAllDefaults();try{let a=(0,x.dirname)(e);(0,C.existsSync)(a)||(0,C.mkdirSync)(a,{recursive:!0}),(0,C.writeFileSync)(e,JSON.stringify(i,null,2),"utf-8"),console.log("[SETTINGS] Created settings file with defaults:",e)}catch(a){console.warn("[SETTINGS] Failed to create settings file, using in-memory defaults:",e,a instanceof Error?a.message:String(a))}return this.applyEnvOverrides(i)}let t=(0,C.readFileSync)(e,"utf-8"),s=JSON.parse(t),n=s;if(s.env&&typeof s.env=="object"){n=s.env;try{(0,C.writeFileSync)(e,JSON.stringify(n,null,2),"utf-8"),console.log("[SETTINGS] Migrated settings file from nested to flat schema:",e)}catch(i){console.warn("[SETTINGS] Failed to auto-migrate settings file:",e,i instanceof Error?i.message:String(i))}}let o={...this.DEFAULTS};for(let i of Object.keys(this.DEFAULTS))n[i]!==void 0&&(o[i]=n[i]);return this.applyEnvOverrides(o)}catch(t){return console.warn("[SETTINGS] Failed to load settings, using defaults:",e,t instanceof Error?t.message:String(t)),this.applyEnvOverrides(this.getAllDefaults())}}};var k=require("fs"),q=require("path");var A=class r{static instance=null;activeMode=null;modesDir;constructor(){let e=Ce(),t=[(0,q.join)(e,"modes"),(0,q.join)(e,"..","plugin","modes")],s=t.find(n=>(0,k.existsSync)(n));this.modesDir=s||t[0]}static getInstance(){return r.instance||(r.instance=new r),r.instance}parseInheritance(e){let t=e.split("--");if(t.length===1)return{hasParent:!1,parentId:"",overrideId:""};if(t.length>2)throw new Error(`Invalid mode inheritance: ${e}. Only one level of inheritance supported (parent--override)`);return{hasParent:!0,parentId:t[0],overrideId:e}}isPlainObject(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}deepMerge(e,t){let s={...e};for(let n in t){let o=t[n],i=e[n];this.isPlainObject(o)&&this.isPlainObject(i)?s[n]=this.deepMerge(i,o):s[n]=o}return s}loadModeFile(e){let t=(0,q.join)(this.modesDir,`${e}.json`);if(!(0,k.existsSync)(t))throw new Error(`Mode file not found: ${t}`);let s=(0,k.readFileSync)(t,"utf-8");return JSON.parse(s)}loadMode(e){let t=this.parseInheritance(e);if(!t.hasParent)try{let d=this.loadModeFile(e);return this.activeMode=d,
|
|
687
|
+
`).run(e.content_session_id,e.prompt_number,e.prompt_text,e.created_at,e.created_at_epoch).lastInsertRowid}}};var Ue=L(require("path"),1),xe=require("os");var C=require("fs"),x=require("path"),oe=require("os"),W=class{static DEFAULTS={CLAUDE_MEM_MODEL:"claude-sonnet-4-6",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_WORKER_PORT:String(37700+(process.getuid?.()??77)%100),CLAUDE_MEM_WORKER_HOST:"127.0.0.1",CLAUDE_MEM_SKIP_TOOLS:"ListMcpResourcesTool,SlashCommand,Skill,TodoWrite,AskUserQuestion",CLAUDE_MEM_PROVIDER:"claude",CLAUDE_MEM_CLAUDE_AUTH_METHOD:"cli",CLAUDE_MEM_GEMINI_API_KEY:"",CLAUDE_MEM_GEMINI_MODEL:"gemini-2.5-flash-lite",CLAUDE_MEM_GEMINI_RATE_LIMITING_ENABLED:"true",CLAUDE_MEM_GEMINI_MAX_CONTEXT_MESSAGES:"20",CLAUDE_MEM_GEMINI_MAX_TOKENS:"100000",CLAUDE_MEM_OPENROUTER_API_KEY:"",CLAUDE_MEM_OPENROUTER_MODEL:"xiaomi/mimo-v2-flash:free",CLAUDE_MEM_OPENROUTER_SITE_URL:"",CLAUDE_MEM_OPENROUTER_APP_NAME:"claude-mem",CLAUDE_MEM_OPENROUTER_MAX_CONTEXT_MESSAGES:"20",CLAUDE_MEM_OPENROUTER_MAX_TOKENS:"100000",CLAUDE_MEM_DATA_DIR:(0,x.join)((0,oe.homedir)(),".claude-mem"),CLAUDE_MEM_LOG_LEVEL:"INFO",CLAUDE_MEM_PYTHON_VERSION:"3.13",CLAUDE_CODE_PATH:"",CLAUDE_MEM_MODE:"code",CLAUDE_MEM_CONTEXT_SHOW_READ_TOKENS:"false",CLAUDE_MEM_CONTEXT_SHOW_WORK_TOKENS:"false",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT:"false",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT:"true",CLAUDE_MEM_CONTEXT_FULL_COUNT:"0",CLAUDE_MEM_CONTEXT_FULL_FIELD:"narrative",CLAUDE_MEM_CONTEXT_SESSION_COUNT:"10",CLAUDE_MEM_CONTEXT_SHOW_LAST_SUMMARY:"true",CLAUDE_MEM_CONTEXT_SHOW_LAST_MESSAGE:"false",CLAUDE_MEM_CONTEXT_SHOW_TERMINAL_OUTPUT:"true",CLAUDE_MEM_FOLDER_CLAUDEMD_ENABLED:"false",CLAUDE_MEM_FOLDER_USE_LOCAL_MD:"false",CLAUDE_MEM_TRANSCRIPTS_ENABLED:"true",CLAUDE_MEM_TRANSCRIPTS_CONFIG_PATH:(0,x.join)((0,oe.homedir)(),".claude-mem","transcript-watch.json"),CLAUDE_MEM_MAX_CONCURRENT_AGENTS:"2",CLAUDE_MEM_HOOK_FAIL_LOUD_THRESHOLD:"3",CLAUDE_MEM_EXCLUDED_PROJECTS:"",CLAUDE_MEM_FOLDER_MD_EXCLUDE:"[]",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_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_TELEGRAM_ENABLED:"true",CLAUDE_MEM_TELEGRAM_BOT_TOKEN:"",CLAUDE_MEM_TELEGRAM_CHAT_ID:"",CLAUDE_MEM_TELEGRAM_TRIGGER_TYPES:"security_alert",CLAUDE_MEM_TELEGRAM_TRIGGER_CONCEPTS:""};static getAllDefaults(){return{...this.DEFAULTS}}static get(e){return process.env[e]??this.DEFAULTS[e]}static getInt(e){let t=this.get(e);return parseInt(t,10)}static getBool(e){let t=this.get(e);return t==="true"||t===!0}static applyEnvOverrides(e){let t={...e};for(let s of Object.keys(this.DEFAULTS))process.env[s]!==void 0&&(t[s]=process.env[s]);return t}static loadFromFile(e){try{if(!(0,C.existsSync)(e)){let i=this.getAllDefaults();try{let a=(0,x.dirname)(e);(0,C.existsSync)(a)||(0,C.mkdirSync)(a,{recursive:!0}),(0,C.writeFileSync)(e,JSON.stringify(i,null,2),"utf-8"),console.log("[SETTINGS] Created settings file with defaults:",e)}catch(a){console.warn("[SETTINGS] Failed to create settings file, using in-memory defaults:",e,a instanceof Error?a.message:String(a))}return this.applyEnvOverrides(i)}let t=(0,C.readFileSync)(e,"utf-8"),s=JSON.parse(t),n=s;if(s.env&&typeof s.env=="object"){n=s.env;try{(0,C.writeFileSync)(e,JSON.stringify(n,null,2),"utf-8"),console.log("[SETTINGS] Migrated settings file from nested to flat schema:",e)}catch(i){console.warn("[SETTINGS] Failed to auto-migrate settings file:",e,i instanceof Error?i.message:String(i))}}let o={...this.DEFAULTS};for(let i of Object.keys(this.DEFAULTS))n[i]!==void 0&&(o[i]=n[i]);return this.applyEnvOverrides(o)}catch(t){return console.warn("[SETTINGS] Failed to load settings, using defaults:",e,t instanceof Error?t.message:String(t)),this.applyEnvOverrides(this.getAllDefaults())}}};var k=require("fs"),q=require("path");var A=class r{static instance=null;activeMode=null;modesDir;constructor(){let e=Ce(),t=[(0,q.join)(e,"modes"),(0,q.join)(e,"..","plugin","modes")],s=t.find(n=>(0,k.existsSync)(n));this.modesDir=s||t[0]}static getInstance(){return r.instance||(r.instance=new r),r.instance}parseInheritance(e){let t=e.split("--");if(t.length===1)return{hasParent:!1,parentId:"",overrideId:""};if(t.length>2)throw new Error(`Invalid mode inheritance: ${e}. Only one level of inheritance supported (parent--override)`);return{hasParent:!0,parentId:t[0],overrideId:e}}isPlainObject(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}deepMerge(e,t){let s={...e};for(let n in t){let o=t[n],i=e[n];this.isPlainObject(o)&&this.isPlainObject(i)?s[n]=this.deepMerge(i,o):s[n]=o}return s}loadModeFile(e){let t=(0,q.join)(this.modesDir,`${e}.json`);if(!(0,k.existsSync)(t))throw new Error(`Mode file not found: ${t}`);let s=(0,k.readFileSync)(t,"utf-8");return JSON.parse(s)}loadMode(e){let t=this.parseInheritance(e);if(!t.hasParent)try{let d=this.loadModeFile(e);return this.activeMode=d,u.debug("SYSTEM",`Loaded mode: ${d.name} (${e})`,void 0,{types:d.observation_types.map(m=>m.id),concepts:d.observation_concepts.map(m=>m.id)}),d}catch(d){if(d instanceof Error?u.warn("WORKER",`Mode file not found: ${e}, falling back to 'code'`,{message:d.message}):u.warn("WORKER",`Mode file not found: ${e}, falling back to 'code'`,{error:String(d)}),e==="code")throw new Error("Critical: code.json mode file missing");return this.loadMode("code")}let{parentId:s,overrideId:n}=t,o;try{o=this.loadMode(s)}catch(d){d instanceof Error?u.warn("WORKER",`Parent mode '${s}' not found for ${e}, falling back to 'code'`,{message:d.message}):u.warn("WORKER",`Parent mode '${s}' not found for ${e}, falling back to 'code'`,{error:String(d)}),o=this.loadMode("code")}let i;try{i=this.loadModeFile(n),u.debug("SYSTEM",`Loaded override file: ${n} for parent ${s}`)}catch(d){return d instanceof Error?u.warn("WORKER",`Override file '${n}' not found, using parent mode '${s}' only`,{message:d.message}):u.warn("WORKER",`Override file '${n}' not found, using parent mode '${s}' only`,{error:String(d)}),this.activeMode=o,o}if(!i)return u.warn("SYSTEM",`Invalid override file: ${n}, using parent mode '${s}' only`),this.activeMode=o,o;let a=this.deepMerge(o,i);return this.activeMode=a,u.debug("SYSTEM",`Loaded mode with inheritance: ${a.name} (${e} = ${s} + ${n})`,void 0,{parent:s,override:n,types:a.observation_types.map(d=>d.id),concepts:a.observation_concepts.map(d=>d.id)}),a}getActiveMode(){if(!this.activeMode)throw new Error("No mode loaded. Call loadMode() first.");return this.activeMode}getObservationTypes(){return this.getActiveMode().observation_types}getObservationConcepts(){return this.getActiveMode().observation_concepts}getTypeIcon(e){return this.getObservationTypes().find(s=>s.id===e)?.emoji||"\u{1F4DD}"}getWorkEmoji(e){return this.getObservationTypes().find(s=>s.id===e)?.work_emoji||"\u{1F4DD}"}validateType(e){return this.getObservationTypes().some(t=>t.id===e)}getTypeLabel(e){return this.getObservationTypes().find(s=>s.id===e)?.label||e}};function ie(){let r=Ue.default.join((0,xe.homedir)(),".claude-mem","settings.json"),e=W.loadFromFile(r),t=A.getInstance().getActiveMode(),s=new Set(t.observation_types.map(o=>o.id)),n=new Set(t.observation_concepts.map(o=>o.id));return{totalObservationCount:parseInt(e.CLAUDE_MEM_CONTEXT_OBSERVATIONS,10),fullObservationCount:parseInt(e.CLAUDE_MEM_CONTEXT_FULL_COUNT,10),sessionCount:parseInt(e.CLAUDE_MEM_CONTEXT_SESSION_COUNT,10),showReadTokens:e.CLAUDE_MEM_CONTEXT_SHOW_READ_TOKENS==="true",showWorkTokens:e.CLAUDE_MEM_CONTEXT_SHOW_WORK_TOKENS==="true",showSavingsAmount:e.CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT==="true",showSavingsPercent:e.CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT==="true",observationTypes:s,observationConcepts:n,fullObservationField:e.CLAUDE_MEM_CONTEXT_FULL_FIELD,showLastSummary:e.CLAUDE_MEM_CONTEXT_SHOW_LAST_SUMMARY==="true",showLastMessage:e.CLAUDE_MEM_CONTEXT_SHOW_LAST_MESSAGE==="true"}}var _={reset:"\x1B[0m",bright:"\x1B[1m",dim:"\x1B[2m",cyan:"\x1B[36m",green:"\x1B[32m",yellow:"\x1B[33m",blue:"\x1B[34m",magenta:"\x1B[35m",gray:"\x1B[90m",red:"\x1B[31m"},ke=4,ae=1;function de(r){let e=(r.title?.length||0)+(r.subtitle?.length||0)+(r.narrative?.length||0)+JSON.stringify(r.facts||[]).length;return Math.ceil(e/ke)}function _e(r){let e=r.length,t=r.reduce((i,a)=>i+de(a),0),s=r.reduce((i,a)=>i+(a.discovery_tokens||0),0),n=s-t,o=s>0?Math.round(n/s*100):0;return{totalObservations:e,totalReadTokens:t,totalDiscoveryTokens:s,savings:n,savingsPercent:o}}function Bt(r){return A.getInstance().getWorkEmoji(r)}function w(r,e){let t=de(r),s=r.discovery_tokens||0,n=Bt(r.type),o=s>0?`${n} ${s.toLocaleString()}`:"-";return{readTokens:t,discoveryTokens:s,discoveryDisplay:o,workEmoji:n}}function Y(r){return r.showReadTokens||r.showWorkTokens||r.showSavingsAmount||r.showSavingsPercent}var Fe=L(require("path"),1),V=require("fs");var Wt=["private","claude-mem-context","system_instruction","system-instruction","persisted-output","system-reminder"],Ks=new RegExp(`<(${Wt.join("|")})\\b[^>]*>[\\s\\S]*?</\\1>`,"g"),we=/<system-reminder>[\s\S]*?<\/system-reminder>/g;var qt=["task-notification"],Js=new RegExp(`^\\s*<(${qt.join("|")})\\b[^>]*>(?:(?!<\\1\\b|</\\1\\b)[\\s\\S])*</\\1>\\s*$`),Qs=256*1024;function ue(r,e,t){let s=Array.from(t.observationTypes),n=s.map(()=>"?").join(","),o=Array.from(t.observationConcepts),i=o.map(()=>"?").join(",");return r.db.prepare(`
|
|
675
688
|
SELECT
|
|
676
689
|
o.id,
|
|
677
690
|
o.memory_session_id,
|
|
@@ -761,14 +774,14 @@ ${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?u=`
|
|
|
761
774
|
OR ss.merged_into_project IN (${s}))
|
|
762
775
|
ORDER BY ss.created_at_epoch DESC
|
|
763
776
|
LIMIT ?
|
|
764
|
-
`).all(...e,...e,t.sessionCount+ae)}function Yt(r){return r.replace(/\//g,"-")}function Vt(r){if(!r.includes('"type":"assistant"'))return null;let e=JSON.parse(r);if(e.type==="assistant"&&e.message?.content&&Array.isArray(e.message.content)){let t="";for(let s of e.message.content)s.type==="text"&&(t+=s.text);if(t=t.replace(we,"").trim(),t)return t}return null}function Kt(r){for(let e=r.length-1;e>=0;e--)try{let t=Vt(r[e]);if(t)return t}catch(t){t instanceof Error?
|
|
765
|
-
`).filter(n=>n.trim());return{userMessage:"",assistantMessage:Kt(t)}}catch(e){return e instanceof Error?
|
|
777
|
+
`).all(...e,...e,t.sessionCount+ae)}function Yt(r){return r.replace(/\//g,"-")}function Vt(r){if(!r.includes('"type":"assistant"'))return null;let e=JSON.parse(r);if(e.type==="assistant"&&e.message?.content&&Array.isArray(e.message.content)){let t="";for(let s of e.message.content)s.type==="text"&&(t+=s.text);if(t=t.replace(we,"").trim(),t)return t}return null}function Kt(r){for(let e=r.length-1;e>=0;e--)try{let t=Vt(r[e]);if(t)return t}catch(t){t instanceof Error?u.debug("WORKER","Skipping malformed transcript line",{lineIndex:e},t):u.debug("WORKER","Skipping malformed transcript line",{lineIndex:e,error:String(t)});continue}return""}function Jt(r){try{if(!(0,V.existsSync)(r))return{userMessage:"",assistantMessage:""};let e=(0,V.readFileSync)(r,"utf-8").trim();if(!e)return{userMessage:"",assistantMessage:""};let t=e.split(`
|
|
778
|
+
`).filter(n=>n.trim());return{userMessage:"",assistantMessage:Kt(t)}}catch(e){return e instanceof Error?u.failure("WORKER","Failed to extract prior messages from transcript",{transcriptPath:r},e):u.warn("WORKER","Failed to extract prior messages from transcript",{transcriptPath:r,error:String(e)}),{userMessage:"",assistantMessage:""}}}function ce(r,e,t,s){if(!e.showLastMessage||r.length===0)return{userMessage:"",assistantMessage:""};let n=r.find(d=>d.memory_session_id!==t);if(!n)return{userMessage:"",assistantMessage:""};let o=n.memory_session_id,i=Yt(s),a=Fe.default.join(y,"projects",i,`${o}.jsonl`);return Jt(a)}function Ge(r,e){let t=e[0]?.id;return r.map((s,n)=>{let o=n===0?null:e[n+1];return{...s,displayEpoch:o?o.created_at_epoch:s.created_at_epoch,displayTime:o?o.created_at:s.created_at,shouldShowLink:s.id!==t}})}function le(r,e){let t=[...r.map(s=>({type:"observation",data:s})),...e.map(s=>({type:"summary",data:s}))];return t.sort((s,n)=>{let o=s.type==="observation"?s.data.created_at_epoch:s.data.displayEpoch,i=n.type==="observation"?n.data.created_at_epoch:n.data.displayEpoch;return o-i}),t}function He(r,e){return new Set(r.slice(0,e).map(t=>t.id))}function Xe(){let r=new Date,e=r.toLocaleDateString("en-CA"),t=r.toLocaleTimeString("en-US",{hour:"numeric",minute:"2-digit",hour12:!0}).toLowerCase().replace(" ",""),s=r.toLocaleTimeString("en-US",{timeZoneName:"short"}).split(" ").pop();return`${e} ${t} ${s}`}function je(r){return[`# [${r}] recent context, ${Xe()}`,""]}function Be(){return[`Legend: \u{1F3AF}session ${A.getInstance().getActiveMode().observation_types.map(t=>`${t.emoji}${t.id}`).join(" ")}`,"Format: ID TIME TYPE TITLE","Fetch details: get_observations([IDs]) | Search: mem-search skill",""]}function We(){return[]}function qe(){return[]}function Ye(r,e){let t=[],s=[`${r.totalObservations} obs (${r.totalReadTokens.toLocaleString()}t read)`,`${r.totalDiscoveryTokens.toLocaleString()}t work`];return r.totalDiscoveryTokens>0&&(e.showSavingsAmount||e.showSavingsPercent)&&(e.showSavingsPercent?s.push(`${r.savingsPercent}% savings`):e.showSavingsAmount&&s.push(`${r.savings.toLocaleString()}t saved`)),t.push(`Stats: ${s.join(" | ")}`),t.push(""),t}function Ve(r){return[`### ${r}`]}function Ke(r){return r.toLowerCase().replace(" am","a").replace(" pm","p")}function Je(r,e,t){let s=r.title||"Untitled",n=A.getInstance().getTypeIcon(r.type),o=e?Ke(e):'"';return`${r.id} ${o} ${n} ${s}`}function Qe(r,e,t,s){let n=[],o=r.title||"Untitled",i=A.getInstance().getTypeIcon(r.type),a=e?Ke(e):'"',{readTokens:d,discoveryDisplay:m}=w(r,s);n.push(`**${r.id}** ${a} ${i} **${o}**`),t&&n.push(t);let c=[];return s.showReadTokens&&c.push(`~${d}t`),s.showWorkTokens&&c.push(m),c.length>0&&n.push(c.join(" ")),n.push(""),n}function ze(r,e){return[`S${r.id} ${r.request||"Session started"} (${e})`]}function F(r,e){return e?[`**${r}**: ${e}`,""]:[]}function Ze(r){return r.assistantMessage?["","---","","**Previously**","",`A: ${r.assistantMessage}`,""]:[]}function et(r,e){return["",`Access ${Math.round(r/1e3)}k tokens of past work via get_observations([IDs]) or mem-search skill.`]}function tt(r){return`# [${r}] recent context, ${Xe()}
|
|
766
779
|
|
|
767
|
-
No previous sessions found.`}function st(){let r=new Date,e=r.toLocaleDateString("en-CA"),t=r.toLocaleTimeString("en-US",{hour:"numeric",minute:"2-digit",hour12:!0}).toLowerCase().replace(" ",""),s=r.toLocaleTimeString("en-US",{timeZoneName:"short"}).split(" ").pop();return`${e} ${t} ${s}`}function rt(r){return["",`${_.bright}${_.cyan}[${r}] recent context, ${st()}${_.reset}`,`${_.gray}${"\u2500".repeat(60)}${_.reset}`,""]}function nt(){let e=A.getInstance().getActiveMode().observation_types.map(t=>`${t.emoji} ${t.id}`).join(" | ");return[`${_.dim}Legend: session-request | ${e}${_.reset}`,""]}function ot(){return[`${_.bright}Column Key${_.reset}`,`${_.dim} Read: Tokens to read this observation (cost to learn it now)${_.reset}`,`${_.dim} Work: Tokens spent on work that produced this record ( research, building, deciding)${_.reset}`,""]}function it(){return[`${_.dim}Context Index: This semantic index (titles, types, files, tokens) is usually sufficient to understand past work.${_.reset}`,"",`${_.dim}When you need implementation details, rationale, or debugging context:${_.reset}`,`${_.dim} - Fetch by ID: get_observations([IDs]) for observations visible in this index${_.reset}`,`${_.dim} - Search history: Use the mem-search skill for past decisions, bugs, and deeper research${_.reset}`,`${_.dim} - Trust this index over re-reading code for past decisions and learnings${_.reset}`,""]}function at(r,e){let t=[];if(t.push(`${_.bright}${_.cyan}Context Economics${_.reset}`),t.push(`${_.dim} Loading: ${r.totalObservations} observations (${r.totalReadTokens.toLocaleString()} tokens to read)${_.reset}`),t.push(`${_.dim} Work investment: ${r.totalDiscoveryTokens.toLocaleString()} tokens spent on research, building, and decisions${_.reset}`),r.totalDiscoveryTokens>0&&(e.showSavingsAmount||e.showSavingsPercent)){let s=" Your savings: ";e.showSavingsAmount&&e.showSavingsPercent?s+=`${r.savings.toLocaleString()} tokens (${r.savingsPercent}% reduction from reuse)`:e.showSavingsAmount?s+=`${r.savings.toLocaleString()} tokens`:s+=`${r.savingsPercent}% reduction from reuse`,t.push(`${_.green}${s}${_.reset}`)}return t.push(""),t}function dt(r){return[`${_.bright}${_.cyan}${r}${_.reset}`,""]}function _t(r){return[`${_.dim}${r}${_.reset}`]}function ut(r,e,t,s){let n=r.title||"Untitled",o=A.getInstance().getTypeIcon(r.type),{readTokens:i,discoveryTokens:a,workEmoji:d}=w(r,s),m=t?`${_.dim}${e}${_.reset}`:" ".repeat(e.length),
|
|
780
|
+
No previous sessions found.`}function st(){let r=new Date,e=r.toLocaleDateString("en-CA"),t=r.toLocaleTimeString("en-US",{hour:"numeric",minute:"2-digit",hour12:!0}).toLowerCase().replace(" ",""),s=r.toLocaleTimeString("en-US",{timeZoneName:"short"}).split(" ").pop();return`${e} ${t} ${s}`}function rt(r){return["",`${_.bright}${_.cyan}[${r}] recent context, ${st()}${_.reset}`,`${_.gray}${"\u2500".repeat(60)}${_.reset}`,""]}function nt(){let e=A.getInstance().getActiveMode().observation_types.map(t=>`${t.emoji} ${t.id}`).join(" | ");return[`${_.dim}Legend: session-request | ${e}${_.reset}`,""]}function ot(){return[`${_.bright}Column Key${_.reset}`,`${_.dim} Read: Tokens to read this observation (cost to learn it now)${_.reset}`,`${_.dim} Work: Tokens spent on work that produced this record ( research, building, deciding)${_.reset}`,""]}function it(){return[`${_.dim}Context Index: This semantic index (titles, types, files, tokens) is usually sufficient to understand past work.${_.reset}`,"",`${_.dim}When you need implementation details, rationale, or debugging context:${_.reset}`,`${_.dim} - Fetch by ID: get_observations([IDs]) for observations visible in this index${_.reset}`,`${_.dim} - Search history: Use the mem-search skill for past decisions, bugs, and deeper research${_.reset}`,`${_.dim} - Trust this index over re-reading code for past decisions and learnings${_.reset}`,""]}function at(r,e){let t=[];if(t.push(`${_.bright}${_.cyan}Context Economics${_.reset}`),t.push(`${_.dim} Loading: ${r.totalObservations} observations (${r.totalReadTokens.toLocaleString()} tokens to read)${_.reset}`),t.push(`${_.dim} Work investment: ${r.totalDiscoveryTokens.toLocaleString()} tokens spent on research, building, and decisions${_.reset}`),r.totalDiscoveryTokens>0&&(e.showSavingsAmount||e.showSavingsPercent)){let s=" Your savings: ";e.showSavingsAmount&&e.showSavingsPercent?s+=`${r.savings.toLocaleString()} tokens (${r.savingsPercent}% reduction from reuse)`:e.showSavingsAmount?s+=`${r.savings.toLocaleString()} tokens`:s+=`${r.savingsPercent}% reduction from reuse`,t.push(`${_.green}${s}${_.reset}`)}return t.push(""),t}function dt(r){return[`${_.bright}${_.cyan}${r}${_.reset}`,""]}function _t(r){return[`${_.dim}${r}${_.reset}`]}function ut(r,e,t,s){let n=r.title||"Untitled",o=A.getInstance().getTypeIcon(r.type),{readTokens:i,discoveryTokens:a,workEmoji:d}=w(r,s),m=t?`${_.dim}${e}${_.reset}`:" ".repeat(e.length),c=s.showReadTokens&&i>0?`${_.dim}(~${i}t)${_.reset}`:"",E=s.showWorkTokens&&a>0?`${_.dim}(${d} ${a.toLocaleString()}t)${_.reset}`:"";return` ${_.dim}#${r.id}${_.reset} ${m} ${o} ${n} ${c} ${E}`}function mt(r,e,t,s,n){let o=[],i=r.title||"Untitled",a=A.getInstance().getTypeIcon(r.type),{readTokens:d,discoveryTokens:m,workEmoji:c}=w(r,n),E=t?`${_.dim}${e}${_.reset}`:" ".repeat(e.length),p=n.showReadTokens&&d>0?`${_.dim}(~${d}t)${_.reset}`:"",g=n.showWorkTokens&&m>0?`${_.dim}(${c} ${m.toLocaleString()}t)${_.reset}`:"";return o.push(` ${_.dim}#${r.id}${_.reset} ${E} ${a} ${_.bright}${i}${_.reset}`),s&&o.push(` ${_.dim}${s}${_.reset}`),(p||g)&&o.push(` ${p} ${g}`),o.push(""),o}function ct(r,e){let t=`${r.request||"Session started"} (${e})`;return[`${_.yellow}#S${r.id}${_.reset} ${t}`,""]}function $(r,e,t){return e?[`${t}${r}:${_.reset} ${e}`,""]:[]}function lt(r){return r.assistantMessage?["","---","",`${_.bright}${_.magenta}Previously${_.reset}`,"",`${_.dim}A: ${r.assistantMessage}${_.reset}`,""]:[]}function pt(r,e){let t=Math.round(r/1e3);return["",`${_.dim}Access ${t}k tokens of past research & decisions for just ${e.toLocaleString()}t. Use the claude-mem skill to access memories by ID.${_.reset}`]}function Et(r){return`
|
|
768
781
|
${_.bright}${_.cyan}[${r}] recent context, ${st()}${_.reset}
|
|
769
782
|
${_.gray}${"\u2500".repeat(60)}${_.reset}
|
|
770
783
|
|
|
771
784
|
${_.dim}No previous sessions found for this project yet.${_.reset}
|
|
772
|
-
`}function gt(r,e,t,s){let n=[];return s?n.push(...rt(r)):n.push(...
|
|
773
|
-
`):null}function zt(r,e,t,s){let n=[];n.push(...Ve(r));let o="";for(let i of e)if(i.type==="summary"){let a=i.data,d=Ee(a.displayTime);n.push(...ze(a,d))}else{let a=i.data,d=ge(a.created_at),
|
|
785
|
+
`}function gt(r,e,t,s){let n=[];return s?n.push(...rt(r)):n.push(...je(r)),s?n.push(...nt()):n.push(...Be()),s?n.push(...ot()):n.push(...We()),s?n.push(...it()):n.push(...qe()),Y(t)&&(s?n.push(...at(e,t)):n.push(...Ye(e,t))),n}var pe=L(require("path"),1);function Q(r){if(!r)return[];try{let e=JSON.parse(r);return Array.isArray(e)?e:[]}catch(e){return u.debug("PARSER","Failed to parse JSON array, using empty fallback",{preview:r?.substring(0,50)},e instanceof Error?e:new Error(String(e))),[]}}function Ee(r){return new Date(r).toLocaleString("en-US",{month:"short",day:"numeric",hour:"numeric",minute:"2-digit",hour12:!0})}function ge(r){return new Date(r).toLocaleString("en-US",{hour:"numeric",minute:"2-digit",hour12:!0})}function ft(r){return new Date(r).toLocaleString("en-US",{month:"short",day:"numeric",year:"numeric"})}function Tt(r,e){return pe.default.isAbsolute(r)?pe.default.relative(e,r):r}function St(r,e,t){let s=Q(r);if(s.length>0)return Tt(s[0],e);if(t){let n=Q(t);if(n.length>0)return Tt(n[0],e)}return"General"}function Qt(r){let e=new Map;for(let s of r){let n=s.type==="observation"?s.data.created_at:s.data.displayTime,o=ft(n);e.has(o)||e.set(o,[]),e.get(o).push(s)}let t=Array.from(e.entries()).sort((s,n)=>{let o=new Date(s[0]).getTime(),i=new Date(n[0]).getTime();return o-i});return new Map(t)}function bt(r,e){return e.fullObservationField==="narrative"?r.narrative:r.facts?Q(r.facts).join(`
|
|
786
|
+
`):null}function zt(r,e,t,s){let n=[];n.push(...Ve(r));let o="";for(let i of e)if(i.type==="summary"){let a=i.data,d=Ee(a.displayTime);n.push(...ze(a,d))}else{let a=i.data,d=ge(a.created_at),c=d!==o?d:"";if(o=d,t.has(a.id)){let p=bt(a,s);n.push(...Qe(a,c,p,s))}else n.push(Je(a,c,s))}return n}function Zt(r,e,t,s,n){let o=[];o.push(...dt(r));let i=null,a="";for(let d of e)if(d.type==="summary"){i=null,a="";let m=d.data,c=Ee(m.displayTime);o.push(...ct(m,c))}else{let m=d.data,c=St(m.files_modified,n,m.files_read),E=ge(m.created_at),p=E!==a;a=E;let g=t.has(m.id);if(c!==i&&(o.push(..._t(c)),i=c),g){let b=bt(m,s);o.push(...mt(m,E,p,b,s))}else o.push(ut(m,E,p,s))}return o.push(""),o}function es(r,e,t,s,n,o){return o?Zt(r,e,t,s,n):zt(r,e,t,s)}function ht(r,e,t,s,n){let o=[],i=Qt(r);for(let[a,d]of i)o.push(...es(a,d,e,t,s,n));return o}function Ot(r,e,t){return!(!r.showLastSummary||!e||!!!(e.investigated||e.learned||e.completed||e.next_steps)||t&&e.created_at_epoch<=t.created_at_epoch)}function At(r,e){let t=[];return e?(t.push(...$("Investigated",r.investigated,_.blue)),t.push(...$("Learned",r.learned,_.yellow)),t.push(...$("Completed",r.completed,_.green)),t.push(...$("Next Steps",r.next_steps,_.magenta))):(t.push(...F("Investigated",r.investigated)),t.push(...F("Learned",r.learned)),t.push(...F("Completed",r.completed)),t.push(...F("Next Steps",r.next_steps))),t}function Rt(r,e){return e?lt(r):Ze(r)}function Nt(r,e,t){return!Y(e)||r.totalDiscoveryTokens<=0||r.savings<=0?[]:t?pt(r.totalDiscoveryTokens,r.totalReadTokens):et(r.totalDiscoveryTokens,r.totalReadTokens)}var ts=Ct.default.join((0,It.homedir)(),".claude","plugins","marketplaces","thedotmack","plugin",".install-version");function ss(){try{return new B}catch(r){if(r instanceof Error&&r.code==="ERR_DLOPEN_FAILED"){try{(0,Lt.unlinkSync)(ts)}catch(e){e instanceof Error?u.debug("WORKER","Marker file cleanup failed (may not exist)",{},e):u.debug("WORKER","Marker file cleanup failed (may not exist)",{error:String(e)})}return u.error("WORKER","Native module rebuild needed - restart Claude Code to auto-fix"),null}throw r}}function rs(r,e){return e?Et(r):tt(r)}function ns(r,e,t,s,n,o,i){let a=[],d=_e(e);a.push(...gt(r,d,s,i));let m=t.slice(0,s.sessionCount),c=Ge(m,t),E=le(e,c),p=He(e,s.fullObservationCount);a.push(...ht(E,p,s,n,i));let g=t[0],b=e[0];Ot(s,g,b)&&a.push(...At(g,i));let N=ce(e,s,o,n);return a.push(...Rt(N,i)),a.push(...Nt(d,s,i)),a.join(`
|
|
774
787
|
`).trimEnd()}async function Te(r,e=!1){let t=ie(),s=r?.cwd??process.cwd(),n=se(s),o=r?.projects?.length?r.projects:n.allProjects,i=o[o.length-1]??n.primary;r?.full&&(t.totalObservationCount=999999,t.sessionCount=999999);let a=ss();if(!a)return"";try{let d=o.length>1?$e(a,o,t):ue(a,i,t),m=o.length>1?Pe(a,o,t):me(a,i,t);return d.length===0&&m.length===0?rs(i,e):ns(i,d,m,t,s,r?.session_id,e)}finally{a.close()}}0&&(module.exports={generateContext});
|