open-mem 0.4.0 → 0.4.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.
Files changed (56) hide show
  1. package/README.md +116 -28
  2. package/dist/ai/compressor.d.ts +1 -0
  3. package/dist/ai/compressor.d.ts.map +1 -1
  4. package/dist/ai/parser.d.ts +1 -0
  5. package/dist/ai/parser.d.ts.map +1 -1
  6. package/dist/ai/provider.d.ts +2 -1
  7. package/dist/ai/provider.d.ts.map +1 -1
  8. package/dist/ai/rate-limiter.d.ts +9 -0
  9. package/dist/ai/rate-limiter.d.ts.map +1 -0
  10. package/dist/ai/summarizer.d.ts +1 -0
  11. package/dist/ai/summarizer.d.ts.map +1 -1
  12. package/dist/config.d.ts.map +1 -1
  13. package/dist/context/builder.d.ts.map +1 -1
  14. package/dist/db/database.d.ts +4 -0
  15. package/dist/db/database.d.ts.map +1 -1
  16. package/dist/db/observations.d.ts +7 -0
  17. package/dist/db/observations.d.ts.map +1 -1
  18. package/dist/db/pending.d.ts.map +1 -1
  19. package/dist/db/schema.d.ts.map +1 -1
  20. package/dist/db/sessions.d.ts +1 -0
  21. package/dist/db/sessions.d.ts.map +1 -1
  22. package/dist/db/summaries.d.ts +1 -0
  23. package/dist/db/summaries.d.ts.map +1 -1
  24. package/dist/hooks/chat-capture.d.ts +20 -0
  25. package/dist/hooks/chat-capture.d.ts.map +1 -0
  26. package/dist/hooks/session-events.d.ts +3 -2
  27. package/dist/hooks/session-events.d.ts.map +1 -1
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +90 -53
  30. package/dist/mcp.d.ts +3 -0
  31. package/dist/mcp.d.ts.map +1 -0
  32. package/dist/mcp.js +260 -0
  33. package/dist/queue/processor.d.ts +3 -1
  34. package/dist/queue/processor.d.ts.map +1 -1
  35. package/dist/search/embeddings.d.ts +9 -0
  36. package/dist/search/embeddings.d.ts.map +1 -0
  37. package/dist/search/hybrid.d.ts +11 -0
  38. package/dist/search/hybrid.d.ts.map +1 -0
  39. package/dist/servers/mcp-server.d.ts +33 -0
  40. package/dist/servers/mcp-server.d.ts.map +1 -0
  41. package/dist/tools/export.d.ts +6 -0
  42. package/dist/tools/export.d.ts.map +1 -0
  43. package/dist/tools/import.d.ts +6 -0
  44. package/dist/tools/import.d.ts.map +1 -0
  45. package/dist/tools/recall.d.ts.map +1 -1
  46. package/dist/tools/save.d.ts.map +1 -1
  47. package/dist/tools/search.d.ts +2 -1
  48. package/dist/tools/search.d.ts.map +1 -1
  49. package/dist/tools/timeline.d.ts.map +1 -1
  50. package/dist/types.d.ts +5 -0
  51. package/dist/types.d.ts.map +1 -1
  52. package/dist/utils/agents-md.d.ts +44 -0
  53. package/dist/utils/agents-md.d.ts.map +1 -0
  54. package/dist/utils/worktree.d.ts +10 -0
  55. package/dist/utils/worktree.d.ts.map +1 -0
  56. package/package.json +7 -8
package/dist/mcp.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env bun
2
+ export {};
3
+ //# sourceMappingURL=mcp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":""}
package/dist/mcp.js ADDED
@@ -0,0 +1,260 @@
1
+ #!/usr/bin/env bun
2
+ // @bun
3
+ import{readFileSync as a}from"fs";import{join as s}from"path";import{parseArgs as HH}from"util";var b={dbPath:".open-mem/memory.db",provider:"google",apiKey:void 0,model:"gemini-2.5-flash-lite",maxTokensPerCompression:1024,compressionEnabled:!0,contextInjectionEnabled:!0,maxContextTokens:4000,batchSize:5,batchIntervalMs:30000,ignoredTools:[],minOutputLength:50,maxIndexEntries:20,sensitivePatterns:[],retentionDays:90,maxDatabaseSizeMb:500,logLevel:"warn",contextShowTokenCosts:!0,contextObservationTypes:"all",contextFullObservationCount:3,maxObservations:50,contextShowLastSummary:!0,rateLimitingEnabled:!0,folderContextEnabled:!0,folderContextMaxDepth:5};function u(){let H={};if(process.env.OPEN_MEM_DB_PATH)H.dbPath=process.env.OPEN_MEM_DB_PATH;if(process.env.OPEN_MEM_PROVIDER)H.provider=process.env.OPEN_MEM_PROVIDER;if(process.env.OPEN_MEM_MODEL)H.model=process.env.OPEN_MEM_MODEL;if(process.env.OPEN_MEM_MAX_CONTEXT_TOKENS)H.maxContextTokens=Number.parseInt(process.env.OPEN_MEM_MAX_CONTEXT_TOKENS,10);if(process.env.OPEN_MEM_COMPRESSION==="false")H.compressionEnabled=!1;if(process.env.OPEN_MEM_CONTEXT_INJECTION==="false")H.contextInjectionEnabled=!1;if(process.env.OPEN_MEM_IGNORED_TOOLS)H.ignoredTools=process.env.OPEN_MEM_IGNORED_TOOLS.split(",").map((Q)=>Q.trim());if(process.env.OPEN_MEM_BATCH_SIZE)H.batchSize=Number.parseInt(process.env.OPEN_MEM_BATCH_SIZE,10);if(process.env.OPEN_MEM_RETENTION_DAYS)H.retentionDays=Number.parseInt(process.env.OPEN_MEM_RETENTION_DAYS,10);if(process.env.OPEN_MEM_LOG_LEVEL)H.logLevel=process.env.OPEN_MEM_LOG_LEVEL;if(process.env.OPEN_MEM_CONTEXT_SHOW_TOKEN_COSTS==="false")H.contextShowTokenCosts=!1;if(process.env.OPEN_MEM_CONTEXT_TYPES)H.contextObservationTypes=process.env.OPEN_MEM_CONTEXT_TYPES==="all"?"all":process.env.OPEN_MEM_CONTEXT_TYPES.split(",").map((Q)=>Q.trim());if(process.env.OPEN_MEM_CONTEXT_FULL_COUNT)H.contextFullObservationCount=Number.parseInt(process.env.OPEN_MEM_CONTEXT_FULL_COUNT,10);if(process.env.OPEN_MEM_MAX_OBSERVATIONS)H.maxObservations=Number.parseInt(process.env.OPEN_MEM_MAX_OBSERVATIONS,10);if(process.env.OPEN_MEM_CONTEXT_SHOW_LAST_SUMMARY==="false")H.contextShowLastSummary=!1;if(process.env.OPEN_MEM_RATE_LIMITING==="false")H.rateLimitingEnabled=!1;if(process.env.OPEN_MEM_FOLDER_CONTEXT==="false")H.folderContextEnabled=!1;if(process.env.OPEN_MEM_FOLDER_CONTEXT_MAX_DEPTH)H.folderContextMaxDepth=Number.parseInt(process.env.OPEN_MEM_FOLDER_CONTEXT_MAX_DEPTH,10);return H}function q(H,Q){let X=u(),Z={...b,...X,...Q};if(!Z.dbPath.startsWith("/"))Z.dbPath=`${H}/${Z.dbPath}`;if(!process.env.OPEN_MEM_PROVIDER&&!Q?.provider){if(process.env.GOOGLE_GENERATIVE_AI_API_KEY||process.env.GEMINI_API_KEY)Z.provider="google";else if(process.env.ANTHROPIC_API_KEY)Z.provider="anthropic";else if(process.env.AWS_BEARER_TOKEN_BEDROCK||process.env.AWS_ACCESS_KEY_ID||process.env.AWS_PROFILE)Z.provider="bedrock"}if(!Z.apiKey)switch(Z.provider){case"google":Z.apiKey=process.env.GOOGLE_GENERATIVE_AI_API_KEY||process.env.GEMINI_API_KEY;break;case"anthropic":Z.apiKey=process.env.ANTHROPIC_API_KEY;break;case"openai":Z.apiKey=process.env.OPENAI_API_KEY;break;case"bedrock":break}return Z}import{Database as c}from"bun:sqlite";import{existsSync as P,mkdirSync as p,unlinkSync as j}from"fs";class S{db;dbPath;constructor(H){this.dbPath=H,this.db=this.open(H),this.configure()}open(H){let Q=H.lastIndexOf("/");if(Q>0){let X=H.substring(0,Q);p(X,{recursive:!0})}return new c(H,{create:!0})}configure(){try{this.applyPragmas()}catch(H){console.warn("[open-mem] Database configure failed, attempting recovery by removing WAL/SHM files:",H.message);try{this.db.close()}catch{}this.deleteSidecarFiles();try{this.db=this.open(this.dbPath),this.applyPragmas(),console.warn("[open-mem] Recovery successful after removing WAL/SHM files");return}catch(Q){console.warn("[open-mem] WAL/SHM cleanup insufficient, recreating database from scratch:",Q.message);try{this.db.close()}catch{}this.deleteDatabaseFiles();try{this.db=this.open(this.dbPath),this.applyPragmas(),console.warn("[open-mem] Recovery successful after full database recreation");return}catch(X){throw console.warn("[open-mem] All recovery attempts failed, filesystem may be broken:",X.message),H}}}}applyPragmas(){this.db.exec("PRAGMA journal_mode = WAL"),this.db.exec("PRAGMA synchronous = NORMAL"),this.db.exec("PRAGMA foreign_keys = ON"),this.db.exec("PRAGMA busy_timeout = 5000")}deleteSidecarFiles(){for(let H of["-wal","-shm"]){let Q=this.dbPath+H;try{if(P(Q))j(Q)}catch{}}}deleteDatabaseFiles(){this.deleteSidecarFiles();try{if(P(this.dbPath))j(this.dbPath)}catch{}}ensureMigrationTable(){this.db.exec(`
4
+ CREATE TABLE IF NOT EXISTS _migrations (
5
+ version INTEGER PRIMARY KEY,
6
+ name TEXT NOT NULL,
7
+ applied_at TEXT NOT NULL DEFAULT (datetime('now'))
8
+ )
9
+ `)}migrate(H){this.ensureMigrationTable();let Q=this.db.query("SELECT version FROM _migrations ORDER BY version").all(),X=new Set(Q.map((z)=>z.version)),Z=H.filter((z)=>!X.has(z.version)).sort((z,W)=>z.version-W.version);for(let z of Z)this.db.transaction(()=>{this.db.exec(z.up),this.db.query("INSERT INTO _migrations (version, name) VALUES ($version, $name)").run({$version:z.version,$name:z.name})})()}run(H,Q){let X=this.db.query(H);if(Q)X.run(...Q);else X.run()}get(H,Q){let X=this.db.query(H);return Q?X.get(...Q):X.get()}all(H,Q){let X=this.db.query(H);return Q?X.all(...Q):X.all()}exec(H){this.db.exec(H)}transaction(H){return this.db.transaction(H)()}close(){this.db.close()}get isOpen(){try{return this.db.query("SELECT 1").get(),!0}catch{return!1}}get raw(){return this.db}}function T(H){return new S(H)}import{randomUUID as g}from"crypto";class _{db;constructor(H){this.db=H}create(H){let Q=g(),X=new Date().toISOString(),Z=H.discoveryTokens??0;return this.db.run(`INSERT INTO observations
10
+ (id, session_id, type, title, subtitle, facts, narrative,
11
+ concepts, files_read, files_modified, raw_tool_output,
12
+ tool_name, created_at, token_count, discovery_tokens)
13
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[Q,H.sessionId,H.type,H.title,H.subtitle,JSON.stringify(H.facts),H.narrative,JSON.stringify(H.concepts),JSON.stringify(H.filesRead),JSON.stringify(H.filesModified),H.rawToolOutput,H.toolName,X,H.tokenCount,Z]),{...H,id:Q,createdAt:X,discoveryTokens:Z}}importObservation(H){this.db.run(`INSERT INTO observations
14
+ (id, session_id, type, title, subtitle, facts, narrative,
15
+ concepts, files_read, files_modified, raw_tool_output,
16
+ tool_name, created_at, token_count, discovery_tokens)
17
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[H.id,H.sessionId,H.type,H.title,H.subtitle,JSON.stringify(H.facts),H.narrative,JSON.stringify(H.concepts),JSON.stringify(H.filesRead),JSON.stringify(H.filesModified),H.rawToolOutput,H.toolName,H.createdAt,H.tokenCount,H.discoveryTokens??0])}getById(H){let Q=this.db.get("SELECT * FROM observations WHERE id = ?",[H]);return Q?this.mapRow(Q):null}getBySession(H){return this.db.all("SELECT * FROM observations WHERE session_id = ? ORDER BY created_at ASC",[H]).map((Q)=>this.mapRow(Q))}getCount(H){if(H)return this.db.get("SELECT COUNT(*) as count FROM observations WHERE session_id = ?",[H])?.count??0;return this.db.get("SELECT COUNT(*) as count FROM observations")?.count??0}getIndex(H,Q=20){return this.db.all(`SELECT o.id, o.session_id, o.type, o.title, o.token_count, o.discovery_tokens, o.created_at
18
+ FROM observations o
19
+ JOIN sessions s ON o.session_id = s.id
20
+ WHERE s.project_path = ?
21
+ ORDER BY o.created_at DESC
22
+ LIMIT ?`,[H,Q]).map((X)=>({id:X.id,sessionId:X.session_id,type:X.type,title:X.title,tokenCount:X.token_count,discoveryTokens:X.discovery_tokens??0,createdAt:X.created_at}))}search(H){let Q=`
23
+ SELECT o.*, rank
24
+ FROM observations o
25
+ JOIN observations_fts fts ON o._rowid = fts.rowid
26
+ WHERE observations_fts MATCH ?
27
+ `,X=[H.query];if(H.sessionId)Q+=" AND o.session_id = ?",X.push(H.sessionId);if(H.type)Q+=" AND o.type = ?",X.push(H.type);return Q+=" ORDER BY rank LIMIT ? OFFSET ?",X.push(H.limit??10),X.push(H.offset??0),this.db.all(Q,X).map((Z)=>({observation:this.mapRow(Z),rank:Z.rank,snippet:Z.title}))}searchByConcept(H,Q=10){return this.db.all(`SELECT o.*
28
+ FROM observations o
29
+ JOIN observations_fts fts ON o._rowid = fts.rowid
30
+ WHERE observations_fts MATCH ?
31
+ ORDER BY rank
32
+ LIMIT ?`,[`concepts:${H}`,Q]).map((X)=>this.mapRow(X))}searchByFile(H,Q=10){return this.db.all(`SELECT o.*
33
+ FROM observations o
34
+ JOIN observations_fts fts ON o._rowid = fts.rowid
35
+ WHERE observations_fts MATCH ?
36
+ ORDER BY rank
37
+ LIMIT ?`,[`files_read:"${H.replace(/"/g,'""')}" OR files_modified:"${H.replace(/"/g,'""')}"`,Q]).map((X)=>this.mapRow(X))}setEmbedding(H,Q){this.db.run("UPDATE observations SET embedding = ? WHERE id = ?",[JSON.stringify(Q),H])}getWithEmbeddings(H,Q){return this.db.all(`SELECT o.id, o.embedding, o.title
38
+ FROM observations o
39
+ JOIN sessions s ON o.session_id = s.id
40
+ WHERE s.project_path = ? AND o.embedding IS NOT NULL
41
+ ORDER BY o.created_at DESC
42
+ LIMIT ?`,[H,Q]).map((X)=>{try{return{id:X.id,embedding:JSON.parse(X.embedding),title:X.title}}catch{return null}}).filter((X)=>X!==null)}mapRow(H){return{id:H.id,sessionId:H.session_id,type:H.type,title:H.title,subtitle:H.subtitle,facts:JSON.parse(H.facts),narrative:H.narrative,concepts:JSON.parse(H.concepts),filesRead:JSON.parse(H.files_read),filesModified:JSON.parse(H.files_modified),rawToolOutput:H.raw_tool_output,toolName:H.tool_name,createdAt:H.created_at,tokenCount:H.token_count,discoveryTokens:H.discovery_tokens??0}}}var l=[{version:1,name:"create-core-tables",up:`
43
+ -- Sessions table
44
+ CREATE TABLE IF NOT EXISTS sessions (
45
+ _rowid INTEGER PRIMARY KEY AUTOINCREMENT,
46
+ id TEXT UNIQUE NOT NULL,
47
+ project_path TEXT NOT NULL,
48
+ started_at TEXT NOT NULL DEFAULT (datetime('now')),
49
+ ended_at TEXT,
50
+ status TEXT NOT NULL DEFAULT 'active'
51
+ CHECK (status IN ('active', 'idle', 'completed')),
52
+ observation_count INTEGER NOT NULL DEFAULT 0,
53
+ summary_id TEXT
54
+ );
55
+
56
+ CREATE INDEX IF NOT EXISTS idx_sessions_project
57
+ ON sessions(project_path);
58
+ CREATE INDEX IF NOT EXISTS idx_sessions_status
59
+ ON sessions(status);
60
+ CREATE INDEX IF NOT EXISTS idx_sessions_started
61
+ ON sessions(started_at DESC);
62
+
63
+ -- Observations table
64
+ CREATE TABLE IF NOT EXISTS observations (
65
+ _rowid INTEGER PRIMARY KEY AUTOINCREMENT,
66
+ id TEXT UNIQUE NOT NULL,
67
+ session_id TEXT NOT NULL,
68
+ type TEXT NOT NULL
69
+ CHECK (type IN ('decision','bugfix','feature','refactor','discovery','change')),
70
+ title TEXT NOT NULL,
71
+ subtitle TEXT NOT NULL DEFAULT '',
72
+ facts TEXT NOT NULL DEFAULT '[]',
73
+ narrative TEXT NOT NULL DEFAULT '',
74
+ concepts TEXT NOT NULL DEFAULT '[]',
75
+ files_read TEXT NOT NULL DEFAULT '[]',
76
+ files_modified TEXT NOT NULL DEFAULT '[]',
77
+ raw_tool_output TEXT NOT NULL,
78
+ tool_name TEXT NOT NULL,
79
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
80
+ token_count INTEGER NOT NULL DEFAULT 0,
81
+ FOREIGN KEY (session_id) REFERENCES sessions(id)
82
+ );
83
+
84
+ CREATE INDEX IF NOT EXISTS idx_observations_session
85
+ ON observations(session_id);
86
+ CREATE INDEX IF NOT EXISTS idx_observations_type
87
+ ON observations(type);
88
+ CREATE INDEX IF NOT EXISTS idx_observations_created
89
+ ON observations(created_at DESC);
90
+
91
+ -- Session summaries table
92
+ CREATE TABLE IF NOT EXISTS session_summaries (
93
+ _rowid INTEGER PRIMARY KEY AUTOINCREMENT,
94
+ id TEXT UNIQUE NOT NULL,
95
+ session_id TEXT NOT NULL UNIQUE,
96
+ summary TEXT NOT NULL,
97
+ key_decisions TEXT NOT NULL DEFAULT '[]',
98
+ files_modified TEXT NOT NULL DEFAULT '[]',
99
+ concepts TEXT NOT NULL DEFAULT '[]',
100
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
101
+ token_count INTEGER NOT NULL DEFAULT 0,
102
+ FOREIGN KEY (session_id) REFERENCES sessions(id)
103
+ );
104
+
105
+ -- Pending messages (queue persistence)
106
+ CREATE TABLE IF NOT EXISTS pending_messages (
107
+ _rowid INTEGER PRIMARY KEY AUTOINCREMENT,
108
+ id TEXT UNIQUE NOT NULL,
109
+ session_id TEXT NOT NULL,
110
+ tool_name TEXT NOT NULL,
111
+ tool_output TEXT NOT NULL,
112
+ call_id TEXT NOT NULL,
113
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
114
+ status TEXT NOT NULL DEFAULT 'pending'
115
+ CHECK (status IN ('pending','processing','completed','failed')),
116
+ retry_count INTEGER NOT NULL DEFAULT 0,
117
+ error TEXT,
118
+ FOREIGN KEY (session_id) REFERENCES sessions(id)
119
+ );
120
+
121
+ CREATE INDEX IF NOT EXISTS idx_pending_status
122
+ ON pending_messages(status);
123
+ CREATE INDEX IF NOT EXISTS idx_pending_session
124
+ ON pending_messages(session_id);
125
+ `},{version:2,name:"create-fts5-tables",up:`
126
+ -- FTS5 for observations (title, subtitle, narrative, facts, concepts, files)
127
+ CREATE VIRTUAL TABLE IF NOT EXISTS observations_fts USING fts5(
128
+ title,
129
+ subtitle,
130
+ narrative,
131
+ facts,
132
+ concepts,
133
+ files_read,
134
+ files_modified,
135
+ content=observations,
136
+ content_rowid=_rowid,
137
+ tokenize='porter unicode61'
138
+ );
139
+
140
+ -- Triggers to keep FTS5 in sync with observations table
141
+ CREATE TRIGGER observations_ai AFTER INSERT ON observations BEGIN
142
+ INSERT INTO observations_fts(
143
+ rowid, title, subtitle, narrative, facts, concepts,
144
+ files_read, files_modified
145
+ )
146
+ VALUES (
147
+ new._rowid, new.title, new.subtitle, new.narrative,
148
+ new.facts, new.concepts, new.files_read, new.files_modified
149
+ );
150
+ END;
151
+
152
+ CREATE TRIGGER observations_ad AFTER DELETE ON observations BEGIN
153
+ INSERT INTO observations_fts(
154
+ observations_fts, rowid, title, subtitle, narrative,
155
+ facts, concepts, files_read, files_modified
156
+ )
157
+ VALUES (
158
+ 'delete', old._rowid, old.title, old.subtitle, old.narrative,
159
+ old.facts, old.concepts, old.files_read, old.files_modified
160
+ );
161
+ END;
162
+
163
+ CREATE TRIGGER observations_au AFTER UPDATE ON observations BEGIN
164
+ INSERT INTO observations_fts(
165
+ observations_fts, rowid, title, subtitle, narrative,
166
+ facts, concepts, files_read, files_modified
167
+ )
168
+ VALUES (
169
+ 'delete', old._rowid, old.title, old.subtitle, old.narrative,
170
+ old.facts, old.concepts, old.files_read, old.files_modified
171
+ );
172
+ INSERT INTO observations_fts(
173
+ rowid, title, subtitle, narrative, facts, concepts,
174
+ files_read, files_modified
175
+ )
176
+ VALUES (
177
+ new._rowid, new.title, new.subtitle, new.narrative,
178
+ new.facts, new.concepts, new.files_read, new.files_modified
179
+ );
180
+ END;
181
+
182
+ -- FTS5 for session summaries
183
+ CREATE VIRTUAL TABLE IF NOT EXISTS summaries_fts USING fts5(
184
+ summary,
185
+ key_decisions,
186
+ concepts,
187
+ content=session_summaries,
188
+ content_rowid=_rowid,
189
+ tokenize='porter unicode61'
190
+ );
191
+
192
+ CREATE TRIGGER summaries_ai AFTER INSERT ON session_summaries BEGIN
193
+ INSERT INTO summaries_fts(rowid, summary, key_decisions, concepts)
194
+ VALUES (new._rowid, new.summary, new.key_decisions, new.concepts);
195
+ END;
196
+
197
+ CREATE TRIGGER summaries_ad AFTER DELETE ON session_summaries BEGIN
198
+ INSERT INTO summaries_fts(
199
+ summaries_fts, rowid, summary, key_decisions, concepts
200
+ )
201
+ VALUES (
202
+ 'delete', old._rowid, old.summary, old.key_decisions, old.concepts
203
+ );
204
+ END;
205
+ `},{version:3,name:"add-structured-summary-columns",up:`
206
+ ALTER TABLE session_summaries ADD COLUMN request TEXT NOT NULL DEFAULT '';
207
+ ALTER TABLE session_summaries ADD COLUMN investigated TEXT NOT NULL DEFAULT '';
208
+ ALTER TABLE session_summaries ADD COLUMN learned TEXT NOT NULL DEFAULT '';
209
+ ALTER TABLE session_summaries ADD COLUMN completed TEXT NOT NULL DEFAULT '';
210
+ ALTER TABLE session_summaries ADD COLUMN next_steps TEXT NOT NULL DEFAULT '';
211
+ `},{version:4,name:"add-discovery-tokens",up:`
212
+ ALTER TABLE observations ADD COLUMN discovery_tokens INTEGER NOT NULL DEFAULT 0;
213
+ `},{version:5,name:"add-embedding-column",up:`
214
+ ALTER TABLE observations ADD COLUMN embedding TEXT;
215
+ `}];function x(H){H.migrate(l)}class F{db;constructor(H){this.db=H}create(H,Q){let X=new Date().toISOString();return this.db.run(`INSERT INTO sessions (id, project_path, started_at, status)
216
+ VALUES (?, ?, ?, 'active')`,[H,Q,X]),this.getById(H)}getOrCreate(H,Q){let X=this.getById(H);if(X)return X;return this.create(H,Q)}getById(H){let Q=this.db.get("SELECT * FROM sessions WHERE id = ?",[H]);return Q?this.mapRow(Q):null}getRecent(H,Q=10){return this.db.all("SELECT * FROM sessions WHERE project_path = ? ORDER BY started_at DESC LIMIT ?",[H,Q]).map((X)=>this.mapRow(X))}getAll(H){return this.db.all("SELECT * FROM sessions WHERE project_path = ? ORDER BY started_at DESC",[H]).map((Q)=>this.mapRow(Q))}getActive(){return this.db.all("SELECT * FROM sessions WHERE status = 'active' ORDER BY started_at DESC").map((H)=>this.mapRow(H))}updateStatus(H,Q){this.db.run("UPDATE sessions SET status = ? WHERE id = ?",[Q,H])}markCompleted(H){this.db.run("UPDATE sessions SET status = 'completed', ended_at = datetime('now') WHERE id = ?",[H])}incrementObservationCount(H){this.db.run("UPDATE sessions SET observation_count = observation_count + 1 WHERE id = ?",[H])}setSummary(H,Q){this.db.run("UPDATE sessions SET summary_id = ? WHERE id = ?",[Q,H])}mapRow(H){return{id:H.id,projectPath:H.project_path,startedAt:H.started_at,endedAt:H.ended_at??null,status:H.status,observationCount:H.observation_count,summaryId:H.summary_id??null}}}import{randomUUID as m}from"crypto";class C{db;constructor(H){this.db=H}create(H){let Q=m(),X=new Date().toISOString();return this.db.run(`INSERT INTO session_summaries
217
+ (id, session_id, summary, key_decisions, files_modified,
218
+ concepts, created_at, token_count,
219
+ request, investigated, learned, completed, next_steps)
220
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[Q,H.sessionId,H.summary,JSON.stringify(H.keyDecisions),JSON.stringify(H.filesModified),JSON.stringify(H.concepts),X,H.tokenCount,H.request??"",H.investigated??"",H.learned??"",H.completed??"",H.nextSteps??""]),{...H,id:Q,createdAt:X}}importSummary(H){this.db.run(`INSERT INTO session_summaries
221
+ (id, session_id, summary, key_decisions, files_modified,
222
+ concepts, created_at, token_count,
223
+ request, investigated, learned, completed, next_steps)
224
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[H.id,H.sessionId,H.summary,JSON.stringify(H.keyDecisions),JSON.stringify(H.filesModified),JSON.stringify(H.concepts),H.createdAt,H.tokenCount,H.request??"",H.investigated??"",H.learned??"",H.completed??"",H.nextSteps??""])}getBySessionId(H){let Q=this.db.get("SELECT * FROM session_summaries WHERE session_id = ?",[H]);return Q?this.mapRow(Q):null}getRecent(H=10){return this.db.all("SELECT * FROM session_summaries ORDER BY created_at DESC LIMIT ?",[H]).map((Q)=>this.mapRow(Q))}search(H,Q=10){return this.db.all(`SELECT ss.*
225
+ FROM session_summaries ss
226
+ JOIN summaries_fts fts ON ss._rowid = fts.rowid
227
+ WHERE summaries_fts MATCH ?
228
+ ORDER BY rank
229
+ LIMIT ?`,[H,Q]).map((X)=>this.mapRow(X))}mapRow(H){return{id:H.id,sessionId:H.session_id,summary:H.summary,keyDecisions:JSON.parse(H.key_decisions),filesModified:JSON.parse(H.files_modified),concepts:JSON.parse(H.concepts),createdAt:H.created_at,tokenCount:H.token_count,request:H.request||void 0,investigated:H.investigated||void 0,learned:H.learned||void 0,completed:H.completed||void 0,nextSteps:H.next_steps||void 0}}}import{createInterface as n}from"readline";function D(H){return Math.ceil(H.length/4)}var d=new Set(["decision","bugfix","feature","refactor","discovery","change"]);function i(H){if(typeof H!=="object"||H===null)return!1;let Q=H;return Q.jsonrpc==="2.0"&&typeof Q.method==="string"}function E(H){return typeof H==="string"&&d.has(H)?H:void 0}function O(H){return Array.isArray(H)?H.filter((Q)=>typeof Q==="string"):[]}class A{observations;sessions;summaries;projectPath;version;constructor(H){this.observations=H.observations,this.sessions=H.sessions,this.summaries=H.summaries,this.projectPath=H.projectPath,this.version=H.version}start(){let H=n({input:process.stdin,terminal:!1});H.on("line",(Q)=>{let X=Q.trim();if(!X)return;try{let Z=JSON.parse(X);if(i(Z))this.handleMessage(Z);else this.sendResponse({jsonrpc:"2.0",id:null,error:{code:-32600,message:"Invalid Request"}})}catch{this.sendResponse({jsonrpc:"2.0",id:null,error:{code:-32700,message:"Parse error"}})}}),H.on("close",()=>{process.exit(0)})}handleMessage(H){if(H.id===void 0||H.id===null)return;let Q=H.id;switch(H.method){case"initialize":this.handleInitialize(Q);break;case"tools/list":this.handleToolsList(Q);break;case"tools/call":this.handleToolsCall(Q,H.params);break;case"ping":this.sendResponse({jsonrpc:"2.0",id:Q,result:{}});break;default:this.sendResponse({jsonrpc:"2.0",id:Q,error:{code:-32601,message:`Method not found: ${H.method}`}})}}handleInitialize(H){this.sendResponse({jsonrpc:"2.0",id:H,result:{protocolVersion:"2024-11-05",capabilities:{tools:{}},serverInfo:{name:"open-mem",version:this.version}}})}handleToolsList(H){this.sendResponse({jsonrpc:"2.0",id:H,result:{tools:this.getToolDefinitions()}})}handleToolsCall(H,Q){let X=typeof Q?.name==="string"?Q.name:void 0,Z=Q?.arguments&&typeof Q.arguments==="object"&&!Array.isArray(Q.arguments)?Q.arguments:{};if(!X){this.sendResponse({jsonrpc:"2.0",id:H,error:{code:-32602,message:"Missing tool name"}});return}try{let z=this.executeTool(X,Z);this.sendResponse({jsonrpc:"2.0",id:H,result:z})}catch(z){let W=z instanceof Error?z.message:String(z);this.sendResponse({jsonrpc:"2.0",id:H,result:{content:[{type:"text",text:`Error: ${W}`}],isError:!0}})}}getToolDefinitions(){return[{name:"mem-search",description:"Search through past coding session observations and memories. Supports full-text search with FTS5 across observations and session summaries.",inputSchema:{type:"object",properties:{query:{type:"string",description:"Search query (supports keywords, phrases, file paths)"},type:{type:"string",enum:["decision","bugfix","feature","refactor","discovery","change"],description:"Filter by observation type"},limit:{type:"number",description:"Maximum number of results (1-50, default: 10)"}},required:["query"]}},{name:"mem-recall",description:"Fetch full observation details by ID. Use after mem-search to get complete narratives, facts, concepts, and file lists for specific observations.",inputSchema:{type:"object",properties:{ids:{type:"array",items:{type:"string"},description:"Observation IDs to fetch"},limit:{type:"number",description:"Maximum number of results (1-50, default: 10)"}},required:["ids"]}},{name:"mem-timeline",description:"View a timeline of past coding sessions for this project. Shows recent sessions with summaries, observation counts, and key decisions.",inputSchema:{type:"object",properties:{limit:{type:"number",description:"Number of recent sessions to show (1-20, default: 5)"},sessionId:{type:"string",description:"Show details for a specific session ID"}}}},{name:"mem-save",description:"Manually save an observation to memory. Use this to explicitly record important decisions, discoveries, or context that should be remembered across sessions.",inputSchema:{type:"object",properties:{title:{type:"string",description:"Brief title for the observation (max 80 chars)"},type:{type:"string",enum:["decision","bugfix","feature","refactor","discovery","change"],description:"Type of observation"},narrative:{type:"string",description:"Detailed description of what to remember"},concepts:{type:"array",items:{type:"string"},description:"Related concepts/tags"},files:{type:"array",items:{type:"string"},description:"Related file paths"}},required:["title","type","narrative"]}},{name:"mem-export",description:"Export project memories (observations and session summaries) as portable JSON. Use this to back up memories, transfer them between machines, or share context across environments.",inputSchema:{type:"object",properties:{type:{type:"string",enum:["decision","bugfix","feature","refactor","discovery","change"],description:"Filter by observation type"},limit:{type:"number",description:"Maximum number of observations to export"}}}},{name:"mem-import",description:"Import observations and session summaries from a JSON export. Use this to restore memories from a backup, or import memories from another machine. Skips duplicate observations (by ID) and summaries (by session ID).",inputSchema:{type:"object",properties:{data:{type:"string",description:"JSON string from a mem-export output"}},required:["data"]}}]}executeTool(H,Q){switch(H){case"mem-search":return this.execSearch(Q);case"mem-recall":return this.execRecall(Q);case"mem-timeline":return this.execTimeline(Q);case"mem-save":return this.execSave(Q);case"mem-export":return this.execExport(Q);case"mem-import":return this.execImport(Q);default:return{content:[{type:"text",text:`Unknown tool: ${H}`}],isError:!0}}}execSearch(H){let Q=typeof H.query==="string"?H.query:void 0,X=E(H.type),Z=typeof H.limit==="number"?Math.max(1,Math.min(H.limit,50)):10;if(!Q)return{content:[{type:"text",text:"Missing required argument: query"}],isError:!0};try{let z=this.observations.search({query:Q,type:X,limit:Z});if(z.length===0){let W=this.summaries.search(Q,Z);if(W.length===0)return{content:[{type:"text",text:"No matching observations or session summaries found."}]};return{content:[{type:"text",text:t(W)}]}}return{content:[{type:"text",text:o(z)}]}}catch(z){return{content:[{type:"text",text:`Search error: ${z}`}],isError:!0}}}execRecall(H){let Q=O(H.ids),X=typeof H.limit==="number"?Math.max(1,Math.min(H.limit,50)):10;if(Q.length===0)return{content:[{type:"text",text:"No observation IDs provided."}]};try{let Z=Q.slice(0,X),z=[];for(let W of Z){let K=this.observations.getById(W);if(K){let B=[];if(B.push(`## [${K.type.toUpperCase()}] ${K.title}`),K.subtitle)B.push(`*${K.subtitle}*`);if(B.push(`
230
+ ${K.narrative}`),K.facts.length>0){B.push(`
231
+ **Facts:**`);for(let J of K.facts)B.push(`- ${J}`)}if(K.concepts.length>0)B.push(`
232
+ **Concepts:** ${K.concepts.join(", ")}`);if(K.filesRead.length>0)B.push(`**Files read:** ${K.filesRead.join(", ")}`);if(K.filesModified.length>0)B.push(`**Files modified:** ${K.filesModified.join(", ")}`);B.push(`
233
+ *ID: ${K.id} | Created: ${K.createdAt} | Tokens: ${K.tokenCount}*`),z.push(B.join(`
234
+ `))}else z.push(`## ID: ${W}
235
+ *Not found*`)}return{content:[{type:"text",text:`Recalled ${z.length} observation(s):
236
+
237
+ ${z.join(`
238
+ ---
239
+ `)}`}]}}catch(Z){return{content:[{type:"text",text:`Recall error: ${Z}`}],isError:!0}}}execTimeline(H){let Q=typeof H.limit==="number"?Math.max(1,Math.min(H.limit,20)):5,X=typeof H.sessionId==="string"?H.sessionId:void 0;try{if(X){let W=this.sessions.getById(X);if(!W)return{content:[{type:"text",text:`Session ${X} not found.`}]};let K=W.summaryId?this.summaries.getBySessionId(X):null,B=this.observations.getBySession(X),J=[`# Session Detail: ${X}
240
+ `];if(J.push(`- **Started**: ${W.startedAt}`),J.push(`- **Ended**: ${W.endedAt??"Active"}`),J.push(`- **Status**: ${W.status}`),J.push(`- **Observations**: ${W.observationCount}`),K){if(J.push(`
241
+ ## Summary
242
+ ${K.summary}`),K.keyDecisions.length>0){J.push(`
243
+ **Key decisions:**`);for(let Y of K.keyDecisions)J.push(`- ${Y}`)}}if(B.length>0){J.push(`
244
+ ## Observations`);for(let Y of B)if(J.push(`
245
+ ### [${Y.type.toUpperCase()}] ${Y.title}`),J.push(Y.narrative),Y.concepts.length>0)J.push(`*Concepts: ${Y.concepts.join(", ")}*`)}return{content:[{type:"text",text:J.join(`
246
+ `)}]}}let Z=this.sessions.getRecent(this.projectPath,Q);if(Z.length===0)return{content:[{type:"text",text:"No past sessions found for this project."}]};let z=[`# Session Timeline (${Z.length} sessions)
247
+ `];for(let W of Z){let K=W.summaryId?this.summaries.getBySessionId(W.id):null;if(z.push(`## Session: ${W.id}`),z.push(`- **Started**: ${W.startedAt}`),z.push(`- **Status**: ${W.status}`),z.push(`- **Observations**: ${W.observationCount}`),K){if(z.push(`- **Summary**: ${K.summary}`),K.keyDecisions.length>0)z.push(`- **Key decisions**: ${K.keyDecisions.join("; ")}`)}z.push("")}return{content:[{type:"text",text:z.join(`
248
+ `)}]}}catch(Z){return{content:[{type:"text",text:`Timeline error: ${Z}`}],isError:!0}}}execSave(H){let Q=typeof H.title==="string"?H.title:void 0,X=E(H.type),Z=typeof H.narrative==="string"?H.narrative:void 0,z=O(H.concepts),W=O(H.files);if(!Q||!X||!Z)return{content:[{type:"text",text:"Missing required arguments: title, type, narrative"}],isError:!0};try{let K=`mcp-${new Date().toISOString().slice(0,10)}`;this.sessions.getOrCreate(K,this.projectPath);let B=this.observations.create({sessionId:K,type:X,title:Q,subtitle:"",facts:[],narrative:Z,concepts:z,filesRead:[],filesModified:W,rawToolOutput:`[MCP save] ${Z}`,toolName:"mem-save",tokenCount:D(`${Q} ${Z}`),discoveryTokens:0});return this.sessions.incrementObservationCount(K),{content:[{type:"text",text:`Saved observation: [${X}] "${Q}" (ID: ${B.id})`}]}}catch(K){return{content:[{type:"text",text:`Save error: ${K}`}],isError:!0}}}execExport(H){let Q=E(H.type),X=typeof H.limit==="number"?Math.max(1,H.limit):void 0;try{let Z=this.sessions.getAll(this.projectPath);if(Z.length===0)return{content:[{type:"text",text:"No sessions found for this project. Nothing to export."}]};let z=[];for(let J of Z){let Y=this.observations.getBySession(J.id);for(let G of Y){let{rawToolOutput:$,...V}=G;z.push(V)}}if(Q)z=z.filter((J)=>J.type===Q);if(z.sort((J,Y)=>{let G=String(J.createdAt??""),$=String(Y.createdAt??"");return G.localeCompare($)}),X&&X<z.length)z=z.slice(0,X);let W=[];for(let J of Z){let Y=this.summaries.getBySessionId(J.id);if(Y)W.push(Y)}let K={version:1,exportedAt:new Date().toISOString(),project:this.projectPath,observations:z,summaries:W},B=JSON.stringify(K,null,2);return{content:[{type:"text",text:`Exported ${z.length} observation(s) and ${W.length} summary(ies).
249
+
250
+ ${B}`}]}}catch(Z){return{content:[{type:"text",text:`Export error: ${Z}`}],isError:!0}}}execImport(H){let Q=typeof H.data==="string"?H.data:void 0;if(!Q)return{content:[{type:"text",text:"Missing required argument: data"}],isError:!0};try{let X;try{X=JSON.parse(Q)}catch{return{content:[{type:"text",text:"Import error: Invalid JSON. Please provide valid JSON from a mem-export."}],isError:!0}}if(typeof X!=="object"||X===null)return{content:[{type:"text",text:"Import error: Invalid JSON structure."}],isError:!0};let Z=X;if(!Z.version||typeof Z.version!=="number")return{content:[{type:"text",text:"Import error: Missing or invalid 'version' field. This doesn't look like a mem-export file."}],isError:!0};if(Z.version!==1)return{content:[{type:"text",text:`Import error: Unsupported export version ${Z.version}. This tool supports version 1.`}],isError:!0};if(!Array.isArray(Z.observations))return{content:[{type:"text",text:"Import error: Missing or invalid 'observations' array."}],isError:!0};let z=0,W=0,K=0,B=0,J=Z.observations;for(let $ of J){let V=typeof $.id==="string"?$.id:void 0,L=typeof $.sessionId==="string"?$.sessionId:void 0,U=typeof $.type==="string"?$.type:void 0,R=typeof $.title==="string"?$.title:void 0,k=typeof $.createdAt==="string"?$.createdAt:void 0;if(!V||!L||!U||!R||!k){W++;continue}if(this.observations.getById(V)){W++;continue}this.sessions.getOrCreate(L,this.projectPath),this.observations.importObservation({id:V,sessionId:L,type:U,title:R,subtitle:typeof $.subtitle==="string"?$.subtitle:"",facts:Array.isArray($.facts)?$.facts:[],narrative:typeof $.narrative==="string"?$.narrative:"",concepts:Array.isArray($.concepts)?$.concepts:[],filesRead:Array.isArray($.filesRead)?$.filesRead:[],filesModified:Array.isArray($.filesModified)?$.filesModified:[],rawToolOutput:typeof $.rawToolOutput==="string"?$.rawToolOutput:"",toolName:typeof $.toolName==="string"?$.toolName:"unknown",createdAt:k,tokenCount:typeof $.tokenCount==="number"?$.tokenCount:0,discoveryTokens:typeof $.discoveryTokens==="number"?$.discoveryTokens:0}),this.sessions.incrementObservationCount(L),z++}let Y=Array.isArray(Z.summaries)?Z.summaries:[];for(let $ of Y){let V=typeof $.sessionId==="string"?$.sessionId:void 0,L=typeof $.id==="string"?$.id:void 0;if(!V||!L){B++;continue}if(this.summaries.getBySessionId(V)){B++;continue}this.sessions.getOrCreate(V,this.projectPath),this.summaries.importSummary({id:L,sessionId:V,summary:typeof $.summary==="string"?$.summary:"",keyDecisions:Array.isArray($.keyDecisions)?$.keyDecisions:[],filesModified:Array.isArray($.filesModified)?$.filesModified:[],concepts:Array.isArray($.concepts)?$.concepts:[],createdAt:typeof $.createdAt==="string"?$.createdAt:new Date().toISOString(),tokenCount:typeof $.tokenCount==="number"?$.tokenCount:0,request:typeof $.request==="string"?$.request:void 0,investigated:typeof $.investigated==="string"?$.investigated:void 0,learned:typeof $.learned==="string"?$.learned:void 0,completed:typeof $.completed==="string"?$.completed:void 0,nextSteps:typeof $.nextSteps==="string"?$.nextSteps:void 0}),this.sessions.setSummary(V,L),K++}let G=[];if(G.push(`Imported ${z} observation(s)`),G.push(`${K} summary(ies)`),W>0)G.push(`Skipped ${W} duplicate/invalid observation(s)`);if(B>0)G.push(`skipped ${B} duplicate summary(ies)`);return{content:[{type:"text",text:`${G.join(". ")}.`}]}}catch(X){return{content:[{type:"text",text:`Import error: ${X}`}],isError:!0}}}sendResponse(H){let Q=JSON.stringify(H);process.stdout.write(`${Q}
251
+ `)}}function o(H){let Q=[`Found ${H.length} observation(s):
252
+ `];for(let{observation:X}of H){if(Q.push(`## [${X.type.toUpperCase()}] ${X.title}`),X.subtitle)Q.push(`*${X.subtitle}*`);if(Q.push(`
253
+ ${X.narrative}`),X.facts.length>0){Q.push(`
254
+ **Facts:**`);for(let Z of X.facts)Q.push(`- ${Z}`)}if(X.concepts.length>0)Q.push(`
255
+ **Concepts:** ${X.concepts.join(", ")}`);if(X.filesModified.length>0)Q.push(`**Files modified:** ${X.filesModified.join(", ")}`);if(X.filesRead.length>0)Q.push(`**Files read:** ${X.filesRead.join(", ")}`);Q.push(`
256
+ *Session: ${X.sessionId} | ${X.createdAt}*`),Q.push("---")}return Q.join(`
257
+ `)}function t(H){let Q=[`Found ${H.length} session summary(ies):
258
+ `];for(let X of H){if(Q.push(`## Session: ${X.sessionId}`),Q.push(X.summary),X.keyDecisions.length>0){Q.push(`
259
+ **Key decisions:**`);for(let Z of X.keyDecisions)Q.push(`- ${Z}`)}Q.push("---")}return Q.join(`
260
+ `)}import{spawnSync as I}from"child_process";import{dirname as e,resolve as h}from"path";function r(H){try{let Q=I("git",["rev-parse","--git-common-dir"],{cwd:H,encoding:"utf-8",timeout:5000});if(Q.status!==0||!Q.stdout)return null;let X=Q.stdout.trim();if(X===".git")return null;let Z=I("git",["rev-parse","--git-dir"],{cwd:H,encoding:"utf-8",timeout:5000});if(Z.status!==0||!Z.stdout)return null;let z=Z.stdout.trim(),W=h(H,X),K=h(H,z);if(W===K)return null;let B=e(W);if(B===W||B==="/")return null;return B}catch{return null}}function f(H){return r(H)??H}var __dirname="/Users/clopca/dev/github/open-mem/src",{values:v}=HH({options:{project:{type:"string",short:"p"}},strict:!1}),QH=typeof v.project==="string"?v.project:process.cwd(),w=f(QH),XH=q(w),M=T(XH.dbPath);x(M);var ZH=new F(M),$H=new _(M),zH=new C(M),KH=JSON.parse(a(s(__dirname,"..","package.json"),"utf-8")),WH=new A({observations:$H,sessions:ZH,summaries:zH,projectPath:w,version:KH.version}),N=!1,y=()=>{if(!N)N=!0,M.close();process.exit(0)};process.on("SIGINT",y);process.on("SIGTERM",y);process.on("beforeExit",()=>{if(!N)N=!0,M.close()});WH.start();
@@ -1,3 +1,4 @@
1
+ import type { EmbeddingModel } from "ai";
1
2
  import type { ObservationCompressor } from "../ai/compressor";
2
3
  import type { SessionSummarizer } from "../ai/summarizer";
3
4
  import type { ObservationRepository } from "../db/observations";
@@ -25,9 +26,10 @@ export declare class QueueProcessor {
25
26
  private observationRepo;
26
27
  private sessionRepo;
27
28
  private summaryRepo;
29
+ private embeddingModel;
28
30
  private processing;
29
31
  private timer;
30
- constructor(config: QueueProcessorConfig, compressor: ObservationCompressor, summarizer: SessionSummarizer, pendingRepo: PendingMessageRepository, observationRepo: ObservationRepository, sessionRepo: SessionRepository, summaryRepo: SummaryRepository);
32
+ constructor(config: QueueProcessorConfig, compressor: ObservationCompressor, summarizer: SessionSummarizer, pendingRepo: PendingMessageRepository, observationRepo: ObservationRepository, sessionRepo: SessionRepository, summaryRepo: SummaryRepository, embeddingModel?: EmbeddingModel | null);
31
33
  /** Add a new pending message to the queue */
32
34
  enqueue(sessionId: string, toolName: string, toolOutput: string, callId: string): void;
33
35
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"processor.d.ts","sourceRoot":"","sources":["../../src/queue/processor.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAE9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAMzD,MAAM,WAAW,oBAAoB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;CACxB;AAMD;;;;;;;;GAQG;AACH,qBAAa,cAAc;IAKzB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,eAAe;IACvB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,WAAW;IAVpB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,KAAK,CAA+C;gBAGnD,MAAM,EAAE,oBAAoB,EAC5B,UAAU,EAAE,qBAAqB,EACjC,UAAU,EAAE,iBAAiB,EAC7B,WAAW,EAAE,wBAAwB,EACrC,eAAe,EAAE,qBAAqB,EACtC,WAAW,EAAE,iBAAiB,EAC9B,WAAW,EAAE,iBAAiB;IAOvC,6CAA6C;IAC7C,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAQtF;;;;OAIG;IACG,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC;IAyDrC,yDAAyD;IACnD,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA4BxD,sCAAsC;IACtC,KAAK,IAAI,IAAI;IAWb,8BAA8B;IAC9B,IAAI,IAAI,IAAI;IAOZ,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,IAAI,YAAY,IAAI,OAAO,CAE1B;IAMD,QAAQ,IAAI;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,OAAO,CAAA;KAAE;CAMpD"}
1
+ {"version":3,"file":"processor.d.ts","sourceRoot":"","sources":["../../src/queue/processor.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,IAAI,CAAC;AACzC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAE9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAOzD,MAAM,WAAW,oBAAoB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;CACxB;AAMD;;;;;;;;GAQG;AACH,qBAAa,cAAc;IAKzB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,eAAe;IACvB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,cAAc;IAXvB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,KAAK,CAA+C;gBAGnD,MAAM,EAAE,oBAAoB,EAC5B,UAAU,EAAE,qBAAqB,EACjC,UAAU,EAAE,iBAAiB,EAC7B,WAAW,EAAE,wBAAwB,EACrC,eAAe,EAAE,qBAAqB,EACtC,WAAW,EAAE,iBAAiB,EAC9B,WAAW,EAAE,iBAAiB,EAC9B,cAAc,GAAE,cAAc,GAAG,IAAW;IAOrD,6CAA6C;IAC7C,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAQtF;;;;OAIG;IACG,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC;IA0ErC,yDAAyD;IACnD,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA4BxD,sCAAsC;IACtC,KAAK,IAAI,IAAI;IAWb,8BAA8B;IAC9B,IAAI,IAAI,IAAI;IAOZ,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,IAAI,YAAY,IAAI,OAAO,CAE1B;IAMD,QAAQ,IAAI;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,OAAO,CAAA;KAAE;CAMpD"}
@@ -0,0 +1,9 @@
1
+ import { type EmbeddingModel } from "ai";
2
+ export declare function generateEmbedding(model: EmbeddingModel, text: string): Promise<number[] | null>;
3
+ export declare function cosineSimilarity(a: number[], b: number[]): number;
4
+ export declare function prepareObservationText(obs: {
5
+ title: string;
6
+ narrative: string;
7
+ concepts: string[];
8
+ }): string;
9
+ //# sourceMappingURL=embeddings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embeddings.d.ts","sourceRoot":"","sources":["../../src/search/embeddings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAS,MAAM,IAAI,CAAC;AAEhD,wBAAsB,iBAAiB,CACtC,KAAK,EAAE,cAAc,EACrB,IAAI,EAAE,MAAM,GACV,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAO1B;AAED,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAiBjE;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACnB,GAAG,MAAM,CAMT"}
@@ -0,0 +1,11 @@
1
+ import type { EmbeddingModel } from "ai";
2
+ import type { ObservationRepository } from "../db/observations";
3
+ import type { ObservationType, SearchResult } from "../types";
4
+ interface HybridSearchOptions {
5
+ type?: ObservationType;
6
+ limit?: number;
7
+ projectPath: string;
8
+ }
9
+ export declare function hybridSearch(query: string, observations: ObservationRepository, embeddingModel: EmbeddingModel | null, options: HybridSearchOptions): Promise<SearchResult[]>;
10
+ export {};
11
+ //# sourceMappingURL=hybrid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hybrid.d.ts","sourceRoot":"","sources":["../../src/search/hybrid.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,IAAI,CAAC;AACzC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAK9D,UAAU,mBAAmB;IAC5B,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,YAAY,CACjC,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,qBAAqB,EACnC,cAAc,EAAE,cAAc,GAAG,IAAI,EACrC,OAAO,EAAE,mBAAmB,GAC1B,OAAO,CAAC,YAAY,EAAE,CAAC,CA2BzB"}
@@ -0,0 +1,33 @@
1
+ import type { ObservationRepository } from "../db/observations";
2
+ import type { SessionRepository } from "../db/sessions";
3
+ import type { SummaryRepository } from "../db/summaries";
4
+ export interface McpServerDeps {
5
+ observations: ObservationRepository;
6
+ sessions: SessionRepository;
7
+ summaries: SummaryRepository;
8
+ projectPath: string;
9
+ version: string;
10
+ }
11
+ export declare class McpServer {
12
+ private observations;
13
+ private sessions;
14
+ private summaries;
15
+ private projectPath;
16
+ private version;
17
+ constructor(deps: McpServerDeps);
18
+ start(): void;
19
+ private handleMessage;
20
+ private handleInitialize;
21
+ private handleToolsList;
22
+ private handleToolsCall;
23
+ private getToolDefinitions;
24
+ private executeTool;
25
+ private execSearch;
26
+ private execRecall;
27
+ private execTimeline;
28
+ private execSave;
29
+ private execExport;
30
+ private execImport;
31
+ private sendResponse;
32
+ }
33
+ //# sourceMappingURL=mcp-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../../src/servers/mcp-server.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AA4CzD,MAAM,WAAW,aAAa;IAC7B,YAAY,EAAE,qBAAqB,CAAC;IACpC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,SAAS,EAAE,iBAAiB,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CAChB;AAiCD,qBAAa,SAAS;IACrB,OAAO,CAAC,YAAY,CAAwB;IAC5C,OAAO,CAAC,QAAQ,CAAoB;IACpC,OAAO,CAAC,SAAS,CAAoB;IACrC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,OAAO,CAAS;gBAEZ,IAAI,EAAE,aAAa;IAY/B,KAAK,IAAI,IAAI;IAwCb,OAAO,CAAC,aAAa;IAkCrB,OAAO,CAAC,gBAAgB;IAqBxB,OAAO,CAAC,eAAe;IAcvB,OAAO,CAAC,eAAe;IAwCvB,OAAO,CAAC,kBAAkB;IA2I1B,OAAO,CAAC,WAAW;IA0BnB,OAAO,CAAC,UAAU;IAqClB,OAAO,CAAC,UAAU;IAwDlB,OAAO,CAAC,YAAY;IA6EpB,OAAO,CAAC,QAAQ;IAmDhB,OAAO,CAAC,UAAU;IAwElB,OAAO,CAAC,UAAU;IAoLlB,OAAO,CAAC,YAAY;CAIpB"}
@@ -0,0 +1,6 @@
1
+ import type { ObservationRepository } from "../db/observations";
2
+ import type { SessionRepository } from "../db/sessions";
3
+ import type { SummaryRepository } from "../db/summaries";
4
+ import type { ToolDefinition } from "../types";
5
+ export declare function createExportTool(observations: ObservationRepository, summaries: SummaryRepository, sessions: SessionRepository, projectPath: string): ToolDefinition;
6
+ //# sourceMappingURL=export.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../src/tools/export.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,KAAK,EAA+B,cAAc,EAAE,MAAM,UAAU,CAAC;AAgB5E,wBAAgB,gBAAgB,CAC/B,YAAY,EAAE,qBAAqB,EACnC,SAAS,EAAE,iBAAiB,EAC5B,QAAQ,EAAE,iBAAiB,EAC3B,WAAW,EAAE,MAAM,GACjB,cAAc,CA6DhB"}
@@ -0,0 +1,6 @@
1
+ import type { ObservationRepository } from "../db/observations";
2
+ import type { SessionRepository } from "../db/sessions";
3
+ import type { SummaryRepository } from "../db/summaries";
4
+ import type { ToolDefinition } from "../types";
5
+ export declare function createImportTool(observations: ObservationRepository, summaries: SummaryRepository, sessions: SessionRepository, projectPath: string): ToolDefinition;
6
+ //# sourceMappingURL=import.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"import.d.ts","sourceRoot":"","sources":["../../src/tools/import.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,KAAK,EAA+B,cAAc,EAAE,MAAM,UAAU,CAAC;AAgB5E,wBAAgB,gBAAgB,CAC/B,YAAY,EAAE,qBAAqB,EACnC,SAAS,EAAE,iBAAiB,EAC5B,QAAQ,EAAE,iBAAiB,EAC3B,WAAW,EAAE,MAAM,GACjB,cAAc,CAqIhB"}
@@ -1 +1 @@
1
- {"version":3,"file":"recall.d.ts","sourceRoot":"","sources":["../../src/tools/recall.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,KAAK,EAAe,cAAc,EAAE,MAAM,UAAU,CAAC;AAE5D,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,qBAAqB,GAAG,cAAc,CAoCpF"}
1
+ {"version":3,"file":"recall.d.ts","sourceRoot":"","sources":["../../src/tools/recall.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,KAAK,EAAe,cAAc,EAAE,MAAM,UAAU,CAAC;AAS5D,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,qBAAqB,GAAG,cAAc,CAgCpF"}
@@ -1 +1 @@
1
- {"version":3,"file":"save.d.ts","sourceRoot":"","sources":["../../src/tools/save.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EAAmB,cAAc,EAAE,MAAM,UAAU,CAAC;AAEhE,wBAAgB,cAAc,CAC7B,YAAY,EAAE,qBAAqB,EACnC,QAAQ,EAAE,iBAAiB,EAC3B,WAAW,EAAE,MAAM,GACjB,cAAc,CAgDhB"}
1
+ {"version":3,"file":"save.d.ts","sourceRoot":"","sources":["../../src/tools/save.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAc/C,wBAAgB,cAAc,CAC7B,YAAY,EAAE,qBAAqB,EACnC,QAAQ,EAAE,iBAAiB,EAC3B,WAAW,EAAE,MAAM,GACjB,cAAc,CAqChB"}
@@ -1,5 +1,6 @@
1
+ import type { EmbeddingModel } from "ai";
1
2
  import type { ObservationRepository } from "../db/observations";
2
3
  import type { SummaryRepository } from "../db/summaries";
3
4
  import type { ToolDefinition } from "../types";
4
- export declare function createSearchTool(observations: ObservationRepository, summaries: SummaryRepository): ToolDefinition;
5
+ export declare function createSearchTool(observations: ObservationRepository, summaries: SummaryRepository, embeddingModel?: EmbeddingModel | null, projectPath?: string): ToolDefinition;
5
6
  //# sourceMappingURL=search.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/tools/search.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,KAAK,EAAgC,cAAc,EAAE,MAAM,UAAU,CAAC;AAE7E,wBAAgB,gBAAgB,CAC/B,YAAY,EAAE,qBAAqB,EACnC,SAAS,EAAE,iBAAiB,GAC1B,cAAc,CA8ChB"}
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/tools/search.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,IAAI,CAAC;AAEzC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,OAAO,KAAK,EAAgC,cAAc,EAAE,MAAM,UAAU,CAAC;AAa7E,wBAAgB,gBAAgB,CAC/B,YAAY,EAAE,qBAAqB,EACnC,SAAS,EAAE,iBAAiB,EAC5B,cAAc,GAAE,cAAc,GAAG,IAAW,EAC5C,WAAW,SAAK,GACd,cAAc,CAqChB"}
@@ -1 +1 @@
1
- {"version":3,"file":"timeline.d.ts","sourceRoot":"","sources":["../../src/tools/timeline.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE/C,wBAAgB,kBAAkB,CACjC,QAAQ,EAAE,iBAAiB,EAC3B,SAAS,EAAE,iBAAiB,EAC5B,YAAY,EAAE,qBAAqB,EACnC,WAAW,EAAE,MAAM,GACjB,cAAc,CAiDhB"}
1
+ {"version":3,"file":"timeline.d.ts","sourceRoot":"","sources":["../../src/tools/timeline.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAS/C,wBAAgB,kBAAkB,CACjC,QAAQ,EAAE,iBAAiB,EAC3B,SAAS,EAAE,iBAAiB,EAC5B,YAAY,EAAE,qBAAqB,EACnC,WAAW,EAAE,MAAM,GACjB,cAAc,CA6ChB"}
package/dist/types.d.ts CHANGED
@@ -16,6 +16,7 @@ export interface Observation {
16
16
  toolName: string;
17
17
  createdAt: string;
18
18
  tokenCount: number;
19
+ discoveryTokens: number;
19
20
  }
20
21
  /** Lightweight index entry for progressive disclosure */
21
22
  export interface ObservationIndex {
@@ -24,6 +25,7 @@ export interface ObservationIndex {
24
25
  type: ObservationType;
25
26
  title: string;
26
27
  tokenCount: number;
28
+ discoveryTokens: number;
27
29
  createdAt: string;
28
30
  }
29
31
  export interface Session {
@@ -95,6 +97,9 @@ export interface OpenMemConfig {
95
97
  contextFullObservationCount: number;
96
98
  maxObservations: number;
97
99
  contextShowLastSummary: boolean;
100
+ rateLimitingEnabled: boolean;
101
+ folderContextEnabled: boolean;
102
+ folderContextMaxDepth: number;
98
103
  }
99
104
  /** OpenCode plugin input shape */
100
105
  export interface PluginInput {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import type { Observation } from "../types";
2
+ /**
3
+ * Update AGENTS.md files for folders referenced by observations.
4
+ *
5
+ * Groups observations by the folders their files belong to, generates
6
+ * a context block for each folder, and writes it into the managed
7
+ * section of each folder's AGENTS.md.
8
+ *
9
+ * @param projectPath - Absolute path to the project root
10
+ * @param observations - Observations from the current session
11
+ * @param maxDepth - Maximum folder depth from project root (default: 5)
12
+ */
13
+ export declare function updateFolderContext(projectPath: string, observations: Observation[], maxDepth?: number): Promise<void>;
14
+ /**
15
+ * Generate a markdown context block for a folder's recent activity.
16
+ *
17
+ * @param folderPath - Absolute path to the folder
18
+ * @param observations - Observations relevant to this folder
19
+ * @param projectPath - Absolute path to the project root
20
+ * @returns Markdown string for the managed section
21
+ */
22
+ export declare function generateFolderContext(folderPath: string, observations: Observation[], projectPath: string): string;
23
+ /**
24
+ * Update the managed section of an AGENTS.md file in the given folder.
25
+ *
26
+ * - Reads existing AGENTS.md if present
27
+ * - Replaces content between managed tags (or appends if no tags exist)
28
+ * - Preserves user content outside the tags
29
+ * - Writes atomically via temp file + rename
30
+ *
31
+ * @param folderPath - Absolute path to the folder (must exist)
32
+ * @param contextBlock - New content for the managed section
33
+ */
34
+ export declare function updateAgentsMd(folderPath: string, contextBlock: string): Promise<void>;
35
+ /**
36
+ * Replace content between managed tags, preserving everything else.
37
+ *
38
+ * Three cases:
39
+ * 1. No existing content → wrap new content in tags
40
+ * 2. Has existing tags → replace only tagged section
41
+ * 3. No tags in existing content → append tagged content at end
42
+ */
43
+ export declare function replaceTaggedContent(existingContent: string, newContent: string): string;
44
+ //# sourceMappingURL=agents-md.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents-md.d.ts","sourceRoot":"","sources":["../../src/utils/agents-md.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,WAAW,EAAmB,MAAM,UAAU,CAAC;AAmC7D;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CACxC,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,WAAW,EAAE,EAC3B,QAAQ,SAAI,GACV,OAAO,CAAC,IAAI,CAAC,CA2Bf;AAMD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACpC,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,WAAW,EAAE,EAC3B,WAAW,EAAE,MAAM,GACjB,MAAM,CA6CR;AAMD;;;;;;;;;;GAUG;AACH,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAqB5F;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,eAAe,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAkBxF"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Resolve the main repository root if the given directory is inside a git worktree.
3
+ *
4
+ * @param projectDir - Absolute path to the project directory
5
+ * @returns The main repo root path if inside a worktree, or `null` if not a worktree
6
+ */
7
+ export declare function resolveWorktreeRoot(projectDir: string): string | null;
8
+ /** Returns worktree root if in a worktree, otherwise the original projectDir. */
9
+ export declare function getCanonicalProjectPath(projectDir: string): string;
10
+ //# sourceMappingURL=worktree.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktree.d.ts","sourceRoot":"","sources":["../../src/utils/worktree.ts"],"names":[],"mappings":"AAOA;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAkDrE;AAED,iFAAiF;AACjF,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAGlE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-mem",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
4
  "description": "Persistent memory plugin for OpenCode — captures, compresses, and recalls context across coding sessions",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -12,15 +12,14 @@
12
12
  "types": "./dist/index.d.ts"
13
13
  }
14
14
  },
15
- "files": [
16
- "dist",
17
- "README.md",
18
- "LICENSE",
19
- "CHANGELOG.md"
20
- ],
15
+ "bin": {
16
+ "open-mem-mcp": "./dist/mcp.js"
17
+ },
18
+ "files": ["dist", "README.md", "LICENSE", "CHANGELOG.md"],
21
19
  "scripts": {
22
- "build": "bun run build:bundle && bun run build:types",
20
+ "build": "bun run build:bundle && bun run build:mcp && bun run build:types",
23
21
  "build:bundle": "bun build src/index.ts --outdir dist --target bun --format esm --minify --external bun:sqlite --external ai --external @ai-sdk/anthropic --external @ai-sdk/amazon-bedrock --external @ai-sdk/openai --external @ai-sdk/google",
22
+ "build:mcp": "bun build src/mcp.ts --outdir dist --target bun --format esm --minify --external bun:sqlite --external ai --external @ai-sdk/anthropic --external @ai-sdk/amazon-bedrock --external @ai-sdk/openai --external @ai-sdk/google",
24
23
  "build:types": "bun x tsc --declaration --emitDeclarationOnly --outDir dist",
25
24
  "dev": "bun run --watch src/index.ts",
26
25
  "test": "bun test",