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