claude-mem 13.9.3 → 13.10.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/README.md +11 -6
- package/dist/npx-cli/index.js +387 -381
- package/dist/opencode-plugin/index.js +11 -8
- package/openclaw/openclaw.plugin.json +1 -1
- package/package.json +2 -1
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/.codex-plugin/plugin.json +1 -1
- package/plugin/hooks/codex-hooks.json +10 -5
- package/plugin/package.json +1 -1
- package/plugin/scripts/bun-runner.js +2 -2
- package/plugin/scripts/context-generator.cjs +131 -124
- package/plugin/scripts/mcp-server.cjs +52 -49
- package/plugin/scripts/server-service.cjs +138 -135
- package/plugin/scripts/transcript-watcher.cjs +17 -14
- package/plugin/scripts/version-check.js +1 -1
- package/plugin/scripts/worker-service.cjs +294 -246
- package/plugin/sqlite/SessionStore.js +764 -0
- package/plugin/sqlite/observations/files.js +10 -0
- package/plugin/ui/viewer-bundle.js +11 -11
- package/plugin/scripts/worker-cli.js +0 -19
|
@@ -1,17 +1,20 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
|
|
1
|
+
"use strict";var Xs=Object.create;var V=Object.defineProperty;var Bs=Object.getOwnPropertyDescriptor;var js=Object.getOwnPropertyNames;var Ws=Object.getPrototypeOf,Vs=Object.prototype.hasOwnProperty;var qs=(r,e)=>{for(var s in e)V(r,s,{get:e[s],enumerable:!0})},Oe=(r,e,s,t)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of js(e))!Vs.call(r,n)&&n!==s&&V(r,n,{get:()=>e[n],enumerable:!(t=Bs(e,n))||t.enumerable});return r};var $=(r,e,s)=>(s=r!=null?Xs(Ws(r)):{},Oe(e||!r||!r.__esModule?V(s,"default",{value:r,enumerable:!0}):s,r)),Ks=r=>Oe(V({},"__esModule",{value:!0}),r);var Mt={};qs(Mt,{generateContext:()=>Gs,generateContextWithStats:()=>Re});module.exports=Ks(Mt);var Fs=$(require("path"),1),$s=require("os"),Hs=require("fs");var me=require("bun:sqlite");var R=require("path"),oe=require("os"),w=require("fs"),he=require("url");var T=require("fs"),be=require("crypto"),v=require("path");var Ys=null;function Js(r){return(Ys??process.stderr.write.bind(process.stderr))(r)}function x(r){Js(r)}var Qs=process.platform==="win32";function zs(r){return r.replace(/^\uFEFF/,"")}function k(r){return JSON.parse(zs(r))}function Zs(r){(0,T.existsSync)(r)||(0,T.mkdirSync)(r,{recursive:!0})}function ne(r,e){let s=r;try{if((0,T.lstatSync)(r).isSymbolicLink())try{s=(0,T.realpathSync)(r)}catch(_){let u=_ instanceof Error?_:new Error(String(_));x(`claude-mem: realpathSync failed for ${r}, resolving symlink manually: ${u.message}
|
|
2
|
+
`);let c=(0,T.readlinkSync)(r);s=(0,v.resolve)((0,v.dirname)(r),c)}}catch(_){let u=_.code;if(u!=="ENOENT"&&u!=="ENOTDIR")throw _}Zs((0,v.dirname)(s));let t=(0,v.dirname)(s),n=(0,v.basename)(s),o=(0,v.join)(t,`.${n}.${process.pid}.${(0,be.randomBytes)(6).toString("hex")}.tmp`),i=Buffer.from(JSON.stringify(e,null,2)+`
|
|
3
|
+
`,"utf-8"),a;try{a=(0,T.statSync)(s).mode&511}catch{}let d;try{d=a!==void 0?(0,T.openSync)(o,"w",a):(0,T.openSync)(o,"w");let _=0;for(;_<i.length;){let u=(0,T.writeSync)(d,i,_,i.length-_);if(u===0)throw new Error(`writeSync stalled at ${_}/${i.length} bytes`);_+=u}if((0,T.fsyncSync)(d),(0,T.closeSync)(d),d=void 0,(0,T.renameSync)(o,s),!Qs){let u;try{u=(0,T.openSync)(t,"r"),(0,T.fsyncSync)(u)}catch(c){let p=c instanceof Error?c:new Error(String(c));x(`claude-mem: directory fsync failed for ${t}: ${p.message}
|
|
4
|
+
`)}finally{if(u!==void 0)try{(0,T.closeSync)(u)}catch{}}}}catch(_){if(d!==void 0)try{(0,T.closeSync)(d)}catch{}try{(0,T.unlinkSync)(o)}catch{}throw _}}var ot={};function et(){return typeof __dirname<"u"?__dirname:(0,R.dirname)((0,he.fileURLToPath)(ot.url))}var st=et();function tt(){if(process.env.CLAUDE_MEM_DATA_DIR)return process.env.CLAUDE_MEM_DATA_DIR;let r=(0,R.join)((0,oe.homedir)(),".claude-mem"),e=(0,R.join)(r,"settings.json");try{if((0,w.existsSync)(e)){let s=k((0,w.readFileSync)(e,"utf-8")),t=s.env??s;if(t.CLAUDE_MEM_DATA_DIR)return t.CLAUDE_MEM_DATA_DIR}}catch{}return r}var A=tt(),ie=process.env.CLAUDE_CONFIG_DIR||(0,R.join)((0,oe.homedir)(),".claude"),Pt=(0,R.join)(ie,"plugins","marketplaces","thedotmack"),rt=(0,R.join)(A,"logs"),Ft=(0,R.join)(A,"settings.json"),Ie=(0,R.join)(A,"claude-mem.db"),nt=(0,R.join)(A,"observer-sessions"),ae=(0,R.basename)(nt);function Ne(r){(0,w.mkdirSync)(r,{recursive:!0})}function Ae(){return(0,R.join)(st,"..")}var H={dataDir:()=>A,workerPid:()=>(0,R.join)(A,"worker.pid"),serverPid:()=>(0,R.join)(A,".server-beta.pid"),serverPort:()=>(0,R.join)(A,".server-beta.port"),serverRuntime:()=>(0,R.join)(A,".server-beta.runtime.json"),settings:()=>(0,R.join)(A,"settings.json"),database:()=>(0,R.join)(A,"claude-mem.db"),chroma:()=>(0,R.join)(A,"chroma"),combinedCerts:()=>(0,R.join)(A,"combined_certs.pem"),transcriptsConfig:()=>(0,R.join)(A,"transcript-watch.json"),transcriptsState:()=>(0,R.join)(A,"transcript-watch-state.json"),corpora:()=>(0,R.join)(A,"corpora"),supervisorRegistry:()=>(0,R.join)(A,"supervisor.json"),envFile:()=>(0,R.join)(A,".env"),logsDir:()=>rt};var y=require("fs"),Ce=require("path");var _e=(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))(_e||{}),de=null,Ee=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=H.logsDir();(0,y.existsSync)(e)||(0,y.mkdirSync)(e,{recursive:!0});let s=new Date().toISOString().split("T")[0];this.logFilePath=(0,Ce.join)(e,`claude-mem-${s}.log`)}catch(e){console.error("[LOGGER] Failed to initialize log file:",e instanceof Error?e.message:String(e)),this.logFilePath=null}}}getLevel(){if(this.level===null)try{let e=H.settings();if((0,y.existsSync)(e)){let s=(0,y.readFileSync)(e,"utf-8"),n=(k(s).CLAUDE_MEM_LOG_LEVEL||"INFO").toUpperCase();this.level=_e[n]??1}else this.level=1}catch(e){console.error("[LOGGER] Failed to load log level from settings:",e instanceof Error?e.message:String(e)),this.level=1}return this.level}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}
|
|
5
|
+
${e.stack}`:e.message;if(Array.isArray(e))return`[${e.length} items]`;let s=Object.keys(e);return s.length===0?"{}":s.length<=3?JSON.stringify(e):`{${s.length} keys: ${s.slice(0,3).join(", ")}...}`}return String(e)}formatTool(e,s){if(!s)return e;let t=s;if(typeof s=="string")try{t=JSON.parse(s)}catch{t=s}if(e==="Bash"&&t.command)return`${e}(${t.command})`;if(t.file_path)return`${e}(${t.file_path})`;if(t.notebook_path)return`${e}(${t.notebook_path})`;if(e==="Glob"&&t.pattern)return`${e}(${t.pattern})`;if(e==="Grep"&&t.pattern)return`${e}(${t.pattern})`;if(t.url)return`${e}(${t.url})`;if(t.query)return`${e}(${t.query})`;if(e==="Task"){if(t.subagent_type)return`${e}(${t.subagent_type})`;if(t.description)return`${e}(${t.description})`}return e==="Skill"&&t.skill?`${e}(${t.skill})`:e==="LSP"&&t.operation?`${e}(${t.operation})`:e}formatTimestamp(e){let s=e.getFullYear(),t=String(e.getMonth()+1).padStart(2,"0"),n=String(e.getDate()).padStart(2,"0"),o=String(e.getHours()).padStart(2,"0"),i=String(e.getMinutes()).padStart(2,"0"),a=String(e.getSeconds()).padStart(2,"0"),d=String(e.getMilliseconds()).padStart(3,"0");return`${s}-${t}-${n} ${o}:${i}:${a}.${d}`}log(e,s,t,n,o){if(e<this.getLevel())return;this.ensureLogFileInitialized();let i=this.formatTimestamp(new Date),a=_e[e].padEnd(5),d=s.padEnd(6),_="";n?.correlationId?_=`[${n.correlationId}] `:n?.sessionId&&(_=`[session-${n.sessionId}] `);let u="";if(o!=null)if(o instanceof Error)u=this.getLevel()===0?`
|
|
3
6
|
${o.message}
|
|
4
|
-
${o.stack}`:` ${o.message}`;else if(this.getLevel()===0&&typeof o=="object")try{
|
|
5
|
-
`+JSON.stringify(o,null,2)}catch{
|
|
6
|
-
`,"utf8")}catch(
|
|
7
|
-
${
|
|
8
|
-
`)}else
|
|
9
|
-
`)}debug(e,s,t,
|
|
7
|
+
${o.stack}`:` ${o.message}`;else if(this.getLevel()===0&&typeof o=="object")try{u=`
|
|
8
|
+
`+JSON.stringify(o,null,2)}catch{u=" "+this.formatData(o)}else u=" "+this.formatData(o);let c="";if(n){let{sessionId:g,memorySessionId:I,correlationId:h,...S}=n;Object.keys(S).length>0&&(c=` {${Object.entries(S).map(([L,U])=>`${L}=${U}`).join(", ")}}`)}let p=`[${i}] [${a}] [${d}] ${_}${t}${c}${u}`;if(this.logFilePath)try{(0,y.appendFileSync)(this.logFilePath,p+`
|
|
9
|
+
`,"utf8")}catch(g){let I=g instanceof Error?g:new Error(String(g));x(`[LOGGER] Failed to write to log file: ${I.message}
|
|
10
|
+
${I.stack??""}
|
|
11
|
+
`)}else x(p+`
|
|
12
|
+
`)}debug(e,s,t,n){this.log(0,e,s,t,n)}info(e,s,t,n){this.log(1,e,s,t,n)}warn(e,s,t,n){this.log(2,e,s,t,n)}setErrorSink(e){de=e}error(e,s,t,n){this.log(3,e,s,t,n),this.routeErrorToSink(s,t,n)}routeErrorToSink(e,s,t){try{if(!de||!(t instanceof Error))return;de(t)}catch{}}dataIn(e,s,t,n){this.info(e,`\u2192 ${s}`,t,n)}dataOut(e,s,t,n){this.info(e,`\u2190 ${s}`,t,n)}success(e,s,t,n){this.info(e,`\u2713 ${s}`,t,n)}failure(e,s,t,n){this.error(e,`\u2717 ${s}`,t,n)}},E=new Ee;var Le=require("crypto");function De(r,e,s){return(0,Le.createHash)("sha256").update([r||"",e||"",s||""].join("\0")).digest("hex").slice(0,16)}var l="claude";function it(r){return r.trim().toLowerCase().replace(/\s+/g,"-")}function C(r){if(!r)return l;let e=it(r);return e?e==="transcript"||e.includes("codex")?"codex":e.includes("cursor")?"cursor":e.includes("claude")?"claude":e:l}function Me(r){let e=["claude","codex","cursor"];return[...r].sort((s,t)=>{let n=e.indexOf(s),o=e.indexOf(t);return n!==-1||o!==-1?n===-1?1:o===-1?-1:n-o:s.localeCompare(t)})}function ve(r,e,s,t,n){let o=Date.now()-t,i=n!==void 0?"up.session_db_id = ?":"up.content_session_id = ?",a=n??e;return r.prepare(`
|
|
10
13
|
SELECT
|
|
11
14
|
up.*,
|
|
12
15
|
s.memory_session_id,
|
|
13
16
|
s.project,
|
|
14
|
-
COALESCE(s.platform_source, '${
|
|
17
|
+
COALESCE(s.platform_source, '${l}') as platform_source
|
|
15
18
|
FROM user_prompts up
|
|
16
19
|
JOIN sdk_sessions s ON up.session_db_id = s.id
|
|
17
20
|
WHERE ${i}
|
|
@@ -19,32 +22,38 @@ ${h.stack??""}
|
|
|
19
22
|
AND up.created_at_epoch >= ?
|
|
20
23
|
ORDER BY up.created_at_epoch DESC
|
|
21
24
|
LIMIT 1
|
|
22
|
-
`).get(a,s,o)??void 0}var
|
|
25
|
+
`).get(a,s,o)??void 0}var xe=["private","claude-mem-context","system_instruction","system-instruction","persisted-output","system-reminder"],ye=new RegExp(`<(${xe.join("|")})\\b[^>]*>[\\s\\S]*?</\\1>`,"g"),ke=/<system-reminder>[\s\S]*?<\/system-reminder>/g,Ue=100;function at(r){let e=Object.fromEntries(xe.map(n=>[n,0]));ye.lastIndex=0;let s=0,t=r.replace(ye,(n,o)=>(e[o]=(e[o]??0)+1,s+=1,""));return s>Ue&&E.warn("SYSTEM","tag count exceeds limit",void 0,{tagCount:s,maxAllowed:Ue,contentLength:r.length}),{stripped:t.trim(),counts:e}}function we(r){return at(r).stripped}var dt=["task-notification"],Yt=new RegExp(`^\\s*<(${dt.join("|")})\\b[^>]*>(?:(?!<\\1\\b|</\\1\\b)[\\s\\S])*</\\1>\\s*$`),Jt=256*1024;var ue=4e3;function q(r){let e=r.trim(),t=we(r).trim()||e;return t.length<=ue?t:(E.debug("DB","Truncated stored prompt text to the configured cap",{originalLength:t.length,storedLength:ue}),`${t.slice(0,ue-1)}\u2026`)}var _t=require("bun:sqlite");var Et=5e3,ut=4194304;function mt(r){return r.prepare(`
|
|
26
|
+
SELECT name
|
|
27
|
+
FROM sqlite_master
|
|
28
|
+
WHERE type = 'table'
|
|
29
|
+
AND name NOT LIKE 'sqlite_%'
|
|
30
|
+
LIMIT 1
|
|
31
|
+
`).get()!=null}function P(r,e,s){try{r.run(e)}catch(t){let n=t instanceof Error?t:new Error(String(t));throw E.warn("DB",`Failed to apply SQLite pragma ${s}`,{sql:e},n),t}}function Pe(r,e={}){let{enableWal:s=!0,enableIncrementalAutoVacuum:t=!0}=e;P(r,`PRAGMA busy_timeout = ${Et}`,"busy_timeout"),P(r,"PRAGMA foreign_keys = ON","foreign_keys"),P(r,"PRAGMA synchronous = NORMAL","synchronous"),P(r,`PRAGMA journal_size_limit = ${ut}`,"journal_size_limit"),t&&!mt(r)&&P(r,"PRAGMA auto_vacuum = INCREMENTAL","auto_vacuum"),s&&P(r,"PRAGMA journal_mode = WAL","journal_mode")}var K=class{db;constructor(e=Ie){e instanceof me.Database?this.db=e:(e!==":memory:"&&Ne(A),this.db=new me.Database(e)),Pe(this.db),this.initializeSchema(),this.ensureWorkerPortColumn(),this.ensurePromptTrackingColumns(),this.removeSessionSummariesUniqueConstraint(),this.addObservationHierarchicalFields(),this.makeObservationsTextNullable(),this.createUserPromptsTable(),this.ensureDiscoveryTokensColumn(),this.createPendingMessagesTable(),this.renameSessionIdColumns(),this.addFailedAtEpochColumn(),this.addOnUpdateCascadeToForeignKeys(),this.addObservationContentHashColumn(),this.addSessionCustomTitleColumn(),this.addSessionPlatformSourceColumn(),this.addObservationModelColumns(),this.ensureMergedIntoProjectColumns(),this.addObservationSubagentColumns(),this.addObservationsUniqueContentHashIndex(),this.addObservationsMetadataColumn(),this.dropDeadPendingMessagesColumns(),this.ensurePendingMessagesToolUseIdColumn(),this.dropWorkerPidColumn(),this.ensureSDKSessionsPlatformContentIdentity(),this.ensureUserPromptsSessionDbId(),this.ensurePendingMessagesSessionToolUniqueIndex()}getIndexColumns(e){return this.db.query(`PRAGMA index_info(${JSON.stringify(e)})`).all().map(s=>s.name)}hasUniqueIndexOnColumns(e,s){return this.db.query(`PRAGMA index_list(${e})`).all().some(n=>{if(n.unique!==1)return!1;let o=this.getIndexColumns(n.name);return o.length===s.length&&o.every((i,a)=>i===s[a])})}resolvePromptSessionDbId(e,s,t){if(s!==void 0)return s;let n=t?C(t):void 0;return n?this.db.prepare(`
|
|
23
32
|
SELECT id
|
|
24
33
|
FROM sdk_sessions
|
|
25
34
|
WHERE COALESCE(NULLIF(platform_source, ''), ?) = ?
|
|
26
35
|
AND content_session_id = ?
|
|
27
36
|
LIMIT 1
|
|
28
|
-
`).get(
|
|
37
|
+
`).get(l,n,e)?.id??null:this.db.prepare(`
|
|
29
38
|
SELECT id
|
|
30
39
|
FROM sdk_sessions
|
|
31
40
|
WHERE content_session_id = ?
|
|
32
|
-
ORDER BY CASE COALESCE(NULLIF(platform_source, ''), '${
|
|
33
|
-
WHEN '${
|
|
41
|
+
ORDER BY CASE COALESCE(NULLIF(platform_source, ''), '${l}')
|
|
42
|
+
WHEN '${l}' THEN 0
|
|
34
43
|
ELSE 1
|
|
35
44
|
END, id
|
|
36
45
|
LIMIT 1
|
|
37
|
-
`).get(e)?.id??null}dropWorkerPidColumn(){let e=this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(32),t=this.db.query("PRAGMA table_info(pending_messages)").all().some(
|
|
46
|
+
`).get(e)?.id??null}dropWorkerPidColumn(){let e=this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(32),t=this.db.query("PRAGMA table_info(pending_messages)").all().some(n=>n.name==="worker_pid");if(!(e&&!t)){if(t)try{this.db.run("DROP INDEX IF EXISTS idx_pending_messages_worker_pid"),this.db.run("ALTER TABLE pending_messages DROP COLUMN worker_pid"),E.debug("DB","Dropped worker_pid column and its index from pending_messages")}catch(n){E.warn("DB","Failed to drop worker_pid column from pending_messages",{},n instanceof Error?n:new Error(String(n)));return}e||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(32,new Date().toISOString())}}ensureSDKSessionsPlatformContentIdentity(){let e=this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(33),s=this.hasUniqueIndexOnColumns("sdk_sessions",["content_session_id"]),t=this.hasUniqueIndexOnColumns("sdk_sessions",["platform_source","content_session_id"]),o=this.db.query("PRAGMA table_info(sdk_sessions)").all().some(i=>i.name==="platform_source");if(!(e&&!s&&t&&o)){if(o||this.db.run(`ALTER TABLE sdk_sessions ADD COLUMN platform_source TEXT NOT NULL DEFAULT '${l}'`),this.db.run(`
|
|
38
47
|
UPDATE sdk_sessions
|
|
39
|
-
SET platform_source = '${
|
|
48
|
+
SET platform_source = '${l}'
|
|
40
49
|
WHERE platform_source IS NULL OR platform_source = ''
|
|
41
|
-
`),s){this.db.run("PRAGMA foreign_keys = OFF"),this.db.run("BEGIN TRANSACTION");try{this.rebuildSdkSessionsWithCompositeIdentity(e),this.db.run("COMMIT")}catch(i){this.db.run("ROLLBACK");let a=i instanceof Error?i:new Error(String(i));throw
|
|
50
|
+
`),s){this.db.run("PRAGMA foreign_keys = OFF"),this.db.run("BEGIN TRANSACTION");try{this.rebuildSdkSessionsWithCompositeIdentity(e),this.db.run("COMMIT")}catch(i){this.db.run("ROLLBACK");let a=i instanceof Error?i:new Error(String(i));throw E.error("DB","Failed to rebuild sdk_sessions with composite identity, rolled back",{},a),i}finally{this.db.run("PRAGMA foreign_keys = ON")}return}this.db.run("CREATE UNIQUE INDEX IF NOT EXISTS ux_sdk_sessions_platform_content ON sdk_sessions(platform_source, content_session_id)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_platform_source ON sdk_sessions(platform_source)"),e||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(33,new Date().toISOString())}}rebuildSdkSessionsWithCompositeIdentity(e){this.db.run("DROP TABLE IF EXISTS sdk_sessions_new"),this.db.run(`
|
|
42
51
|
CREATE TABLE sdk_sessions_new (
|
|
43
52
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
44
53
|
content_session_id TEXT NOT NULL,
|
|
45
54
|
memory_session_id TEXT UNIQUE,
|
|
46
55
|
project TEXT NOT NULL,
|
|
47
|
-
platform_source TEXT NOT NULL DEFAULT '${
|
|
56
|
+
platform_source TEXT NOT NULL DEFAULT '${l}',
|
|
48
57
|
user_prompt TEXT,
|
|
49
58
|
started_at TEXT NOT NULL,
|
|
50
59
|
started_at_epoch INTEGER NOT NULL,
|
|
@@ -63,27 +72,27 @@ ${h.stack??""}
|
|
|
63
72
|
)
|
|
64
73
|
SELECT
|
|
65
74
|
id, content_session_id, memory_session_id, project,
|
|
66
|
-
COALESCE(NULLIF(platform_source, ''), '${
|
|
75
|
+
COALESCE(NULLIF(platform_source, ''), '${l}'),
|
|
67
76
|
user_prompt, started_at, started_at_epoch, completed_at, completed_at_epoch,
|
|
68
77
|
status, worker_port, prompt_counter, custom_title
|
|
69
78
|
FROM sdk_sessions
|
|
70
|
-
`),this.db.run("DROP TABLE sdk_sessions"),this.db.run("ALTER TABLE sdk_sessions_new RENAME TO sdk_sessions"),this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_claude_id ON sdk_sessions(content_session_id)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_sdk_id ON sdk_sessions(memory_session_id)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_project ON sdk_sessions(project)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_status ON sdk_sessions(status)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_started ON sdk_sessions(started_at_epoch DESC)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_platform_source ON sdk_sessions(platform_source)"),this.db.run("CREATE UNIQUE INDEX IF NOT EXISTS ux_sdk_sessions_platform_content ON sdk_sessions(platform_source, content_session_id)"),e||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(33,new Date().toISOString())}ensureUserPromptsSessionDbId(){let e=this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(34);if(this.db.query("SELECT name FROM sqlite_master WHERE type='table' AND name='user_prompts'").all().length===0){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(34,new Date().toISOString());return}let
|
|
79
|
+
`),this.db.run("DROP TABLE sdk_sessions"),this.db.run("ALTER TABLE sdk_sessions_new RENAME TO sdk_sessions"),this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_claude_id ON sdk_sessions(content_session_id)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_sdk_id ON sdk_sessions(memory_session_id)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_project ON sdk_sessions(project)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_status ON sdk_sessions(status)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_started ON sdk_sessions(started_at_epoch DESC)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_platform_source ON sdk_sessions(platform_source)"),this.db.run("CREATE UNIQUE INDEX IF NOT EXISTS ux_sdk_sessions_platform_content ON sdk_sessions(platform_source, content_session_id)"),e||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(33,new Date().toISOString())}ensureUserPromptsSessionDbId(){let e=this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(34);if(this.db.query("SELECT name FROM sqlite_master WHERE type='table' AND name='user_prompts'").all().length===0){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(34,new Date().toISOString());return}let n=this.db.query("PRAGMA table_info(user_prompts)").all().some(_=>_.name==="session_db_id"),i=this.db.query("PRAGMA foreign_key_list(user_prompts)").all().some(_=>_.table==="sdk_sessions"&&_.from==="content_session_id");if(e&&n&&!i)return;let a=this.db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='user_prompts_fts'").all().length>0,d=n?`COALESCE(up.session_db_id, (
|
|
71
80
|
SELECT s.id FROM sdk_sessions s
|
|
72
81
|
WHERE s.content_session_id = up.content_session_id
|
|
73
|
-
ORDER BY CASE COALESCE(NULLIF(s.platform_source, ''), '${
|
|
74
|
-
WHEN '${
|
|
82
|
+
ORDER BY CASE COALESCE(NULLIF(s.platform_source, ''), '${l}')
|
|
83
|
+
WHEN '${l}' THEN 0
|
|
75
84
|
ELSE 1
|
|
76
85
|
END, s.id
|
|
77
86
|
LIMIT 1
|
|
78
87
|
))`:`(
|
|
79
88
|
SELECT s.id FROM sdk_sessions s
|
|
80
89
|
WHERE s.content_session_id = up.content_session_id
|
|
81
|
-
ORDER BY CASE COALESCE(NULLIF(s.platform_source, ''), '${
|
|
82
|
-
WHEN '${
|
|
90
|
+
ORDER BY CASE COALESCE(NULLIF(s.platform_source, ''), '${l}')
|
|
91
|
+
WHEN '${l}' THEN 0
|
|
83
92
|
ELSE 1
|
|
84
93
|
END, s.id
|
|
85
94
|
LIMIT 1
|
|
86
|
-
)`;this.db.run("PRAGMA foreign_keys = OFF"),this.db.run("BEGIN TRANSACTION");try{this.rebuildUserPromptsWithSessionDbId(e,d,a),this.db.run("COMMIT")}catch(
|
|
95
|
+
)`;this.db.run("PRAGMA foreign_keys = OFF"),this.db.run("BEGIN TRANSACTION");try{this.rebuildUserPromptsWithSessionDbId(e,d,a),this.db.run("COMMIT")}catch(_){this.db.run("ROLLBACK");let u=_ instanceof Error?_:new Error(String(_));throw E.error("DB","Failed to rebuild user_prompts with session_db_id, rolled back",{},u),_}finally{this.db.run("PRAGMA foreign_keys = ON")}}rebuildUserPromptsWithSessionDbId(e,s,t){this.db.run("DROP TRIGGER IF EXISTS user_prompts_ai"),this.db.run("DROP TRIGGER IF EXISTS user_prompts_ad"),this.db.run("DROP TRIGGER IF EXISTS user_prompts_au"),this.db.run("DROP TABLE IF EXISTS user_prompts_new"),this.db.run(`
|
|
87
96
|
CREATE TABLE user_prompts_new (
|
|
88
97
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
89
98
|
session_db_id INTEGER,
|
|
@@ -125,7 +134,7 @@ ${h.stack??""}
|
|
|
125
134
|
INSERT INTO user_prompts_fts(rowid, prompt_text)
|
|
126
135
|
VALUES (new.id, new.prompt_text);
|
|
127
136
|
END;
|
|
128
|
-
`),this.db.run("INSERT INTO user_prompts_fts(user_prompts_fts) VALUES('rebuild')")),e||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(34,new Date().toISOString())}ensurePendingMessagesSessionToolUniqueIndex(){let e=this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(35);if(this.db.query("SELECT name FROM sqlite_master WHERE type='table' AND name='pending_messages'").all().length===0){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(35,new Date().toISOString());return}let t=this.hasUniqueIndexOnColumns("pending_messages",["session_db_id","tool_use_id"]);if(!(e&&t)){this.db.run("BEGIN TRANSACTION");try{this.recreatePendingSessionToolUniqueIndex(e),this.db.run("COMMIT")}catch(
|
|
137
|
+
`),this.db.run("INSERT INTO user_prompts_fts(user_prompts_fts) VALUES('rebuild')")),e||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(34,new Date().toISOString())}ensurePendingMessagesSessionToolUniqueIndex(){let e=this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(35);if(this.db.query("SELECT name FROM sqlite_master WHERE type='table' AND name='pending_messages'").all().length===0){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(35,new Date().toISOString());return}let t=this.hasUniqueIndexOnColumns("pending_messages",["session_db_id","tool_use_id"]);if(!(e&&t)){this.db.run("BEGIN TRANSACTION");try{this.recreatePendingSessionToolUniqueIndex(e),this.db.run("COMMIT")}catch(n){this.db.run("ROLLBACK");let o=n instanceof Error?n:new Error(String(n));throw E.error("DB","Failed to recreate ux_pending_session_tool index, rolled back",{},o),n}}}recreatePendingSessionToolUniqueIndex(e){this.db.run("DROP INDEX IF EXISTS ux_pending_session_tool"),this.db.run(`
|
|
129
138
|
DELETE FROM pending_messages
|
|
130
139
|
WHERE id IN (
|
|
131
140
|
SELECT id
|
|
@@ -148,7 +157,7 @@ ${h.stack??""}
|
|
|
148
157
|
CREATE UNIQUE INDEX IF NOT EXISTS ux_pending_session_tool
|
|
149
158
|
ON pending_messages(session_db_id, tool_use_id)
|
|
150
159
|
WHERE tool_use_id IS NOT NULL
|
|
151
|
-
`),e||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(35,new Date().toISOString())}dropDeadPendingMessagesColumns(){let e=this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(31),s=this.db.query("PRAGMA table_info(pending_messages)").all(),t=new Set(s.map(i=>i.name)),o=["retry_count","failed_at_epoch","completed_at_epoch"].filter(i=>t.has(i));if(!(e&&o.length===0)){if(o.length>0){this.db.run("BEGIN TRANSACTION");try{this.db.run("DELETE FROM pending_messages WHERE status NOT IN ('pending', 'processing')");for(let i of o)this.db.run(`ALTER TABLE pending_messages DROP COLUMN ${i}`),
|
|
160
|
+
`),e||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(35,new Date().toISOString())}dropDeadPendingMessagesColumns(){let e=this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(31),s=this.db.query("PRAGMA table_info(pending_messages)").all(),t=new Set(s.map(i=>i.name)),o=["retry_count","failed_at_epoch","completed_at_epoch"].filter(i=>t.has(i));if(!(e&&o.length===0)){if(o.length>0){this.db.run("BEGIN TRANSACTION");try{this.db.run("DELETE FROM pending_messages WHERE status NOT IN ('pending', 'processing')");for(let i of o)this.db.run(`ALTER TABLE pending_messages DROP COLUMN ${i}`),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(`
|
|
152
161
|
CREATE TABLE IF NOT EXISTS schema_versions (
|
|
153
162
|
id INTEGER PRIMARY KEY,
|
|
154
163
|
version INTEGER UNIQUE NOT NULL,
|
|
@@ -174,8 +183,6 @@ ${h.stack??""}
|
|
|
174
183
|
CREATE INDEX IF NOT EXISTS idx_sdk_sessions_project ON sdk_sessions(project);
|
|
175
184
|
CREATE INDEX IF NOT EXISTS idx_sdk_sessions_status ON sdk_sessions(status);
|
|
176
185
|
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);
|
|
179
186
|
|
|
180
187
|
CREATE TABLE IF NOT EXISTS observations (
|
|
181
188
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
@@ -213,7 +220,7 @@ ${h.stack??""}
|
|
|
213
220
|
CREATE INDEX IF NOT EXISTS idx_session_summaries_sdk_session ON session_summaries(memory_session_id);
|
|
214
221
|
CREATE INDEX IF NOT EXISTS idx_session_summaries_project ON session_summaries(project);
|
|
215
222
|
CREATE INDEX IF NOT EXISTS idx_session_summaries_created ON session_summaries(created_at_epoch DESC);
|
|
216
|
-
`),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(4,new Date().toISOString())}ensureWorkerPortColumn(){this.db.query("PRAGMA table_info(sdk_sessions)").all().some(t=>t.name==="worker_port")||(this.db.run("ALTER TABLE sdk_sessions ADD COLUMN worker_port INTEGER"),
|
|
223
|
+
`),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(4,new Date().toISOString())}ensureWorkerPortColumn(){this.db.query("PRAGMA table_info(sdk_sessions)").all().some(t=>t.name==="worker_port")||(this.db.run("ALTER TABLE sdk_sessions ADD COLUMN worker_port INTEGER"),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(t=>t.unique===1&&t.origin!=="pk")){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(7,new Date().toISOString());return}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(`
|
|
217
224
|
CREATE TABLE session_summaries_new (
|
|
218
225
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
219
226
|
memory_session_id TEXT NOT NULL,
|
|
@@ -241,7 +248,7 @@ ${h.stack??""}
|
|
|
241
248
|
CREATE INDEX idx_session_summaries_sdk_session ON session_summaries(memory_session_id);
|
|
242
249
|
CREATE INDEX idx_session_summaries_project ON session_summaries(project);
|
|
243
250
|
CREATE INDEX idx_session_summaries_created ON session_summaries(created_at_epoch DESC);
|
|
244
|
-
`),this.db.run("COMMIT"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(7,new Date().toISOString()),
|
|
251
|
+
`),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(n=>n.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(`
|
|
245
252
|
ALTER TABLE observations ADD COLUMN title TEXT;
|
|
246
253
|
ALTER TABLE observations ADD COLUMN subtitle TEXT;
|
|
247
254
|
ALTER TABLE observations ADD COLUMN facts TEXT;
|
|
@@ -249,7 +256,7 @@ ${h.stack??""}
|
|
|
249
256
|
ALTER TABLE observations ADD COLUMN concepts TEXT;
|
|
250
257
|
ALTER TABLE observations ADD COLUMN files_read TEXT;
|
|
251
258
|
ALTER TABLE observations ADD COLUMN files_modified TEXT;
|
|
252
|
-
`),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(8,new Date().toISOString()),
|
|
259
|
+
`),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 t=this.db.query("PRAGMA table_info(observations)").all().find(n=>n.name==="text");if(!t||t.notnull===0){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(9,new Date().toISOString());return}E.debug("DB","Making observations.text nullable"),this.db.run("BEGIN TRANSACTION"),this.db.run("DROP TABLE IF EXISTS observations_new"),this.db.run(`
|
|
253
260
|
CREATE TABLE observations_new (
|
|
254
261
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
255
262
|
memory_session_id TEXT NOT NULL,
|
|
@@ -279,7 +286,7 @@ ${h.stack??""}
|
|
|
279
286
|
CREATE INDEX idx_observations_project ON observations(project);
|
|
280
287
|
CREATE INDEX idx_observations_type ON observations(type);
|
|
281
288
|
CREATE INDEX idx_observations_created ON observations(created_at_epoch DESC);
|
|
282
|
-
`),this.db.run("COMMIT"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(9,new Date().toISOString()),
|
|
289
|
+
`),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(`
|
|
283
290
|
CREATE TABLE user_prompts (
|
|
284
291
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
285
292
|
session_db_id INTEGER,
|
|
@@ -303,7 +310,7 @@ ${h.stack??""}
|
|
|
303
310
|
content='user_prompts',
|
|
304
311
|
content_rowid='id'
|
|
305
312
|
);
|
|
306
|
-
`,
|
|
313
|
+
`,n=`
|
|
307
314
|
CREATE TRIGGER user_prompts_ai AFTER INSERT ON user_prompts BEGIN
|
|
308
315
|
INSERT INTO user_prompts_fts(rowid, prompt_text)
|
|
309
316
|
VALUES (new.id, new.prompt_text);
|
|
@@ -320,7 +327,7 @@ ${h.stack??""}
|
|
|
320
327
|
INSERT INTO user_prompts_fts(rowid, prompt_text)
|
|
321
328
|
VALUES (new.id, new.prompt_text);
|
|
322
329
|
END;
|
|
323
|
-
`;try{this.db.run(t),this.db.run(
|
|
330
|
+
`;try{this.db.run(t),this.db.run(n)}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(`
|
|
324
331
|
CREATE TABLE pending_messages (
|
|
325
332
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
326
333
|
session_db_id INTEGER NOT NULL,
|
|
@@ -337,9 +344,9 @@ ${h.stack??""}
|
|
|
337
344
|
created_at_epoch INTEGER NOT NULL,
|
|
338
345
|
FOREIGN KEY (session_db_id) REFERENCES sdk_sessions(id) ON DELETE CASCADE
|
|
339
346
|
)
|
|
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()),
|
|
341
|
-
metadata TEXT`:"",i=t?", metadata":"",a=
|
|
342
|
-
content_hash TEXT`:"",d=
|
|
347
|
+
`),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 s=0,t=(n,o,i)=>{let a=this.db.query(`PRAGMA table_info(${n})`).all(),d=a.some(u=>u.name===o);return a.some(u=>u.name===i)?!1:d?(this.db.run(`ALTER TABLE ${n} RENAME COLUMN ${o} TO ${i}`),E.debug("DB",`Renamed ${n}.${o} to ${i}`),!0):(E.warn("DB",`Column ${o} not found in ${n}, skipping rename`),!1)};t("sdk_sessions","claude_session_id","content_session_id")&&s++,t("sdk_sessions","sdk_session_id","memory_session_id")&&s++,t("pending_messages","claude_session_id","content_session_id")&&s++,t("observations","sdk_session_id","memory_session_id")&&s++,t("session_summaries","sdk_session_id","memory_session_id")&&s++,t("user_prompts","claude_session_id","content_session_id")&&s++,this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(17,new Date().toISOString()),s>0?E.debug("DB",`Successfully renamed ${s} session ID columns`):E.debug("DB","No session ID column renames needed (already up to date)")}addFailedAtEpochColumn(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(20))return;this.db.query("PRAGMA table_info(pending_messages)").all().some(n=>n.name==="failed_at_epoch")||(this.db.run("ALTER TABLE pending_messages ADD COLUMN failed_at_epoch INTEGER"),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 s=this.db.query("PRAGMA table_info(observations)").all(),t=s.some(f=>f.name==="metadata"),n=s.some(f=>f.name==="content_hash"),o=t?`,
|
|
348
|
+
metadata TEXT`:"",i=t?", metadata":"",a=n?`,
|
|
349
|
+
content_hash TEXT`:"",d=n?", content_hash":"",_=`
|
|
343
350
|
CREATE TABLE observations_new (
|
|
344
351
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
345
352
|
memory_session_id TEXT NOT NULL,
|
|
@@ -359,18 +366,18 @@ ${h.stack??""}
|
|
|
359
366
|
created_at_epoch INTEGER NOT NULL${o}${a},
|
|
360
367
|
FOREIGN KEY(memory_session_id) REFERENCES sdk_sessions(memory_session_id) ON DELETE CASCADE ON UPDATE CASCADE
|
|
361
368
|
)
|
|
362
|
-
`,
|
|
369
|
+
`,u=`
|
|
363
370
|
INSERT INTO observations_new
|
|
364
371
|
SELECT id, memory_session_id, project, text, type, title, subtitle, facts,
|
|
365
372
|
narrative, concepts, files_read, files_modified, prompt_number,
|
|
366
373
|
discovery_tokens, created_at, created_at_epoch${i}${d}
|
|
367
374
|
FROM observations
|
|
368
|
-
`,
|
|
375
|
+
`,c=`
|
|
369
376
|
CREATE INDEX idx_observations_sdk_session ON observations(memory_session_id);
|
|
370
377
|
CREATE INDEX idx_observations_project ON observations(project);
|
|
371
378
|
CREATE INDEX idx_observations_type ON observations(type);
|
|
372
379
|
CREATE INDEX idx_observations_created ON observations(created_at_epoch DESC);
|
|
373
|
-
`,
|
|
380
|
+
`,p=`
|
|
374
381
|
CREATE TRIGGER IF NOT EXISTS observations_ai AFTER INSERT ON observations BEGIN
|
|
375
382
|
INSERT INTO observations_fts(rowid, title, subtitle, narrative, text, facts, concepts)
|
|
376
383
|
VALUES (new.id, new.title, new.subtitle, new.narrative, new.text, new.facts, new.concepts);
|
|
@@ -387,7 +394,7 @@ ${h.stack??""}
|
|
|
387
394
|
INSERT INTO observations_fts(rowid, title, subtitle, narrative, text, facts, concepts)
|
|
388
395
|
VALUES (new.id, new.title, new.subtitle, new.narrative, new.text, new.facts, new.concepts);
|
|
389
396
|
END;
|
|
390
|
-
`;this.db.run("DROP TRIGGER IF EXISTS session_summaries_ai"),this.db.run("DROP TRIGGER IF EXISTS session_summaries_ad"),this.db.run("DROP TRIGGER IF EXISTS session_summaries_au"),this.db.run("DROP TABLE IF EXISTS session_summaries_new");let
|
|
397
|
+
`;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=`
|
|
391
398
|
CREATE TABLE session_summaries_new (
|
|
392
399
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
393
400
|
memory_session_id TEXT NOT NULL,
|
|
@@ -406,17 +413,17 @@ ${h.stack??""}
|
|
|
406
413
|
created_at_epoch INTEGER NOT NULL,
|
|
407
414
|
FOREIGN KEY(memory_session_id) REFERENCES sdk_sessions(memory_session_id) ON DELETE CASCADE ON UPDATE CASCADE
|
|
408
415
|
)
|
|
409
|
-
`,
|
|
416
|
+
`,I=`
|
|
410
417
|
INSERT INTO session_summaries_new
|
|
411
418
|
SELECT id, memory_session_id, project, request, investigated, learned,
|
|
412
419
|
completed, next_steps, files_read, files_edited, notes,
|
|
413
420
|
prompt_number, discovery_tokens, created_at, created_at_epoch
|
|
414
421
|
FROM session_summaries
|
|
415
|
-
`,
|
|
422
|
+
`,h=`
|
|
416
423
|
CREATE INDEX idx_session_summaries_sdk_session ON session_summaries(memory_session_id);
|
|
417
424
|
CREATE INDEX idx_session_summaries_project ON session_summaries(project);
|
|
418
425
|
CREATE INDEX idx_session_summaries_created ON session_summaries(created_at_epoch DESC);
|
|
419
|
-
`,
|
|
426
|
+
`,S=`
|
|
420
427
|
CREATE TRIGGER IF NOT EXISTS session_summaries_ai AFTER INSERT ON session_summaries BEGIN
|
|
421
428
|
INSERT INTO session_summaries_fts(rowid, request, investigated, learned, completed, next_steps, notes)
|
|
422
429
|
VALUES (new.id, new.request, new.investigated, new.learned, new.completed, new.next_steps, new.notes);
|
|
@@ -433,11 +440,11 @@ ${h.stack??""}
|
|
|
433
440
|
INSERT INTO session_summaries_fts(rowid, request, investigated, learned, completed, next_steps, notes)
|
|
434
441
|
VALUES (new.id, new.request, new.investigated, new.learned, new.completed, new.next_steps, new.notes);
|
|
435
442
|
END;
|
|
436
|
-
`;try{this.recreateObservationsWithCascade(u,
|
|
443
|
+
`;try{this.recreateObservationsWithCascade(_,u,c,p),this.recreateSessionSummariesWithCascade(g,I,h,S),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(f){throw this.db.run("ROLLBACK"),this.db.run("PRAGMA foreign_keys = ON"),f instanceof Error?f:new Error(String(f))}}recreateObservationsWithCascade(e,s,t,n){this.db.run(e),this.db.run(s),this.db.run("DROP TABLE observations"),this.db.run("ALTER TABLE observations_new RENAME TO observations"),this.db.run(t),this.db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='observations_fts'").all().length>0&&this.db.run(n)}recreateSessionSummariesWithCascade(e,s,t,n){this.db.run(e),this.db.run(s),this.db.run("DROP TABLE session_summaries"),this.db.run("ALTER TABLE session_summaries_new RENAME TO session_summaries"),this.db.run(t),this.db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='session_summaries_fts'").all().length>0&&this.db.run(n)}addObservationContentHashColumn(){if(this.db.query("PRAGMA table_info(observations)").all().some(t=>t.name==="content_hash")){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(22,new Date().toISOString());return}this.db.run("ALTER TABLE observations ADD COLUMN content_hash TEXT"),this.db.run("UPDATE observations SET content_hash = substr(hex(randomblob(8)), 1, 16) WHERE content_hash IS NULL"),this.db.run("CREATE INDEX IF NOT EXISTS idx_observations_content_hash ON observations(content_hash, created_at_epoch)"),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(){let e=this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(23),t=this.db.query("PRAGMA table_info(sdk_sessions)").all().some(n=>n.name==="custom_title");e&&t||(t||(this.db.run("ALTER TABLE sdk_sessions ADD COLUMN custom_title TEXT"),E.debug("DB","Added custom_title column to sdk_sessions table")),e||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(23,new Date().toISOString()))}addSessionPlatformSourceColumn(){let s=this.db.query("PRAGMA table_info(sdk_sessions)").all().some(i=>i.name==="platform_source"),n=this.db.query("PRAGMA index_list(sdk_sessions)").all().some(i=>i.name==="idx_sdk_sessions_platform_source");this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(24)&&s&&n||(s||(this.db.run(`ALTER TABLE sdk_sessions ADD COLUMN platform_source TEXT NOT NULL DEFAULT '${l}'`),E.debug("DB","Added platform_source column to sdk_sessions table")),this.db.run(`
|
|
437
444
|
UPDATE sdk_sessions
|
|
438
|
-
SET platform_source = '${
|
|
445
|
+
SET platform_source = '${l}'
|
|
439
446
|
WHERE platform_source IS NULL OR platform_source = ''
|
|
440
|
-
`),
|
|
447
|
+
`),n||this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_platform_source ON sdk_sessions(platform_source)"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(24,new Date().toISOString()))}addObservationModelColumns(){let e=this.db.query("PRAGMA table_info(observations)").all(),s=e.some(n=>n.name==="generated_by_model"),t=e.some(n=>n.name==="relevance_count");s&&t||(s||this.db.run("ALTER TABLE observations ADD COLUMN generated_by_model TEXT"),t||this.db.run("ALTER TABLE observations ADD COLUMN relevance_count INTEGER DEFAULT 0"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(26,new Date().toISOString()))}ensureMergedIntoProjectColumns(){this.db.query("PRAGMA table_info(observations)").all().some(t=>t.name==="merged_into_project")||this.db.run("ALTER TABLE observations ADD COLUMN merged_into_project TEXT"),this.db.run("CREATE INDEX IF NOT EXISTS idx_observations_merged_into ON observations(merged_into_project)"),this.db.query("PRAGMA table_info(session_summaries)").all().some(t=>t.name==="merged_into_project")||this.db.run("ALTER TABLE session_summaries ADD COLUMN merged_into_project TEXT"),this.db.run("CREATE INDEX IF NOT EXISTS idx_summaries_merged_into ON session_summaries(merged_into_project)")}addObservationSubagentColumns(){let e=this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(27),s=this.db.query("PRAGMA table_info(observations)").all(),t=s.some(i=>i.name==="agent_type"),n=s.some(i=>i.name==="agent_id");t||this.db.run("ALTER TABLE observations ADD COLUMN agent_type TEXT"),n||this.db.run("ALTER TABLE observations ADD COLUMN agent_id TEXT"),this.db.run("CREATE INDEX IF NOT EXISTS idx_observations_agent_type ON observations(agent_type)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_observations_agent_id ON observations(agent_id)");let o=this.db.query("PRAGMA table_info(pending_messages)").all();if(o.length>0){let i=o.some(d=>d.name==="agent_type"),a=o.some(d=>d.name==="agent_id");i||this.db.run("ALTER TABLE pending_messages ADD COLUMN agent_type TEXT"),a||this.db.run("ALTER TABLE pending_messages ADD COLUMN agent_id TEXT")}e||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(27,new Date().toISOString())}ensurePendingMessagesToolUseIdColumn(){if(this.db.query("SELECT name FROM sqlite_master WHERE type='table' AND name='pending_messages'").all().length===0){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(28,new Date().toISOString());return}this.db.query("PRAGMA table_info(pending_messages)").all().some(n=>n.name==="tool_use_id")||this.db.run("ALTER TABLE pending_messages ADD COLUMN tool_use_id TEXT"),this.db.run("BEGIN TRANSACTION");try{this.dedupePendingMessagesByToolUseId(),this.db.run("COMMIT")}catch(n){this.db.run("ROLLBACK");let o=n instanceof Error?n:new Error(String(n));throw E.error("DB","Failed to de-dupe pending_messages by tool_use_id, rolled back",{},o),n}}dedupePendingMessagesByToolUseId(){this.db.run(`
|
|
441
448
|
DELETE FROM pending_messages
|
|
442
449
|
WHERE id IN (
|
|
443
450
|
SELECT id
|
|
@@ -462,7 +469,7 @@ ${h.stack??""}
|
|
|
462
469
|
CREATE UNIQUE INDEX IF NOT EXISTS ux_pending_session_tool
|
|
463
470
|
ON pending_messages(session_db_id, tool_use_id)
|
|
464
471
|
WHERE tool_use_id IS NOT NULL
|
|
465
|
-
`),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(28,new Date().toISOString())}addObservationsUniqueContentHashIndex(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(29))return;let s=this.db.query("PRAGMA table_info(observations)").all(),t=s.some(o=>o.name==="memory_session_id"),
|
|
472
|
+
`),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(28,new Date().toISOString())}addObservationsUniqueContentHashIndex(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(29))return;let s=this.db.query("PRAGMA table_info(observations)").all(),t=s.some(o=>o.name==="memory_session_id"),n=s.some(o=>o.name==="content_hash");if(!t||!n){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(29,new Date().toISOString());return}this.db.run("BEGIN TRANSACTION");try{this.dedupeObservationsByContentHash(),this.db.run("COMMIT")}catch(o){this.db.run("ROLLBACK");let i=o instanceof Error?o:new Error(String(o));throw E.error("DB","Failed to de-dupe observations by content_hash, rolled back",{},i),o}}dedupeObservationsByContentHash(){this.db.run(`
|
|
466
473
|
UPDATE observations
|
|
467
474
|
SET content_hash = '__null_migration_' || id || '__'
|
|
468
475
|
WHERE content_hash IS NULL
|
|
@@ -483,7 +490,7 @@ ${h.stack??""}
|
|
|
483
490
|
`),this.db.run(`
|
|
484
491
|
CREATE UNIQUE INDEX IF NOT EXISTS ux_observations_session_hash
|
|
485
492
|
ON observations(memory_session_id, content_hash)
|
|
486
|
-
`),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(29,new Date().toISOString())}addObservationsMetadataColumn(){this.db.query("PRAGMA table_info(observations)").all().some(t=>t.name==="metadata")||(this.db.run("ALTER TABLE observations ADD COLUMN metadata TEXT"),
|
|
493
|
+
`),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(29,new Date().toISOString())}addObservationsMetadataColumn(){this.db.query("PRAGMA table_info(observations)").all().some(t=>t.name==="metadata")||(this.db.run("ALTER TABLE observations ADD COLUMN metadata TEXT"),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,s){this.db.prepare(`
|
|
487
494
|
UPDATE sdk_sessions
|
|
488
495
|
SET memory_session_id = ?
|
|
489
496
|
WHERE id = ?
|
|
@@ -491,39 +498,39 @@ ${h.stack??""}
|
|
|
491
498
|
UPDATE sdk_sessions
|
|
492
499
|
SET status = 'completed', completed_at = ?, completed_at_epoch = ?
|
|
493
500
|
WHERE id = ?
|
|
494
|
-
`).run(t,s,e)}ensureMemorySessionIdRegistered(e,s,t){let
|
|
501
|
+
`).run(t,s,e)}ensureMemorySessionIdRegistered(e,s,t){let n=this.db.prepare(`
|
|
495
502
|
SELECT id, memory_session_id, worker_port FROM sdk_sessions WHERE id = ?
|
|
496
|
-
`).get(e);if(!
|
|
503
|
+
`).get(e);if(!n)throw new Error(`Session ${e} not found in sdk_sessions`);n.memory_session_id!==s&&(this.db.prepare(`
|
|
497
504
|
UPDATE sdk_sessions SET memory_session_id = ? WHERE id = ?
|
|
498
|
-
`).run(s,e),
|
|
505
|
+
`).run(s,e),E.info("DB","Registered memory_session_id before storage (FK fix)",{sessionDbId:e,oldId:n.memory_session_id,newId:s})),typeof t=="number"&&n.worker_port!==t&&this.db.prepare(`
|
|
499
506
|
UPDATE sdk_sessions SET worker_port = ? WHERE id = ?
|
|
500
|
-
`).run(t,e)}getAllProjects(e){let s=e?
|
|
507
|
+
`).run(t,e)}getAllProjects(e){let s=e?C(e):void 0,t=`
|
|
501
508
|
SELECT DISTINCT project
|
|
502
509
|
FROM sdk_sessions
|
|
503
510
|
WHERE project IS NOT NULL AND project != ''
|
|
504
511
|
AND project != ?
|
|
505
|
-
`,
|
|
512
|
+
`,n=[ae];return s&&(t+=" AND COALESCE(platform_source, ?) = ?",n.push(l,s)),t+=" ORDER BY project ASC",this.db.prepare(t).all(...n).map(i=>i.project)}getProjectCatalog(){let e=this.db.prepare(`
|
|
506
513
|
SELECT
|
|
507
|
-
COALESCE(platform_source, '${
|
|
514
|
+
COALESCE(platform_source, '${l}') as platform_source,
|
|
508
515
|
project,
|
|
509
516
|
MAX(started_at_epoch) as latest_epoch
|
|
510
517
|
FROM sdk_sessions
|
|
511
518
|
WHERE project IS NOT NULL AND project != ''
|
|
512
519
|
AND project != ?
|
|
513
|
-
GROUP BY COALESCE(platform_source, '${
|
|
520
|
+
GROUP BY COALESCE(platform_source, '${l}'), project
|
|
514
521
|
ORDER BY latest_epoch DESC
|
|
515
|
-
`).all(
|
|
522
|
+
`).all(ae),s=[],t=new Set,n={};for(let i of e){let a=C(i.platform_source);n[a]||(n[a]=[]),n[a].includes(i.project)||n[a].push(i.project),t.has(i.project)||(t.add(i.project),s.push(i.project))}let o=Me(Object.keys(n));return{projects:s,sources:o,projectsBySource:Object.fromEntries(o.map(i=>[i,n[i]||[]]))}}getLatestUserPrompt(e,s){let t=this.resolvePromptSessionDbId(e,s),n=t!==null?"up.session_db_id = ?":"up.content_session_id = ?",o=t!==null?t:e;return this.db.prepare(`
|
|
516
523
|
SELECT
|
|
517
524
|
up.*,
|
|
518
525
|
s.memory_session_id,
|
|
519
526
|
s.project,
|
|
520
|
-
COALESCE(s.platform_source, '${
|
|
527
|
+
COALESCE(s.platform_source, '${l}') as platform_source
|
|
521
528
|
FROM user_prompts up
|
|
522
529
|
JOIN sdk_sessions s ON up.session_db_id = s.id
|
|
523
|
-
WHERE ${
|
|
530
|
+
WHERE ${n}
|
|
524
531
|
ORDER BY up.created_at_epoch DESC
|
|
525
532
|
LIMIT 1
|
|
526
|
-
`).get(o)}findRecentDuplicateUserPrompt(e,s,t,
|
|
533
|
+
`).get(o)}findRecentDuplicateUserPrompt(e,s,t,n){return ve(this.db,e,q(s),t,this.resolvePromptSessionDbId(e,n)??void 0)}getRecentSessionsWithStatus(e,s=3,t){let n=[e],o="";return t&&(o=`AND COALESCE(NULLIF(s.platform_source, ''), '${l}') = ?`,n.push(C(t))),n.push(s),this.db.prepare(`
|
|
527
534
|
SELECT * FROM (
|
|
528
535
|
SELECT
|
|
529
536
|
s.memory_session_id,
|
|
@@ -541,63 +548,63 @@ ${h.stack??""}
|
|
|
541
548
|
LIMIT ?
|
|
542
549
|
)
|
|
543
550
|
ORDER BY started_at_epoch ASC
|
|
544
|
-
`).all(...
|
|
551
|
+
`).all(...n)}getObservationsForSession(e,s){let t=[e],n="";return s&&(n=`
|
|
545
552
|
AND EXISTS (
|
|
546
553
|
SELECT 1
|
|
547
554
|
FROM sdk_sessions s
|
|
548
555
|
WHERE s.memory_session_id = observations.memory_session_id
|
|
549
|
-
AND COALESCE(NULLIF(s.platform_source, ''), '${
|
|
556
|
+
AND COALESCE(NULLIF(s.platform_source, ''), '${l}') = ?
|
|
550
557
|
)
|
|
551
|
-
`,t.push(
|
|
558
|
+
`,t.push(C(s))),this.db.prepare(`
|
|
552
559
|
SELECT title, subtitle, type, prompt_number
|
|
553
560
|
FROM observations
|
|
554
561
|
WHERE memory_session_id = ?
|
|
555
|
-
${
|
|
562
|
+
${n}
|
|
556
563
|
ORDER BY created_at_epoch ASC
|
|
557
564
|
`).all(...t)}getObservationById(e,s){return s?this.db.prepare(`
|
|
558
565
|
SELECT o.*
|
|
559
566
|
FROM observations o
|
|
560
567
|
LEFT JOIN sdk_sessions s ON s.memory_session_id = o.memory_session_id
|
|
561
568
|
WHERE o.id = ?
|
|
562
|
-
AND COALESCE(NULLIF(s.platform_source, ''), '${
|
|
563
|
-
`).get(e,
|
|
569
|
+
AND COALESCE(NULLIF(s.platform_source, ''), '${l}') = ?
|
|
570
|
+
`).get(e,C(s))||null:this.db.prepare(`
|
|
564
571
|
SELECT *
|
|
565
572
|
FROM observations
|
|
566
573
|
WHERE id = ?
|
|
567
|
-
`).get(e)||null}getObservationsByIds(e,s={}){if(e.length===0)return[];let{orderBy:t="date_desc",limit:
|
|
574
|
+
`).get(e)||null}getObservationsByIds(e,s={}){if(e.length===0)return[];let{orderBy:t="date_desc",limit:n,project:o,platformSource:i,type:a,concepts:d,files:_}=s,u=t==="relevance",c=u?"":`ORDER BY o.created_at_epoch ${t==="date_asc"?"ASC":"DESC"}`,p=n&&!u?`LIMIT ${n}`:"",g=e.map(()=>"?").join(","),I=[...e],h=[];if(o&&(h.push("o.project = ?"),I.push(o)),i&&(h.push(`COALESCE(NULLIF(s.platform_source, ''), '${l}') = ?`),I.push(C(i))),a)if(Array.isArray(a)){let N=a.map(()=>"?").join(",");h.push(`o.type IN (${N})`),I.push(...a)}else h.push("o.type = ?"),I.push(a);if(d){let N=Array.isArray(d)?d:[d],b=N.map(()=>"EXISTS (SELECT 1 FROM json_each(o.concepts) WHERE value = ?)");I.push(...N),h.push(`(${b.join(" OR ")})`)}if(_){let N=Array.isArray(_)?_:[_],b=N.map(()=>"(EXISTS (SELECT 1 FROM json_each(o.files_read) WHERE value LIKE ?) OR EXISTS (SELECT 1 FROM json_each(o.files_modified) WHERE value LIKE ?))");N.forEach(D=>{I.push(`%${D}%`,`%${D}%`)}),h.push(`(${b.join(" OR ")})`)}let S=h.length>0?`WHERE o.id IN (${g}) AND ${h.join(" AND ")}`:`WHERE o.id IN (${g})`,L=this.db.prepare(`
|
|
568
575
|
SELECT o.*
|
|
569
576
|
FROM observations o
|
|
570
577
|
LEFT JOIN sdk_sessions s ON s.memory_session_id = o.memory_session_id
|
|
571
|
-
${
|
|
572
|
-
${l}
|
|
578
|
+
${S}
|
|
573
579
|
${c}
|
|
574
|
-
|
|
580
|
+
${p}
|
|
581
|
+
`).all(...I);if(!u)return L;let U=new Map(L.map(N=>[N.id,N])),O=e.map(N=>U.get(N)).filter(N=>!!N);return n?O.slice(0,n):O}getSummaryForSession(e,s){let t=[e],n="";return s&&(n=`
|
|
575
582
|
AND EXISTS (
|
|
576
583
|
SELECT 1
|
|
577
584
|
FROM sdk_sessions sdk
|
|
578
585
|
WHERE sdk.memory_session_id = session_summaries.memory_session_id
|
|
579
|
-
AND COALESCE(NULLIF(sdk.platform_source, ''), '${
|
|
586
|
+
AND COALESCE(NULLIF(sdk.platform_source, ''), '${l}') = ?
|
|
580
587
|
)
|
|
581
|
-
`,t.push(
|
|
588
|
+
`,t.push(C(s))),this.db.prepare(`
|
|
582
589
|
SELECT
|
|
583
590
|
request, investigated, learned, completed, next_steps,
|
|
584
591
|
files_read, files_edited, notes, prompt_number, created_at,
|
|
585
592
|
created_at_epoch
|
|
586
593
|
FROM session_summaries
|
|
587
594
|
WHERE memory_session_id = ?
|
|
588
|
-
${
|
|
595
|
+
${n}
|
|
589
596
|
ORDER BY created_at_epoch DESC
|
|
590
597
|
LIMIT 1
|
|
591
598
|
`).get(...t)||null}getSessionById(e){return this.db.prepare(`
|
|
592
599
|
SELECT id, content_session_id, memory_session_id, project,
|
|
593
|
-
COALESCE(platform_source, '${
|
|
600
|
+
COALESCE(platform_source, '${l}') as platform_source,
|
|
594
601
|
user_prompt, custom_title, status
|
|
595
602
|
FROM sdk_sessions
|
|
596
603
|
WHERE id = ?
|
|
597
604
|
LIMIT 1
|
|
598
605
|
`).get(e)||null}getSdkSessionsBySessionIds(e){if(e.length===0)return[];let s=e.map(()=>"?").join(",");return this.db.prepare(`
|
|
599
606
|
SELECT id, content_session_id, memory_session_id, project,
|
|
600
|
-
COALESCE(platform_source, '${
|
|
607
|
+
COALESCE(platform_source, '${l}') as platform_source,
|
|
601
608
|
user_prompt, custom_title,
|
|
602
609
|
started_at, started_at_epoch, completed_at, completed_at_epoch, status
|
|
603
610
|
FROM sdk_sessions
|
|
@@ -607,41 +614,41 @@ ${h.stack??""}
|
|
|
607
614
|
SELECT COUNT(*) as count FROM user_prompts WHERE session_db_id = ?
|
|
608
615
|
`).get(t).count:this.db.prepare(`
|
|
609
616
|
SELECT COUNT(*) as count FROM user_prompts WHERE content_session_id = ?
|
|
610
|
-
`).get(e).count}createSDKSession(e,s,t,
|
|
617
|
+
`).get(e).count}createSDKSession(e,s,t,n,o){let i=new Date,a=i.getTime(),d=o?C(o):l,_=q(t),u=this.db.prepare(`
|
|
611
618
|
SELECT id, platform_source
|
|
612
619
|
FROM sdk_sessions
|
|
613
620
|
WHERE COALESCE(NULLIF(platform_source, ''), ?) = ?
|
|
614
621
|
AND content_session_id = ?
|
|
615
|
-
`).get(
|
|
622
|
+
`).get(l,d,e);if(u)return s&&this.db.prepare(`
|
|
616
623
|
UPDATE sdk_sessions SET project = ?
|
|
617
624
|
WHERE id = ? AND (project IS NULL OR project = '')
|
|
618
|
-
`).run(s,
|
|
625
|
+
`).run(s,u.id),n&&this.db.prepare(`
|
|
619
626
|
UPDATE sdk_sessions SET custom_title = ?
|
|
620
627
|
WHERE id = ? AND custom_title IS NULL
|
|
621
|
-
`).run(
|
|
628
|
+
`).run(n,u.id),u.id;let c=this.db.prepare(`
|
|
622
629
|
INSERT INTO sdk_sessions
|
|
623
630
|
(content_session_id, memory_session_id, project, platform_source, user_prompt, custom_title, started_at, started_at_epoch, status)
|
|
624
631
|
VALUES (?, NULL, ?, ?, ?, ?, ?, ?, 'active')
|
|
625
|
-
`).run(e,s,d,
|
|
632
|
+
`).run(e,s,d,_,n||null,i.toISOString(),a);return Number(c.lastInsertRowid)}saveUserPrompt(e,s,t,n){let o=new Date,i=o.getTime(),a=q(t),d=this.resolvePromptSessionDbId(e,n);return this.db.prepare(`
|
|
626
633
|
INSERT INTO user_prompts
|
|
627
634
|
(session_db_id, content_session_id, prompt_number, prompt_text, created_at, created_at_epoch)
|
|
628
635
|
VALUES (?, ?, ?, ?, ?, ?)
|
|
629
|
-
`).run(d,e,s,a,o.toISOString(),i).lastInsertRowid}getUserPrompt(e,s,t){let
|
|
636
|
+
`).run(d,e,s,a,o.toISOString(),i).lastInsertRowid}getUserPrompt(e,s,t){let n=this.resolvePromptSessionDbId(e,t);return n!==null?this.db.prepare(`
|
|
630
637
|
SELECT prompt_text
|
|
631
638
|
FROM user_prompts
|
|
632
639
|
WHERE session_db_id = ? AND prompt_number = ?
|
|
633
640
|
LIMIT 1
|
|
634
|
-
`).get(
|
|
641
|
+
`).get(n,s)?.prompt_text??null:this.db.prepare(`
|
|
635
642
|
SELECT prompt_text
|
|
636
643
|
FROM user_prompts
|
|
637
644
|
WHERE content_session_id = ? AND prompt_number = ?
|
|
638
645
|
LIMIT 1
|
|
639
|
-
`).get(e,s)?.prompt_text??null}storeObservation(e,s,t,
|
|
646
|
+
`).get(e,s)?.prompt_text??null}storeObservation(e,s,t,n,o=0,i,a){let d=this.storeObservations(e,s,[t],null,n,o,i,a);return{id:d.observationIds[0],createdAtEpoch:d.createdAtEpoch}}storeSummary(e,s,t,n,o=0,i){let a=i??Date.now(),d=new Date(a).toISOString(),u=this.db.prepare(`
|
|
640
647
|
INSERT INTO session_summaries
|
|
641
648
|
(memory_session_id, project, request, investigated, learned, completed,
|
|
642
649
|
next_steps, notes, prompt_number, discovery_tokens, created_at, created_at_epoch)
|
|
643
650
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
644
|
-
`).run(e,s,t.request,t.investigated,t.learned,t.completed,t.next_steps,t.notes,
|
|
651
|
+
`).run(e,s,t.request,t.investigated,t.learned,t.completed,t.next_steps,t.notes,n||null,o,d,a);return{id:Number(u.lastInsertRowid),createdAtEpoch:a}}storeObservations(e,s,t,n,o,i=0,a,d){let _=a??Date.now(),u=new Date(_).toISOString();return this.db.transaction(()=>{let p=[],g=this.db.prepare(`
|
|
645
652
|
INSERT INTO observations
|
|
646
653
|
(memory_session_id, project, type, title, subtitle, facts, narrative, concepts,
|
|
647
654
|
files_read, files_modified, prompt_number, discovery_tokens, agent_type, agent_id, content_hash, created_at, created_at_epoch,
|
|
@@ -649,79 +656,79 @@ ${h.stack??""}
|
|
|
649
656
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
650
657
|
ON CONFLICT(memory_session_id, content_hash) DO NOTHING
|
|
651
658
|
RETURNING id
|
|
652
|
-
`),
|
|
659
|
+
`),I=this.db.prepare("SELECT id FROM observations WHERE memory_session_id = ? AND content_hash = ?");for(let S of t){let f=De(e,S.title,S.narrative),L=g.get(e,s,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),o||null,i,S.agent_type??null,S.agent_id??null,f,u,_,d||null,S.metadata??null);if(L){p.push(L.id);continue}let U=I.get(e,f);if(!U)throw new Error(`storeObservations: ON CONFLICT without existing row for content_hash=${f}`);p.push(U.id)}let h=null;if(n){let f=this.db.prepare(`
|
|
653
660
|
INSERT INTO session_summaries
|
|
654
661
|
(memory_session_id, project, request, investigated, learned, completed,
|
|
655
662
|
next_steps, notes, prompt_number, discovery_tokens, created_at, created_at_epoch)
|
|
656
663
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
657
|
-
`).run(e,s,
|
|
664
|
+
`).run(e,s,n.request,n.investigated,n.learned,n.completed,n.next_steps,n.notes,o||null,i,u,_);h=Number(f.lastInsertRowid)}return{observationIds:p,summaryId:h,createdAtEpoch:_}})()}getSessionSummariesByIds(e,s={}){if(e.length===0)return[];let{orderBy:t="date_desc",limit:n,project:o,platformSource:i}=s,a=t==="relevance",d=a?"":`ORDER BY ss.created_at_epoch ${t==="date_asc"?"ASC":"DESC"}`,_=n&&!a?`LIMIT ${n}`:"",u=e.map(()=>"?").join(","),c=[...e],p=[];o&&(p.push("ss.project = ?"),c.push(o)),i&&(p.push(`COALESCE(NULLIF(s.platform_source, ''), '${l}') = ?`),c.push(C(i)));let g=p.length>0?`AND ${p.join(" AND ")}`:"",h=this.db.prepare(`
|
|
658
665
|
SELECT ss.*
|
|
659
666
|
FROM session_summaries ss
|
|
660
667
|
LEFT JOIN sdk_sessions s ON s.memory_session_id = ss.memory_session_id
|
|
661
|
-
WHERE ss.id IN (${
|
|
668
|
+
WHERE ss.id IN (${u}) ${g}
|
|
662
669
|
${d}
|
|
663
|
-
${
|
|
664
|
-
`).all(...
|
|
670
|
+
${_}
|
|
671
|
+
`).all(...c);if(!a)return h;let S=new Map(h.map(L=>[L.id,L])),f=e.map(L=>S.get(L)).filter(L=>!!L);return n?f.slice(0,n):f}getUserPromptsByIds(e,s={}){if(e.length===0)return[];let{orderBy:t="date_desc",limit:n,project:o,platformSource:i}=s,a=t==="relevance",d=a?"":`ORDER BY up.created_at_epoch ${t==="date_asc"?"ASC":"DESC"}`,_=n?`LIMIT ${n}`:"",u=e.map(()=>"?").join(","),c=[...e],p=[];o&&(p.push("s.project = ?"),c.push(o)),i&&(p.push(`COALESCE(NULLIF(s.platform_source, ''), '${l}') = ?`),c.push(C(i)));let g=p.length>0?`AND ${p.join(" AND ")}`:"",h=this.db.prepare(`
|
|
665
672
|
SELECT
|
|
666
673
|
up.*,
|
|
667
674
|
s.project,
|
|
668
675
|
s.memory_session_id,
|
|
669
|
-
COALESCE(NULLIF(s.platform_source, ''), '${
|
|
676
|
+
COALESCE(NULLIF(s.platform_source, ''), '${l}') as platform_source
|
|
670
677
|
FROM user_prompts up
|
|
671
678
|
JOIN sdk_sessions s ON up.session_db_id = s.id
|
|
672
|
-
WHERE up.id IN (${
|
|
679
|
+
WHERE up.id IN (${u}) ${g}
|
|
673
680
|
${d}
|
|
674
|
-
${
|
|
675
|
-
`).all(...
|
|
681
|
+
${_}
|
|
682
|
+
`).all(...c);if(!a)return h;let S=new Map(h.map(f=>[f.id,f]));return e.map(f=>S.get(f)).filter(f=>!!f)}getTimelineAroundTimestamp(e,s=10,t=10,n,o){return this.getTimelineAroundObservation(null,e,s,t,n,o)}getTimelineAroundObservation(e,s,t=10,n=10,o,i){let a=i?C(i):void 0,d=(O,N)=>{let b=[],D=[];return o&&(b.push(`${O}.project = ?`),D.push(o)),a&&(b.push(`COALESCE(NULLIF(${N}.platform_source, ''), '${l}') = ?`),D.push(a)),{clause:b.length>0?`AND ${b.join(" AND ")}`:"",params:D}},_=d("o","src"),u=d("ss","src"),c=d("s","s"),p,g;if(e!==null){let O=`
|
|
676
683
|
SELECT o.id, o.created_at_epoch
|
|
677
684
|
FROM observations o
|
|
678
685
|
LEFT JOIN sdk_sessions src ON src.memory_session_id = o.memory_session_id
|
|
679
|
-
WHERE o.id <= ? ${
|
|
686
|
+
WHERE o.id <= ? ${_.clause}
|
|
680
687
|
ORDER BY o.id DESC
|
|
681
688
|
LIMIT ?
|
|
682
689
|
`,N=`
|
|
683
690
|
SELECT o.id, o.created_at_epoch
|
|
684
691
|
FROM observations o
|
|
685
692
|
LEFT JOIN sdk_sessions src ON src.memory_session_id = o.memory_session_id
|
|
686
|
-
WHERE o.id >= ? ${
|
|
693
|
+
WHERE o.id >= ? ${_.clause}
|
|
687
694
|
ORDER BY o.id ASC
|
|
688
695
|
LIMIT ?
|
|
689
|
-
`;try{let
|
|
696
|
+
`;try{let b=this.db.prepare(O).all(e,..._.params,t+1),D=this.db.prepare(N).all(e,..._.params,n+1);if(b.length===0&&D.length===0)return{observations:[],sessions:[],prompts:[]};p=b.length>0?b[b.length-1].created_at_epoch:s,g=D.length>0?D[D.length-1].created_at_epoch:s}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 O=`
|
|
690
697
|
SELECT o.created_at_epoch
|
|
691
698
|
FROM observations o
|
|
692
699
|
LEFT JOIN sdk_sessions src ON src.memory_session_id = o.memory_session_id
|
|
693
|
-
WHERE o.created_at_epoch <= ? ${
|
|
700
|
+
WHERE o.created_at_epoch <= ? ${_.clause}
|
|
694
701
|
ORDER BY o.created_at_epoch DESC
|
|
695
702
|
LIMIT ?
|
|
696
703
|
`,N=`
|
|
697
704
|
SELECT o.created_at_epoch
|
|
698
705
|
FROM observations o
|
|
699
706
|
LEFT JOIN sdk_sessions src ON src.memory_session_id = o.memory_session_id
|
|
700
|
-
WHERE o.created_at_epoch >= ? ${
|
|
707
|
+
WHERE o.created_at_epoch >= ? ${_.clause}
|
|
701
708
|
ORDER BY o.created_at_epoch ASC
|
|
702
709
|
LIMIT ?
|
|
703
|
-
`;try{let
|
|
710
|
+
`;try{let b=this.db.prepare(O).all(s,..._.params,t),D=this.db.prepare(N).all(s,..._.params,n+1);if(b.length===0&&D.length===0)return{observations:[],sessions:[],prompts:[]};p=b.length>0?b[b.length-1].created_at_epoch:s,g=D.length>0?D[D.length-1].created_at_epoch:s}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 I=`
|
|
704
711
|
SELECT o.*
|
|
705
712
|
FROM observations o
|
|
706
713
|
LEFT JOIN sdk_sessions src ON src.memory_session_id = o.memory_session_id
|
|
707
|
-
WHERE o.created_at_epoch >= ? AND o.created_at_epoch <= ? ${
|
|
714
|
+
WHERE o.created_at_epoch >= ? AND o.created_at_epoch <= ? ${_.clause}
|
|
708
715
|
ORDER BY o.created_at_epoch ASC
|
|
709
|
-
`,
|
|
716
|
+
`,h=`
|
|
710
717
|
SELECT ss.*
|
|
711
718
|
FROM session_summaries ss
|
|
712
719
|
LEFT JOIN sdk_sessions src ON src.memory_session_id = ss.memory_session_id
|
|
713
|
-
WHERE ss.created_at_epoch >= ? AND ss.created_at_epoch <= ? ${
|
|
720
|
+
WHERE ss.created_at_epoch >= ? AND ss.created_at_epoch <= ? ${u.clause}
|
|
714
721
|
ORDER BY ss.created_at_epoch ASC
|
|
715
|
-
`,
|
|
716
|
-
SELECT up.*, s.project, s.memory_session_id, COALESCE(NULLIF(s.platform_source, ''), '${
|
|
722
|
+
`,S=`
|
|
723
|
+
SELECT up.*, s.project, s.memory_session_id, COALESCE(NULLIF(s.platform_source, ''), '${l}') as platform_source
|
|
717
724
|
FROM user_prompts up
|
|
718
725
|
JOIN sdk_sessions s ON up.session_db_id = s.id
|
|
719
|
-
WHERE up.created_at_epoch >= ? AND up.created_at_epoch <= ? ${
|
|
726
|
+
WHERE up.created_at_epoch >= ? AND up.created_at_epoch <= ? ${c.clause}
|
|
720
727
|
ORDER BY up.created_at_epoch ASC
|
|
721
|
-
`,
|
|
728
|
+
`,f=this.db.prepare(I).all(p,g,..._.params),L=this.db.prepare(h).all(p,g,...u.params),U=this.db.prepare(S).all(p,g,...c.params);return{observations:f,sessions:L.map(O=>({id:O.id,memory_session_id:O.memory_session_id,project:O.project,request:O.request,completed:O.completed,next_steps:O.next_steps,created_at:O.created_at,created_at_epoch:O.created_at_epoch})),prompts:U.map(O=>({id:O.id,content_session_id:O.content_session_id,prompt_number:O.prompt_number,prompt_text:O.prompt_text,project:O.project,platform_source:O.platform_source,created_at:O.created_at,created_at_epoch:O.created_at_epoch}))}}getOrCreateManualSession(e){let s=`manual-${e}`,t=`manual-content-${e}`;if(this.db.prepare("SELECT memory_session_id FROM sdk_sessions WHERE memory_session_id = ?").get(s))return s;let o=new Date;return this.db.prepare(`
|
|
722
729
|
INSERT INTO sdk_sessions (memory_session_id, content_session_id, project, platform_source, started_at, started_at_epoch, status)
|
|
723
730
|
VALUES (?, ?, ?, ?, ?, ?, 'active')
|
|
724
|
-
`).run(s,t,e,
|
|
731
|
+
`).run(s,t,e,l,o.toISOString(),o.getTime()),E.info("SESSION","Created manual session",{memorySessionId:s,project:e}),s}close(){this.db.close()}importSdkSession(e){let s=C(e.platform_source),t=this.db.prepare(`SELECT id FROM sdk_sessions
|
|
725
732
|
WHERE platform_source = ? AND content_session_id = ?`).get(s,e.content_session_id);return t?{imported:!1,id:t.id}:{imported:!0,id:this.db.prepare(`
|
|
726
733
|
INSERT INTO sdk_sessions (
|
|
727
734
|
content_session_id, memory_session_id, project, platform_source, user_prompt,
|
|
@@ -743,20 +750,20 @@ ${h.stack??""}
|
|
|
743
750
|
prompt_number, discovery_tokens, agent_type, agent_id,
|
|
744
751
|
created_at, created_at_epoch
|
|
745
752
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
746
|
-
`).run(e.memory_session_id,e.project,e.text,e.type,e.title,e.subtitle,e.facts,e.narrative,e.concepts,e.files_read,e.files_modified,e.prompt_number,e.discovery_tokens||0,e.agent_type??null,e.agent_id??null,e.created_at,e.created_at_epoch).lastInsertRowid}}rebuildObservationsFTSIndex(){this.db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='observations_fts'").all().length>0&&this.db.run("INSERT INTO observations_fts(observations_fts) VALUES('rebuild')")}importUserPrompt(e){let s=null,t=e.platform_source?
|
|
747
|
-
SELECT id, content_session_id, COALESCE(NULLIF(platform_source, ''), '${
|
|
753
|
+
`).run(e.memory_session_id,e.project,e.text,e.type,e.title,e.subtitle,e.facts,e.narrative,e.concepts,e.files_read,e.files_modified,e.prompt_number,e.discovery_tokens||0,e.agent_type??null,e.agent_id??null,e.created_at,e.created_at_epoch).lastInsertRowid}}rebuildObservationsFTSIndex(){this.db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='observations_fts'").all().length>0&&this.db.run("INSERT INTO observations_fts(observations_fts) VALUES('rebuild')")}importUserPrompt(e){let s=null,t=e.platform_source?C(e.platform_source):void 0;if(typeof e.session_db_id=="number"){let a=this.db.prepare(`
|
|
754
|
+
SELECT id, content_session_id, COALESCE(NULLIF(platform_source, ''), '${l}') as platform_source
|
|
748
755
|
FROM sdk_sessions
|
|
749
756
|
WHERE id = ?
|
|
750
757
|
LIMIT 1
|
|
751
|
-
`).get(e.session_db_id);a&&a.content_session_id===e.content_session_id&&(!t||
|
|
758
|
+
`).get(e.session_db_id);a&&a.content_session_id===e.content_session_id&&(!t||C(a.platform_source)===t)&&(s=a.id)}s===null&&(s=this.resolvePromptSessionDbId(e.content_session_id,void 0,t));let n=this.db.prepare(`
|
|
752
759
|
SELECT id FROM user_prompts
|
|
753
760
|
WHERE ${s!==null?"session_db_id = ?":"content_session_id = ?"} AND prompt_number = ?
|
|
754
|
-
`).get(s??e.content_session_id,e.prompt_number);return
|
|
761
|
+
`).get(s??e.content_session_id,e.prompt_number);return n?{imported:!1,id:n.id}:{imported:!0,id:this.db.prepare(`
|
|
755
762
|
INSERT INTO user_prompts (
|
|
756
763
|
session_db_id, content_session_id, prompt_number, prompt_text,
|
|
757
764
|
created_at, created_at_epoch
|
|
758
765
|
) VALUES (?, ?, ?, ?, ?, ?)
|
|
759
|
-
`).run(s,e.content_session_id,e.prompt_number,e.prompt_text,e.created_at,e.created_at_epoch).lastInsertRowid}}};var ye=require("os"),Ue=x(require("path"),1),xe=require("child_process");var V=require("fs"),W=x(require("path"),1);var w={isWorktree:!1,worktreeName:null,parentRepoPath:null,parentProjectName:null};function ve(n){let e=W.default.join(n,".git"),s;try{s=(0,V.statSync)(e)}catch(m){return m instanceof Error&&m.code!=="ENOENT"&&_.warn("GIT","Unexpected error checking .git",{error:m instanceof Error?m.message:String(m)}),w}if(!s.isFile())return w;let t;try{t=(0,V.readFileSync)(e,"utf-8").trim()}catch(m){return _.warn("GIT","Failed to read .git file",{error:m instanceof Error?m.message:String(m)}),w}let r=t.match(/^gitdir:\s*(.+)$/);if(!r)return w;let i=r[1].match(/^(.+)[/\\]\.git[/\\]worktrees[/\\]([^/\\]+)$/);if(!i)return w;let a=i[1],d=W.default.basename(n),u=W.default.basename(a);return{isWorktree:!0,worktreeName:d,parentRepoPath:a,parentProjectName:u}}function ke(n){return n==="~"||n.startsWith("~/")?n.replace(/^~/,(0,ye.homedir)()):n}function Zs(n){try{return(0,xe.execFileSync)("git",["rev-parse","--show-toplevel"],{cwd:n,encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim()||null}catch(e){let s=e instanceof Error?e:new Error(String(e));return _.debug("PROJECT_NAME","git rev-parse failed, falling back to basename",{dir:n},s),null}}function et(n){if(!n||n.trim()==="")return _.warn("PROJECT_NAME","Empty cwd provided, using fallback",{cwd:n}),"unknown-project";let e=ke(n),t=Zs(e)??e,r=Ue.default.basename(t);if(r===""){if(process.platform==="win32"){let i=n.match(/^([A-Z]):\\/i);if(i){let d=`drive-${i[1].toUpperCase()}`;return _.info("PROJECT_NAME","Drive root detected",{cwd:n,projectName:d}),d}}return _.warn("PROJECT_NAME","Root directory detected, using fallback",{cwd:n}),"unknown-project"}return r}function we(n){let e=et(n);if(!n)return{primary:e,parent:null,isWorktree:!1,allProjects:[e]};let s=ke(n),t=ve(s);if(t.isWorktree&&t.parentProjectName){let r=`${t.parentProjectName}/${e}`;return{primary:r,parent:t.parentProjectName,isWorktree:!0,allProjects:[t.parentProjectName,r]}}return{primary:e,parent:null,isWorktree:!1,allProjects:[e]}}var M=require("fs"),F=require("path"),Ee=require("os");var _e={HEALTH_CHECK:3e3,API_REQUEST:3e4,HOOK_READINESS_WAIT:1e4,POST_SPAWN_WAIT:15e3,READINESS_WAIT:3e4,PORT_IN_USE_WAIT:3e3,POWERSHELL_COMMAND:1e4,WINDOWS_MULTIPLIER:1.5};function Fe(n){return process.platform==="win32"?Math.round(n*_e.WINDOWS_MULTIPLIER):n}var K=class{static DEFAULTS={CLAUDE_MEM_MODEL:"claude-haiku-4-5-20251001",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_WORKER_PORT:String(37700+(process.getuid?.()??77)%100),CLAUDE_MEM_WORKER_HOST:"127.0.0.1",CLAUDE_MEM_API_TIMEOUT_MS:String(Fe(_e.API_REQUEST)),CLAUDE_MEM_SKIP_TOOLS:"ListMcpResourcesTool,SlashCommand,Skill,TodoWrite,AskUserQuestion",CLAUDE_MEM_PROVIDER:"claude",CLAUDE_MEM_CLAUDE_AUTH_METHOD:"subscription",CLAUDE_MEM_GEMINI_API_KEY:"",CLAUDE_MEM_GEMINI_MODEL:"gemini-2.5-flash-lite",CLAUDE_MEM_GEMINI_RATE_LIMITING_ENABLED:"true",CLAUDE_MEM_OPENROUTER_API_KEY:"",CLAUDE_MEM_OPENROUTER_MODEL:"xiaomi/mimo-v2-flash:free",CLAUDE_MEM_OPENROUTER_BASE_URL:"",CLAUDE_MEM_OPENROUTER_SITE_URL:"",CLAUDE_MEM_OPENROUTER_APP_NAME:"claude-mem",CLAUDE_MEM_DATA_DIR:(0,F.join)((0,Ee.homedir)(),".claude-mem"),CLAUDE_MEM_LOG_LEVEL:"INFO",CLAUDE_MEM_PYTHON_VERSION:"3.13",CLAUDE_CODE_PATH:"",CLAUDE_MEM_MODE:"code",CLAUDE_MEM_CONTEXT_SHOW_READ_TOKENS:"false",CLAUDE_MEM_CONTEXT_SHOW_WORK_TOKENS:"false",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT:"false",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT:"true",CLAUDE_MEM_CONTEXT_FULL_COUNT:"0",CLAUDE_MEM_CONTEXT_FULL_FIELD:"narrative",CLAUDE_MEM_CONTEXT_SESSION_COUNT:"10",CLAUDE_MEM_CONTEXT_SHOW_LAST_SUMMARY:"true",CLAUDE_MEM_CONTEXT_SHOW_LAST_MESSAGE:"false",CLAUDE_MEM_CONTEXT_SHOW_TERMINAL_OUTPUT:"true",CLAUDE_MEM_WELCOME_HINT_ENABLED:"true",CLAUDE_MEM_FOLDER_CLAUDEMD_ENABLED:"false",CLAUDE_MEM_FOLDER_USE_LOCAL_MD:"false",CLAUDE_MEM_TRANSCRIPTS_ENABLED:"true",CLAUDE_MEM_TRANSCRIPTS_CONFIG_PATH:(0,F.join)((0,Ee.homedir)(),".claude-mem","transcript-watch.json"),CLAUDE_MEM_CODEX_TRANSCRIPT_INGESTION:"false",CLAUDE_MEM_MAX_CONCURRENT_AGENTS:"2",CLAUDE_MEM_HOOK_FAIL_LOUD_THRESHOLD:"3",CLAUDE_MEM_EXCLUDED_PROJECTS:"",CLAUDE_MEM_FOLDER_MD_EXCLUDE:"[]",CLAUDE_MEM_FOLDER_MD_SKELETON_DENYLIST:"[]",CLAUDE_MEM_SEMANTIC_INJECT:"false",CLAUDE_MEM_SEMANTIC_INJECT_LIMIT:"5",CLAUDE_MEM_TIER_ROUTING_ENABLED:"true",CLAUDE_MEM_TIER_SIMPLE_MODEL:"haiku",CLAUDE_MEM_TIER_SUMMARY_MODEL:"",CLAUDE_MEM_TIER_FAST_MODEL:"haiku",CLAUDE_MEM_TIER_SMART_MODEL:"sonnet",CLAUDE_MEM_CHROMA_ENABLED:"true",CLAUDE_MEM_CHROMA_MODE:"local",CLAUDE_MEM_CHROMA_HOST:"127.0.0.1",CLAUDE_MEM_CHROMA_PORT:"8000",CLAUDE_MEM_CHROMA_SSL:"false",CLAUDE_MEM_CHROMA_API_KEY:"",CLAUDE_MEM_CHROMA_TENANT:"default_tenant",CLAUDE_MEM_CHROMA_DATABASE:"default_database",CLAUDE_MEM_CHROMA_PREWARM_TIMEOUT_MS:"120000",CLAUDE_MEM_TELEGRAM_ENABLED:"true",CLAUDE_MEM_TELEGRAM_BOT_TOKEN:"",CLAUDE_MEM_TELEGRAM_CHAT_ID:"",CLAUDE_MEM_TELEGRAM_TRIGGER_TYPES:"security_alert",CLAUDE_MEM_TELEGRAM_TRIGGER_CONCEPTS:"",CLAUDE_MEM_QUEUE_ENGINE:"sqlite",CLAUDE_MEM_REDIS_URL:"",CLAUDE_MEM_REDIS_HOST:"127.0.0.1",CLAUDE_MEM_REDIS_PORT:"6379",CLAUDE_MEM_REDIS_MODE:"external",CLAUDE_MEM_QUEUE_REDIS_PREFIX:`claude_mem_${process.env.CLAUDE_MEM_WORKER_PORT??String(37700+(process.getuid?.()??77)%100)}`,CLAUDE_MEM_AUTH_MODE:"api-key",CLAUDE_MEM_RUNTIME:"worker",CLAUDE_MEM_SERVER_URL:`http://127.0.0.1:${process.env.CLAUDE_MEM_SERVER_PORT??String(37877+(process.getuid?.()??77)%100)}`,CLAUDE_MEM_SERVER_API_KEY:"",CLAUDE_MEM_SERVER_PROJECT_ID:"",CLAUDE_MEM_SERVER_BETA_URL:`http://127.0.0.1:${process.env.CLAUDE_MEM_SERVER_PORT??String(37877+(process.getuid?.()??77)%100)}`,CLAUDE_MEM_SERVER_BETA_API_KEY:"",CLAUDE_MEM_SERVER_BETA_PROJECT_ID:""};static getAllDefaults(){return{...this.DEFAULTS}}static get(e){return process.env[e]??this.DEFAULTS[e]}static getInt(e){let s=this.get(e);return parseInt(s,10)}static applyEnvOverrides(e){let s={...e};for(let t of Object.keys(this.DEFAULTS))process.env[t]!==void 0&&(s[t]=process.env[t]);return s}static loadFromFile(e,s=!0){try{if(!(0,M.existsSync)(e)){let a=this.getAllDefaults();try{let d=(0,F.dirname)(e);(0,M.existsSync)(d)||(0,M.mkdirSync)(d,{recursive:!0}),(0,M.writeFileSync)(e,JSON.stringify(a,null,2),"utf-8"),console.warn("[SETTINGS] Created settings file with defaults:",e)}catch(d){console.warn("[SETTINGS] Failed to create settings file, using in-memory defaults:",e,d instanceof Error?d.message:String(d))}return s?this.applyEnvOverrides(a):a}let t=(0,M.readFileSync)(e,"utf-8"),r=JSON.parse(t.replace(/^\uFEFF/,"")),o=r;if(r.env&&typeof r.env=="object"){o=r.env;try{(0,M.writeFileSync)(e,JSON.stringify(o,null,2),"utf-8"),console.warn("[SETTINGS] Migrated settings file from nested to flat schema:",e)}catch(a){console.warn("[SETTINGS] Failed to auto-migrate settings file:",e,a instanceof Error?a.message:String(a))}}let i={...this.DEFAULTS};for(let a of Object.keys(this.DEFAULTS))o[a]!==void 0&&(i[a]=o[a]);return s?this.applyEnvOverrides(i):i}catch(t){console.warn("[SETTINGS] Failed to load settings, using defaults:",e,t instanceof Error?t.message:String(t));let r=this.getAllDefaults();return s?this.applyEnvOverrides(r):r}}};var P=require("fs"),Y=require("path");var D=class n{static instance=null;activeMode=null;modesDir;constructor(){let e=Re(),s=[...process.env.CLAUDE_MEM_MODES_DIR?[process.env.CLAUDE_MEM_MODES_DIR]:[],(0,Y.join)(e,"modes"),(0,Y.join)(e,"..","plugin","modes")],t=s.find(r=>(0,P.existsSync)(r));this.modesDir=t||s[0]}static getInstance(){return n.instance||(n.instance=new n),n.instance}parseInheritance(e){let s=e.split("--");if(s.length===1)return{hasParent:!1,parentId:"",overrideId:""};if(s.length>2)throw new Error(`Invalid mode inheritance: ${e}. Only one level of inheritance supported (parent--override)`);return{hasParent:!0,parentId:s[0],overrideId:e}}isPlainObject(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}deepMerge(e,s){let t={...e};for(let r in s){let o=s[r],i=e[r];this.isPlainObject(o)&&this.isPlainObject(i)?t[r]=this.deepMerge(i,o):t[r]=o}return t}loadModeFile(e){let s=(0,Y.join)(this.modesDir,`${e}.json`);if(!(0,P.existsSync)(s))throw new Error(`Mode file not found: ${s}`);let t=(0,P.readFileSync)(s,"utf-8");return JSON.parse(t)}loadMode(e){let s=this.parseInheritance(e);if(!s.hasParent)try{let d=this.loadModeFile(e);return this.activeMode=d,_.debug("SYSTEM",`Loaded mode: ${d.name} (${e})`,void 0,{types:d.observation_types.map(u=>u.id),concepts:d.observation_concepts.map(u=>u.id)}),d}catch(d){if(d instanceof Error?_.warn("WORKER",`Mode file not found: ${e}, falling back to 'code'`,{message:d.message}):_.warn("WORKER",`Mode file not found: ${e}, falling back to 'code'`,{error:String(d)}),e==="code")throw new Error("Critical: code.json mode file missing");return this.loadMode("code")}let{parentId:t,overrideId:r}=s,o;try{o=this.loadMode(t)}catch(d){d instanceof Error?_.warn("WORKER",`Parent mode '${t}' not found for ${e}, falling back to 'code'`,{message:d.message}):_.warn("WORKER",`Parent mode '${t}' not found for ${e}, falling back to 'code'`,{error:String(d)}),o=this.loadMode("code")}let i;try{i=this.loadModeFile(r),_.debug("SYSTEM",`Loaded override file: ${r} for parent ${t}`)}catch(d){return d instanceof Error?_.warn("WORKER",`Override file '${r}' not found, using parent mode '${t}' only`,{message:d.message}):_.warn("WORKER",`Override file '${r}' not found, using parent mode '${t}' only`,{error:String(d)}),this.activeMode=o,o}if(!i)return _.warn("SYSTEM",`Invalid override file: ${r}, using parent mode '${t}' only`),this.activeMode=o,o;let a=this.deepMerge(o,i);return this.activeMode=a,_.debug("SYSTEM",`Loaded mode with inheritance: ${a.name} (${e} = ${t} + ${r})`,void 0,{parent:t,override:r,types:a.observation_types.map(d=>d.id),concepts:a.observation_concepts.map(d=>d.id)}),a}getActiveMode(){if(!this.activeMode)throw new Error("No mode loaded. Call loadMode() first.");return this.activeMode}getObservationTypes(){return this.getActiveMode().observation_types}getTypeIcon(e){return this.getObservationTypes().find(t=>t.id===e)?.emoji||"\u{1F4DD}"}getWorkEmoji(e){return this.getObservationTypes().find(t=>t.id===e)?.work_emoji||"\u{1F4DD}"}};function Pe(){let n=k.settings(),e=K.loadFromFile(n),s=D.getInstance().getActiveMode(),t=new Set(s.observation_types.map(o=>o.id)),r=new Set(s.observation_concepts.map(o=>o.id));return{totalObservationCount:parseInt(e.CLAUDE_MEM_CONTEXT_OBSERVATIONS,10),fullObservationCount:parseInt(e.CLAUDE_MEM_CONTEXT_FULL_COUNT,10),sessionCount:parseInt(e.CLAUDE_MEM_CONTEXT_SESSION_COUNT,10),showReadTokens:e.CLAUDE_MEM_CONTEXT_SHOW_READ_TOKENS==="true",showWorkTokens:e.CLAUDE_MEM_CONTEXT_SHOW_WORK_TOKENS==="true",showSavingsAmount:e.CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT==="true",showSavingsPercent:e.CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT==="true",observationTypes:t,observationConcepts:r,fullObservationField:e.CLAUDE_MEM_CONTEXT_FULL_FIELD,showLastSummary:e.CLAUDE_MEM_CONTEXT_SHOW_LAST_SUMMARY==="true",showLastMessage:e.CLAUDE_MEM_CONTEXT_SHOW_LAST_MESSAGE==="true"}}var E={reset:"\x1B[0m",bright:"\x1B[1m",dim:"\x1B[2m",cyan:"\x1B[36m",green:"\x1B[32m",yellow:"\x1B[33m",blue:"\x1B[34m",magenta:"\x1B[35m",gray:"\x1B[90m",red:"\x1B[31m"},$e=4,Xe=1;function He(n){let e=(n.title?.length||0)+(n.subtitle?.length||0)+(n.narrative?.length||0)+JSON.stringify(n.facts||[]).length;return Math.ceil(e/$e)}function ue(n){let e=n.length,s=n.reduce((i,a)=>i+He(a),0),t=n.reduce((i,a)=>i+(a.discovery_tokens||0),0),r=t-s,o=t>0?Math.round(r/t*100):0;return{totalObservations:e,totalReadTokens:s,totalDiscoveryTokens:t,savings:r,savingsPercent:o}}function st(n){return D.getInstance().getWorkEmoji(n)}function $(n,e){let s=He(n),t=n.discovery_tokens||0,r=st(n.type),o=t>0?`${r} ${t.toLocaleString()}`:"-";return{readTokens:s,discoveryTokens:t,discoveryDisplay:o,workEmoji:r}}function q(n){return n.showReadTokens||n.showWorkTokens||n.showSavingsAmount||n.showSavingsPercent}var Ge=x(require("path"),1),J=require("fs");function Be(n,e,s,t){let r=Array.from(s.observationTypes),o=r.map(()=>"?").join(","),i=Array.from(s.observationConcepts),a=i.map(()=>"?").join(","),d=e.map(()=>"?").join(",");return n.db.prepare(`
|
|
766
|
+
`).run(s,e.content_session_id,e.prompt_number,e.prompt_text,e.created_at,e.created_at_epoch).lastInsertRowid}}};var $e=require("os"),He=$(require("path"),1),Ge=require("child_process");var Y=require("fs"),F=$(require("path"),1);var G={isWorktree:!1,worktreeName:null,parentRepoPath:null,parentProjectName:null};function Fe(r){let e=F.default.join(r,".git"),s;try{s=(0,Y.statSync)(e)}catch(u){return u instanceof Error&&u.code!=="ENOENT"&&E.warn("GIT","Unexpected error checking .git",{error:u instanceof Error?u.message:String(u)}),G}if(!s.isFile())return G;let t;try{t=(0,Y.readFileSync)(e,"utf-8").trim()}catch(u){return E.warn("GIT","Failed to read .git file",{error:u instanceof Error?u.message:String(u)}),G}let n=t.match(/^gitdir:\s*(.+)$/);if(!n)return G;let i=F.default.resolve(F.default.dirname(e),n[1]).match(/^(.+)[/\\]\.git[/\\]worktrees[/\\]([^/\\]+)$/);if(!i)return G;let a=i[1],d=F.default.basename(r),_=F.default.basename(a);return{isWorktree:!0,worktreeName:d,parentRepoPath:a,parentProjectName:_}}function Xe(r){return r==="~"||r.startsWith("~/")?r.replace(/^~/,(0,$e.homedir)()):r}function ct(r){try{return(0,Ge.execFileSync)("git",["rev-parse","--show-toplevel"],{cwd:r,encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim()||null}catch(e){let s=e instanceof Error?e:new Error(String(e));return E.debug("PROJECT_NAME","git rev-parse failed, falling back to basename",{dir:r},s),null}}function pt(r){if(!r||r.trim()==="")return E.warn("PROJECT_NAME","Empty cwd provided, using fallback",{cwd:r}),"unknown-project";let e=Xe(r),t=ct(e)??e,n=He.default.basename(t);if(n===""){if(process.platform==="win32"){let i=r.match(/^([A-Z]):\\/i);if(i){let d=`drive-${i[1].toUpperCase()}`;return E.info("PROJECT_NAME","Drive root detected",{cwd:r,projectName:d}),d}}return E.warn("PROJECT_NAME","Root directory detected, using fallback",{cwd:r}),"unknown-project"}return n}function Be(r){let e=pt(r);if(!r)return{primary:e,parent:null,isWorktree:!1,allProjects:[e]};let s=Xe(r),t=Fe(s);if(t.isWorktree&&t.parentProjectName){let n=`${t.parentProjectName}/${e}`;return{primary:n,parent:t.parentProjectName,isWorktree:!0,allProjects:[t.parentProjectName,n]}}return{primary:e,parent:null,isWorktree:!1,allProjects:[e]}}var Q=require("fs"),pe=require("path"),le=require("os");var ce={HEALTH_CHECK:3e3,API_REQUEST:3e4,HOOK_READINESS_WAIT:1e4,POST_SPAWN_WAIT:15e3,READINESS_WAIT:3e4,PORT_IN_USE_WAIT:3e3,POWERSHELL_COMMAND:1e4,WINDOWS_MULTIPLIER:1.5};function je(r){return process.platform==="win32"?Math.round(r*ce.WINDOWS_MULTIPLIER):r}var J=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(je(ce.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,pe.join)((0,le.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,pe.join)((0,le.homedir)(),".claude-mem","transcript-watch.json"),CLAUDE_MEM_CODEX_TRANSCRIPT_INGESTION:"false",CLAUDE_MEM_MAX_CONCURRENT_AGENTS:"2",CLAUDE_MEM_HOOK_FAIL_LOUD_THRESHOLD:"3",CLAUDE_MEM_EXCLUDED_PROJECTS:"",CLAUDE_MEM_FOLDER_MD_EXCLUDE:"[]",CLAUDE_MEM_FOLDER_MD_SKELETON_DENYLIST:"[]",CLAUDE_MEM_SEMANTIC_INJECT:"false",CLAUDE_MEM_SEMANTIC_INJECT_LIMIT:"5",CLAUDE_MEM_TIER_ROUTING_ENABLED:"true",CLAUDE_MEM_TIER_SIMPLE_MODEL:"haiku",CLAUDE_MEM_TIER_SUMMARY_MODEL:"",CLAUDE_MEM_TIER_FAST_MODEL:"haiku",CLAUDE_MEM_TIER_SMART_MODEL:"sonnet",CLAUDE_MEM_CHROMA_ENABLED:"true",CLAUDE_MEM_CHROMA_MODE:"local",CLAUDE_MEM_CHROMA_HOST:"127.0.0.1",CLAUDE_MEM_CHROMA_PORT:"8000",CLAUDE_MEM_CHROMA_SSL:"false",CLAUDE_MEM_CHROMA_API_KEY:"",CLAUDE_MEM_CHROMA_TENANT:"default_tenant",CLAUDE_MEM_CHROMA_DATABASE:"default_database",CLAUDE_MEM_CHROMA_PREWARM_TIMEOUT_MS:"120000",CLAUDE_MEM_TELEGRAM_ENABLED:"true",CLAUDE_MEM_TELEGRAM_BOT_TOKEN:"",CLAUDE_MEM_TELEGRAM_CHAT_ID:"",CLAUDE_MEM_TELEGRAM_TRIGGER_TYPES:"security_alert",CLAUDE_MEM_TELEGRAM_TRIGGER_CONCEPTS:"",CLAUDE_MEM_QUEUE_ENGINE:"sqlite",CLAUDE_MEM_REDIS_URL:"",CLAUDE_MEM_REDIS_HOST:"127.0.0.1",CLAUDE_MEM_REDIS_PORT:"6379",CLAUDE_MEM_REDIS_MODE:"external",CLAUDE_MEM_QUEUE_REDIS_PREFIX:`claude_mem_${process.env.CLAUDE_MEM_WORKER_PORT??String(37700+(process.getuid?.()??77)%100)}`,CLAUDE_MEM_AUTH_MODE:"api-key",CLAUDE_MEM_RUNTIME:"worker",CLAUDE_MEM_SERVER_URL:`http://127.0.0.1:${process.env.CLAUDE_MEM_SERVER_PORT??String(37877+(process.getuid?.()??77)%100)}`,CLAUDE_MEM_SERVER_API_KEY:"",CLAUDE_MEM_SERVER_PROJECT_ID:"",CLAUDE_MEM_SERVER_BETA_URL:`http://127.0.0.1:${process.env.CLAUDE_MEM_SERVER_PORT??String(37877+(process.getuid?.()??77)%100)}`,CLAUDE_MEM_SERVER_BETA_API_KEY:"",CLAUDE_MEM_SERVER_BETA_PROJECT_ID:""};static getAllDefaults(){return{...this.DEFAULTS}}static get(e){return process.env[e]??this.DEFAULTS[e]}static getInt(e){let s=this.get(e);return parseInt(s,10)}static applyEnvOverrides(e){let s={...e};for(let t of Object.keys(this.DEFAULTS))process.env[t]!==void 0&&(s[t]=process.env[t]);return s}static loadFromFile(e,s=!0){try{if(!(0,Q.existsSync)(e)){let a=this.getAllDefaults();try{ne(e,a),console.warn("[SETTINGS] Created settings file with defaults:",e)}catch(d){console.warn("[SETTINGS] Failed to create settings file, using in-memory defaults:",e,d instanceof Error?d.message:String(d))}return s?this.applyEnvOverrides(a):a}let t=(0,Q.readFileSync)(e,"utf-8"),n=k(t),o=n;if(n.env&&typeof n.env=="object"){o=n.env;try{ne(e,o),console.warn("[SETTINGS] Migrated settings file from nested to flat schema:",e)}catch(a){console.warn("[SETTINGS] Failed to auto-migrate settings file:",e,a instanceof Error?a.message:String(a))}}let i={...this.DEFAULTS};for(let a of Object.keys(this.DEFAULTS))o[a]!==void 0&&(i[a]=o[a]);return s?this.applyEnvOverrides(i):i}catch(t){console.warn("[SETTINGS] Failed to load settings, using defaults:",e,t instanceof Error?t.message:String(t));let n=this.getAllDefaults();return s?this.applyEnvOverrides(n):n}}};var X=require("fs"),z=require("path");var M=class r{static instance=null;activeMode=null;modesDir;constructor(){let e=Ae(),s=[...process.env.CLAUDE_MEM_MODES_DIR?[process.env.CLAUDE_MEM_MODES_DIR]:[],(0,z.join)(e,"modes"),(0,z.join)(e,"..","plugin","modes")],t=s.find(n=>(0,X.existsSync)(n));this.modesDir=t||s[0]}static getInstance(){return r.instance||(r.instance=new r),r.instance}parseInheritance(e){let s=e.split("--");if(s.length===1)return{hasParent:!1,parentId:"",overrideId:""};if(s.length>2)throw new Error(`Invalid mode inheritance: ${e}. Only one level of inheritance supported (parent--override)`);return{hasParent:!0,parentId:s[0],overrideId:e}}isPlainObject(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}deepMerge(e,s){let t={...e};for(let n in s){let o=s[n],i=e[n];this.isPlainObject(o)&&this.isPlainObject(i)?t[n]=this.deepMerge(i,o):t[n]=o}return t}loadModeFile(e){let s=(0,z.join)(this.modesDir,`${e}.json`);if(!(0,X.existsSync)(s))throw new Error(`Mode file not found: ${s}`);let t=(0,X.readFileSync)(s,"utf-8");return JSON.parse(t)}loadMode(e){let s=this.parseInheritance(e);if(!s.hasParent)try{let d=this.loadModeFile(e);return this.activeMode=d,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:t,overrideId:n}=s,o;try{o=this.loadMode(t)}catch(d){d instanceof Error?E.warn("WORKER",`Parent mode '${t}' not found for ${e}, falling back to 'code'`,{message:d.message}):E.warn("WORKER",`Parent mode '${t}' not found for ${e}, falling back to 'code'`,{error:String(d)}),o=this.loadMode("code")}let i;try{i=this.loadModeFile(n),E.debug("SYSTEM",`Loaded override file: ${n} for parent ${t}`)}catch(d){return d instanceof Error?E.warn("WORKER",`Override file '${n}' not found, using parent mode '${t}' only`,{message:d.message}):E.warn("WORKER",`Override file '${n}' not found, using parent mode '${t}' only`,{error:String(d)}),this.activeMode=o,o}if(!i)return E.warn("SYSTEM",`Invalid override file: ${n}, using parent mode '${t}' 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} = ${t} + ${n})`,void 0,{parent:t,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(t=>t.id===e)?.emoji||"\u{1F4DD}"}getWorkEmoji(e){return this.getObservationTypes().find(t=>t.id===e)?.work_emoji||"\u{1F4DD}"}};function We(){let r=H.settings(),e=J.loadFromFile(r),s=M.getInstance().getActiveMode(),t=new Set(s.observation_types.map(o=>o.id)),n=new Set(s.observation_concepts.map(o=>o.id));return{totalObservationCount:parseInt(e.CLAUDE_MEM_CONTEXT_OBSERVATIONS,10),fullObservationCount:parseInt(e.CLAUDE_MEM_CONTEXT_FULL_COUNT,10),sessionCount:parseInt(e.CLAUDE_MEM_CONTEXT_SESSION_COUNT,10),showReadTokens:e.CLAUDE_MEM_CONTEXT_SHOW_READ_TOKENS==="true",showWorkTokens:e.CLAUDE_MEM_CONTEXT_SHOW_WORK_TOKENS==="true",showSavingsAmount:e.CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT==="true",showSavingsPercent:e.CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT==="true",observationTypes:t,observationConcepts: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 m={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"},Ve=4,qe=1;function Ke(r){let e=(r.title?.length||0)+(r.subtitle?.length||0)+(r.narrative?.length||0)+JSON.stringify(r.facts||[]).length;return Math.ceil(e/Ve)}function Te(r){let e=r.length,s=r.reduce((i,a)=>i+Ke(a),0),t=r.reduce((i,a)=>i+(a.discovery_tokens||0),0),n=t-s,o=t>0?Math.round(n/t*100):0;return{totalObservations:e,totalReadTokens:s,totalDiscoveryTokens:t,savings:n,savingsPercent:o}}function lt(r){return M.getInstance().getWorkEmoji(r)}function B(r,e){let s=Ke(r),t=r.discovery_tokens||0,n=lt(r.type),o=t>0?`${n} ${t.toLocaleString()}`:"-";return{readTokens:s,discoveryTokens:t,discoveryDisplay:o,workEmoji:n}}function Z(r){return r.showReadTokens||r.showWorkTokens||r.showSavingsAmount||r.showSavingsPercent}var Ye=$(require("path"),1),ee=require("fs");function Je(r,e,s,t){let n=Array.from(s.observationTypes),o=n.map(()=>"?").join(","),i=Array.from(s.observationConcepts),a=i.map(()=>"?").join(","),d=e.map(()=>"?").join(",");return r.db.prepare(`
|
|
760
767
|
SELECT
|
|
761
768
|
o.id,
|
|
762
769
|
o.memory_session_id,
|
|
@@ -785,7 +792,7 @@ ${h.stack??""}
|
|
|
785
792
|
)
|
|
786
793
|
ORDER BY o.created_at_epoch DESC
|
|
787
794
|
LIMIT ?
|
|
788
|
-
`).all(...e,...e,t??null,t??null,...
|
|
795
|
+
`).all(...e,...e,t??null,t??null,...n,...i,s.totalObservationCount)}function Qe(r,e,s,t){let n=e.map(()=>"?").join(",");return r.db.prepare(`
|
|
789
796
|
SELECT
|
|
790
797
|
ss.id,
|
|
791
798
|
ss.memory_session_id,
|
|
@@ -800,19 +807,19 @@ ${h.stack??""}
|
|
|
800
807
|
ss.project
|
|
801
808
|
FROM session_summaries ss
|
|
802
809
|
LEFT JOIN sdk_sessions s ON ss.memory_session_id = s.memory_session_id
|
|
803
|
-
WHERE (ss.project IN (${
|
|
804
|
-
OR ss.merged_into_project IN (${
|
|
810
|
+
WHERE (ss.project IN (${n})
|
|
811
|
+
OR ss.merged_into_project IN (${n}))
|
|
805
812
|
AND (? IS NULL OR s.platform_source = ?)
|
|
806
813
|
ORDER BY ss.created_at_epoch DESC
|
|
807
814
|
LIMIT ?
|
|
808
|
-
`).all(...e,...e,t??null,t??null,s.sessionCount+
|
|
809
|
-
`).filter(
|
|
815
|
+
`).all(...e,...e,t??null,t??null,s.sessionCount+qe)}function Tt(r){return r.replace(/[/.]/g,"-")}function gt(r){if(!r.includes('"type":"assistant"'))return null;let e=JSON.parse(r);if(e.type==="assistant"&&e.message?.content&&Array.isArray(e.message.content)){let s="";for(let t of e.message.content)t.type==="text"&&(s+=t.text);if(s=s.replace(ke,"").trim(),s)return s}return null}function St(r){for(let e=r.length-1;e>=0;e--)try{let s=gt(r[e]);if(s)return s}catch(s){s instanceof Error?E.debug("WORKER","Skipping malformed transcript line",{lineIndex:e},s):E.debug("WORKER","Skipping malformed transcript line",{lineIndex:e,error:String(s)});continue}return""}function ft(r){try{if(!(0,ee.existsSync)(r))return{assistantMessage:""};let e=(0,ee.readFileSync)(r,"utf-8").trim();if(!e)return{assistantMessage:""};let s=e.split(`
|
|
816
|
+
`).filter(n=>n.trim());return{assistantMessage:St(s)}}catch(e){return e instanceof Error?E.failure("WORKER","Failed to extract prior messages from transcript",{transcriptPath:r},e):E.warn("WORKER","Failed to extract prior messages from transcript",{transcriptPath:r,error:String(e)}),{assistantMessage:""}}}function ze(r,e,s,t){if(!e.showLastMessage||r.length===0)return{assistantMessage:""};let n=r.find(d=>d.memory_session_id!==s);if(!n)return{assistantMessage:""};let o=n.memory_session_id,i=Tt(t),a=Ye.default.join(ie,"projects",i,`${o}.jsonl`);return ft(a)}function Ze(r,e){let s=e[0]?.id;return r.map((t,n)=>{let o=n===0?null:e[n+1];return{...t,displayEpoch:o?o.created_at_epoch:t.created_at_epoch,displayTime:o?o.created_at:t.created_at,shouldShowLink:t.id!==s}})}function es(r,e){let s=[...r.map(t=>({type:"observation",data:t})),...e.map(t=>({type:"summary",data:t}))];return s.sort((t,n)=>{let o=t.type==="observation"?t.data.created_at_epoch:t.data.displayEpoch,i=n.type==="observation"?n.data.created_at_epoch:n.data.displayEpoch;return o-i}),s}function ss(r,e){return new Set(r.slice(0,e).map(s=>s.id))}function ts(){let r=new Date,e=r.toLocaleDateString("en-CA"),s=r.toLocaleTimeString("en-US",{hour:"numeric",minute:"2-digit",hour12:!0}).toLowerCase().replace(" ",""),t=r.toLocaleTimeString("en-US",{timeZoneName:"short"}).split(" ").pop();return`${e} ${s} ${t}`}function rs(r){return[`# [${r}] recent context, ${ts()}`,""]}function ns(){return[`Legend: \u{1F3AF}session ${M.getInstance().getActiveMode().observation_types.map(s=>`${s.emoji}${s.id}`).join(" ")}`,"Format: ID TIME TYPE TITLE","Fetch details: get_observations([IDs]) | Search: mem-search skill",""]}function os(r,e){let s=[],t=[`${r.totalObservations} obs (${r.totalReadTokens.toLocaleString()}t read)`,`${r.totalDiscoveryTokens.toLocaleString()}t work`];return r.totalDiscoveryTokens>0&&(e.showSavingsAmount||e.showSavingsPercent)&&(e.showSavingsPercent?t.push(`${r.savingsPercent}% savings`):e.showSavingsAmount&&t.push(`${r.savings.toLocaleString()}t saved`)),s.push(`Stats: ${t.join(" | ")}`),s.push(""),s}function is(r){return[`### ${r}`]}function as(r){return r.toLowerCase().replace(" am","a").replace(" pm","p")}function ds(r,e,s){let t=r.title||"Untitled",n=M.getInstance().getTypeIcon(r.type),o=e?as(e):'"';return`${r.id} ${o} ${n} ${t}`}function _s(r,e,s,t){let n=[],o=r.title||"Untitled",i=M.getInstance().getTypeIcon(r.type),a=e?as(e):'"',{readTokens:d,discoveryDisplay:_}=B(r,t);n.push(`**${r.id}** ${a} ${i} **${o}**`),s&&n.push(s);let u=[];return t.showReadTokens&&u.push(`~${d}t`),t.showWorkTokens&&u.push(_),u.length>0&&n.push(u.join(" ")),n.push(""),n}function Es(r,e){return[`S${r.id} ${r.request||"Session started"} (${e})`]}function j(r,e){return e?[`**${r}**: ${e}`,""]:[]}function us(r){return r.assistantMessage?["","---","","**Previously**","",`A: ${r.assistantMessage}`,""]:[]}function ms(r,e){return["",`Access ${Math.round(r/1e3)}k tokens of past work via get_observations([IDs]) or mem-search skill.`]}function cs(r){return`# [${r}] recent context, ${ts()}
|
|
810
817
|
|
|
811
|
-
No previous sessions found.`}function
|
|
812
|
-
${
|
|
813
|
-
${
|
|
818
|
+
No previous sessions found.`}function ps(){let r=new Date,e=r.toLocaleDateString("en-CA"),s=r.toLocaleTimeString("en-US",{hour:"numeric",minute:"2-digit",hour12:!0}).toLowerCase().replace(" ",""),t=r.toLocaleTimeString("en-US",{timeZoneName:"short"}).split(" ").pop();return`${e} ${s} ${t}`}function ls(r){return["",`${m.bright}${m.cyan}[${r}] recent context, ${ps()}${m.reset}`,`${m.gray}${"\u2500".repeat(60)}${m.reset}`,""]}function Ts(){let e=M.getInstance().getActiveMode().observation_types.map(s=>`${s.emoji} ${s.id}`).join(" | ");return[`${m.dim}Legend: session-request | ${e}${m.reset}`,""]}function gs(){return[`${m.bright}Column Key${m.reset}`,`${m.dim} Read: Tokens to read this observation (cost to learn it now)${m.reset}`,`${m.dim} Work: Tokens spent on work that produced this record ( research, building, deciding)${m.reset}`,""]}function Ss(){return[`${m.dim}Context Index: This semantic index (titles, types, files, tokens) is usually sufficient to understand past work.${m.reset}`,"",`${m.dim}When you need implementation details, rationale, or debugging context:${m.reset}`,`${m.dim} - Fetch by ID: get_observations([IDs]) for observations visible in this index${m.reset}`,`${m.dim} - Search history: Use the mem-search skill for past decisions, bugs, and deeper research${m.reset}`,`${m.dim} - Trust this index over re-reading code for past decisions and learnings${m.reset}`,""]}function fs(r,e){let s=[];if(s.push(`${m.bright}${m.cyan}Context Economics${m.reset}`),s.push(`${m.dim} Loading: ${r.totalObservations} observations (${r.totalReadTokens.toLocaleString()} tokens to read)${m.reset}`),s.push(`${m.dim} Work investment: ${r.totalDiscoveryTokens.toLocaleString()} tokens spent on research, building, and decisions${m.reset}`),r.totalDiscoveryTokens>0&&(e.showSavingsAmount||e.showSavingsPercent)){let t=" Your savings: ";e.showSavingsAmount&&e.showSavingsPercent?t+=`${r.savings.toLocaleString()} tokens (${r.savingsPercent}% reduction from reuse)`:e.showSavingsAmount?t+=`${r.savings.toLocaleString()} tokens`:t+=`${r.savingsPercent}% reduction from reuse`,s.push(`${m.green}${t}${m.reset}`)}return s.push(""),s}function Rs(r){return[`${m.bright}${m.cyan}${r}${m.reset}`,""]}function Os(r){return[`${m.dim}${r}${m.reset}`]}function bs(r,e,s,t){let n=r.title||"Untitled",o=M.getInstance().getTypeIcon(r.type),{readTokens:i,discoveryTokens:a,workEmoji:d}=B(r,t),_=s?`${m.dim}${e}${m.reset}`:" ".repeat(e.length),u=t.showReadTokens&&i>0?`${m.dim}(~${i}t)${m.reset}`:"",c=t.showWorkTokens&&a>0?`${m.dim}(${d} ${a.toLocaleString()}t)${m.reset}`:"";return` ${m.dim}#${r.id}${m.reset} ${_} ${o} ${n} ${u} ${c}`}function hs(r,e,s,t,n){let o=[],i=r.title||"Untitled",a=M.getInstance().getTypeIcon(r.type),{readTokens:d,discoveryTokens:_,workEmoji:u}=B(r,n),c=s?`${m.dim}${e}${m.reset}`:" ".repeat(e.length),p=n.showReadTokens&&d>0?`${m.dim}(~${d}t)${m.reset}`:"",g=n.showWorkTokens&&_>0?`${m.dim}(${u} ${_.toLocaleString()}t)${m.reset}`:"";return o.push(` ${m.dim}#${r.id}${m.reset} ${c} ${a} ${m.bright}${i}${m.reset}`),t&&o.push(` ${m.dim}${t}${m.reset}`),(p||g)&&o.push(` ${p} ${g}`),o.push(""),o}function Is(r,e){let s=`${r.request||"Session started"} (${e})`;return[`${m.yellow}#S${r.id}${m.reset} ${s}`,""]}function W(r,e,s){return e?[`${s}${r}:${m.reset} ${e}`,""]:[]}function Ns(r){return r.assistantMessage?["","---","",`${m.bright}${m.magenta}Previously${m.reset}`,"",`${m.dim}A: ${r.assistantMessage}${m.reset}`,""]:[]}function As(r,e){let s=Math.round(r/1e3);return["",`${m.dim}Access ${s}k tokens of past research & decisions for just ${e.toLocaleString()}t. Use the claude-mem skill to access memories by ID.${m.reset}`]}function Cs(r){return`
|
|
819
|
+
${m.bright}${m.cyan}[${r}] recent context, ${ps()}${m.reset}
|
|
820
|
+
${m.gray}${"\u2500".repeat(60)}${m.reset}
|
|
814
821
|
|
|
815
|
-
${
|
|
816
|
-
`}function
|
|
817
|
-
`):null}function
|
|
818
|
-
`).trimEnd()}var
|
|
822
|
+
${m.dim}No previous sessions found for this project yet.${m.reset}
|
|
823
|
+
`}function Ls(r,e,s,t){let n=[];return t?n.push(...ls(r)):n.push(...rs(r)),t?n.push(...Ts()):n.push(...ns()),t&&(n.push(...gs()),n.push(...Ss())),Z(s)&&(t?n.push(...fs(e,s)):n.push(...os(e,s))),n}var ge=$(require("path"),1);function re(r){if(!r)return[];try{let e=JSON.parse(r);return Array.isArray(e)?e:[]}catch(e){return E.debug("PARSER","Failed to parse JSON array, using empty fallback",{preview:r?.substring(0,50)},e instanceof Error?e:new Error(String(e))),[]}}function Se(r){return new Date(r).toLocaleString("en-US",{month:"short",day:"numeric",hour:"numeric",minute:"2-digit",hour12:!0})}function fe(r){return new Date(r).toLocaleString("en-US",{hour:"numeric",minute:"2-digit",hour12:!0})}function Ms(r){return new Date(r).toLocaleString("en-US",{month:"short",day:"numeric",year:"numeric"})}function Ds(r,e){return ge.default.isAbsolute(r)?ge.default.relative(e,r):r}function vs(r,e,s){let t=re(r);if(t.length>0)return Ds(t[0],e);if(s){let n=re(s);if(n.length>0)return Ds(n[0],e)}return"General"}function Rt(r){let e=new Map;for(let t of r){let n=t.type==="observation"?t.data.created_at:t.data.displayTime,o=Ms(n);e.has(o)||e.set(o,[]),e.get(o).push(t)}let s=Array.from(e.entries()).sort((t,n)=>{let o=new Date(t[0]).getTime(),i=new Date(n[0]).getTime();return o-i});return new Map(s)}function ys(r,e){return e.fullObservationField==="narrative"?r.narrative:r.facts?re(r.facts).join(`
|
|
824
|
+
`):null}function Ot(r,e,s,t){let n=[];n.push(...is(r));let o="";for(let i of e)if(i.type==="summary"){let a=i.data,d=Se(a.displayTime);n.push(...Es(a,d))}else{let a=i.data,d=fe(a.created_at),u=d!==o?d:"";if(o=d,s.has(a.id)){let p=ys(a,t);n.push(..._s(a,u,p,t))}else n.push(ds(a,u,t))}return n}function bt(r,e,s,t,n){let o=[];o.push(...Rs(r));let i=null,a="";for(let d of e)if(d.type==="summary"){i=null,a="";let _=d.data,u=Se(_.displayTime);o.push(...Is(_,u))}else{let _=d.data,u=vs(_.files_modified,n,_.files_read),c=fe(_.created_at),p=c!==a;a=c;let g=s.has(_.id);if(u!==i&&(o.push(...Os(u)),i=u),g){let I=ys(_,t);o.push(...hs(_,c,p,I,t))}else o.push(bs(_,c,p,t))}return o.push(""),o}function ht(r,e,s,t,n,o){return o?bt(r,e,s,t,n):Ot(r,e,s,t)}function Us(r,e,s,t,n){let o=[],i=Rt(r);for(let[a,d]of i)o.push(...ht(a,d,e,s,t,n));return o}function xs(r,e,s){return!(!r.showLastSummary||!e||!!!(e.investigated||e.learned||e.completed||e.next_steps)||s&&e.created_at_epoch<=s.created_at_epoch)}function ks(r,e){let s=[];return e?(s.push(...W("Investigated",r.investigated,m.blue)),s.push(...W("Learned",r.learned,m.yellow)),s.push(...W("Completed",r.completed,m.green)),s.push(...W("Next Steps",r.next_steps,m.magenta))):(s.push(...j("Investigated",r.investigated)),s.push(...j("Learned",r.learned)),s.push(...j("Completed",r.completed)),s.push(...j("Next Steps",r.next_steps))),s}function ws(r,e){return e?Ns(r):us(r)}function Ps(r,e,s){return!Z(e)||r.totalDiscoveryTokens<=0||r.savings<=0?[]:s?As(r.totalDiscoveryTokens,r.totalReadTokens):ms(r.totalDiscoveryTokens,r.totalReadTokens)}var It=Fs.default.join((0,$s.homedir)(),".claude","plugins","marketplaces","thedotmack","plugin",".install-version");function Nt(){try{return new K}catch(r){if(r instanceof Error&&r.code==="ERR_DLOPEN_FAILED"){try{(0,Hs.unlinkSync)(It)}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 r}}function At(r,e){return e?Cs(r):cs(r)}function Ct(r,e,s,t,n,o,i){let a=[],d=Te(e);a.push(...Ls(r,d,t,i));let _=s.slice(0,t.sessionCount),u=Ze(_,s),c=es(e,u),p=ss(e,t.fullObservationCount);a.push(...Us(c,p,t,n,i));let g=s[0],I=e[0];xs(t,g,I)&&a.push(...ks(g,i));let h=ze(e,t,o,n);return a.push(...ws(h,i)),a.push(...Ps(d,t,i)),a.join(`
|
|
825
|
+
`).trimEnd()}var Lt=new Set(["bugfix","discovery","decision","refactor"]);function Dt(r,e,s){let t=Te(r),n={bugfix:0,discovery:0,decision:0,refactor:0,other:0},o=new Set,i=Number.POSITIVE_INFINITY;for(let d of r){let _=Lt.has(d.type)?d.type:"other";n[_]++,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:r.length,session_count:o.size,timeline_depth_days:a,has_session_summary:e.length>0,obs_type_bugfix:n.bugfix,obs_type_discovery:n.discovery,obs_type_decision:n.decision,obs_type_refactor:n.refactor,obs_type_other:n.other,tokens_injected:t.totalReadTokens,tokens_saved_vs_naive:t.savings,search_strategy:s?"full":"timeline"}}async function Re(r,e=!1){let s=We(),t=r?.cwd??process.cwd(),n=Be(t),o=r?.projects?.length?r.projects:n.allProjects,i=o[o.length-1]??n.primary;r?.full&&(s.totalObservationCount=999999,s.sessionCount=999999);let a=Nt();if(!a)return{text:"",stats:null};try{let d=r?.platformSource?C(r.platformSource):void 0,_=o.length>1?o:[i],u=Je(a,_,s,d),c=Qe(a,_,s,d);return u.length===0&&c.length===0?{text:At(i,e),stats:null}:{text:Ct(i,u,c,s,t,r?.session_id,e),stats:Dt(u,c,!!r?.full)}}finally{a.close()}}async function Gs(r,e=!1){return(await Re(r,e)).text}0&&(module.exports={generateContext,generateContextWithStats});
|