ai-mind-map 1.6.1 → 1.6.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.
@@ -221,29 +221,29 @@ function cosineSimilarity(vecA, vecB, magB) {
221
221
  // Semantic Search Engine
222
222
  // ============================================================
223
223
  /** Schema for semantic search tables */
224
- const SEMANTIC_SCHEMA = `
225
- -- TF-IDF vectors for each indexed node
226
- CREATE TABLE IF NOT EXISTS tfidf_vectors (
227
- node_id TEXT PRIMARY KEY,
228
- terms TEXT NOT NULL,
229
- magnitude REAL NOT NULL,
230
- updated_at INTEGER NOT NULL
231
- );
232
-
233
- -- Inverse document frequency stats
234
- CREATE TABLE IF NOT EXISTS corpus_stats (
235
- term TEXT PRIMARY KEY,
236
- doc_frequency INTEGER NOT NULL
237
- );
238
-
239
- -- Metadata for the semantic index
240
- CREATE TABLE IF NOT EXISTS search_metadata (
241
- key TEXT PRIMARY KEY,
242
- value TEXT NOT NULL
243
- );
244
-
245
- -- Index for fast lookups
246
- CREATE INDEX IF NOT EXISTS idx_tfidf_updated ON tfidf_vectors(updated_at);
224
+ const SEMANTIC_SCHEMA = `
225
+ -- TF-IDF vectors for each indexed node
226
+ CREATE TABLE IF NOT EXISTS tfidf_vectors (
227
+ node_id TEXT PRIMARY KEY,
228
+ terms TEXT NOT NULL,
229
+ magnitude REAL NOT NULL,
230
+ updated_at INTEGER NOT NULL
231
+ );
232
+
233
+ -- Inverse document frequency stats
234
+ CREATE TABLE IF NOT EXISTS corpus_stats (
235
+ term TEXT PRIMARY KEY,
236
+ doc_frequency INTEGER NOT NULL
237
+ );
238
+
239
+ -- Metadata for the semantic index
240
+ CREATE TABLE IF NOT EXISTS search_metadata (
241
+ key TEXT PRIMARY KEY,
242
+ value TEXT NOT NULL
243
+ );
244
+
245
+ -- Index for fast lookups
246
+ CREATE INDEX IF NOT EXISTS idx_tfidf_updated ON tfidf_vectors(updated_at);
247
247
  `;
248
248
  /**
249
249
  * SemanticSearchEngine — TF-IDF cosine similarity search with synonym expansion.
@@ -282,40 +282,40 @@ export class SemanticSearchEngine {
282
282
  }
283
283
  /** Prepare reusable SQL statements */
284
284
  prepareStatements() {
285
- this.stmtUpsertVector = this.db.prepare(`
286
- INSERT OR REPLACE INTO tfidf_vectors (node_id, terms, magnitude, updated_at)
287
- VALUES (?, ?, ?, ?)
285
+ this.stmtUpsertVector = this.db.prepare(`
286
+ INSERT OR REPLACE INTO tfidf_vectors (node_id, terms, magnitude, updated_at)
287
+ VALUES (?, ?, ?, ?)
288
288
  `);
289
- this.stmtDeleteVector = this.db.prepare(`
290
- DELETE FROM tfidf_vectors WHERE node_id = ?
289
+ this.stmtDeleteVector = this.db.prepare(`
290
+ DELETE FROM tfidf_vectors WHERE node_id = ?
291
291
  `);
292
- this.stmtUpsertCorpusStat = this.db.prepare(`
293
- INSERT OR REPLACE INTO corpus_stats (term, doc_frequency)
294
- VALUES (?, ?)
292
+ this.stmtUpsertCorpusStat = this.db.prepare(`
293
+ INSERT OR REPLACE INTO corpus_stats (term, doc_frequency)
294
+ VALUES (?, ?)
295
295
  `);
296
- this.stmtGetVector = this.db.prepare(`
297
- SELECT terms, magnitude FROM tfidf_vectors WHERE node_id = ?
296
+ this.stmtGetVector = this.db.prepare(`
297
+ SELECT terms, magnitude FROM tfidf_vectors WHERE node_id = ?
298
298
  `);
299
- this.stmtGetAllVectors = this.db.prepare(`
300
- SELECT node_id, terms, magnitude FROM tfidf_vectors
299
+ this.stmtGetAllVectors = this.db.prepare(`
300
+ SELECT node_id, terms, magnitude FROM tfidf_vectors
301
301
  `);
302
- this.stmtGetCorpusStats = this.db.prepare(`
303
- SELECT term, doc_frequency FROM corpus_stats
302
+ this.stmtGetCorpusStats = this.db.prepare(`
303
+ SELECT term, doc_frequency FROM corpus_stats
304
304
  `);
305
- this.stmtSetMetadata = this.db.prepare(`
306
- INSERT OR REPLACE INTO search_metadata (key, value) VALUES (?, ?)
305
+ this.stmtSetMetadata = this.db.prepare(`
306
+ INSERT OR REPLACE INTO search_metadata (key, value) VALUES (?, ?)
307
307
  `);
308
- this.stmtGetMetadata = this.db.prepare(`
309
- SELECT value FROM search_metadata WHERE key = ?
308
+ this.stmtGetMetadata = this.db.prepare(`
309
+ SELECT value FROM search_metadata WHERE key = ?
310
310
  `);
311
- this.stmtCountVectors = this.db.prepare(`
312
- SELECT COUNT(*) as count FROM tfidf_vectors
311
+ this.stmtCountVectors = this.db.prepare(`
312
+ SELECT COUNT(*) as count FROM tfidf_vectors
313
313
  `);
314
- this.stmtCountTerms = this.db.prepare(`
315
- SELECT COUNT(*) as count FROM corpus_stats
314
+ this.stmtCountTerms = this.db.prepare(`
315
+ SELECT COUNT(*) as count FROM corpus_stats
316
316
  `);
317
- this.stmtDeleteCorpusStats = this.db.prepare(`
318
- DELETE FROM corpus_stats
317
+ this.stmtDeleteCorpusStats = this.db.prepare(`
318
+ DELETE FROM corpus_stats
319
319
  `);
320
320
  }
321
321
  /** Load corpus statistics from SQLite */
@@ -389,9 +389,9 @@ export class SemanticSearchEngine {
389
389
  * Remove all nodes for a file path from the semantic index.
390
390
  */
391
391
  removeFileNodes(filePath) {
392
- this.db.prepare(`
393
- DELETE FROM tfidf_vectors
394
- WHERE node_id IN (SELECT id FROM nodes WHERE filePath = ?)
392
+ this.db.prepare(`
393
+ DELETE FROM tfidf_vectors
394
+ WHERE node_id IN (SELECT id FROM nodes WHERE filePath = ?)
395
395
  `).run(filePath);
396
396
  this.idfStale = true;
397
397
  }
@@ -41,68 +41,68 @@ export class DecisionLog {
41
41
  // Schema
42
42
  // ────────────────────────────────────────────────────────────
43
43
  ensureSchema() {
44
- this.db.exec(`
45
- CREATE TABLE IF NOT EXISTS decisions (
46
- id INTEGER PRIMARY KEY AUTOINCREMENT,
47
- title TEXT NOT NULL,
48
- description TEXT NOT NULL,
49
- rationale TEXT NOT NULL,
50
- alternatives TEXT NOT NULL DEFAULT '[]',
51
- consequences TEXT NOT NULL DEFAULT '[]',
52
- related_files TEXT NOT NULL DEFAULT '[]',
53
- tags TEXT NOT NULL DEFAULT '[]',
54
- decided_at INTEGER NOT NULL,
55
- decided_by TEXT NOT NULL DEFAULT 'agent',
56
- status TEXT NOT NULL DEFAULT 'active',
57
- superseded_by INTEGER
58
- );
59
-
60
- CREATE INDEX IF NOT EXISTS idx_decisions_status ON decisions(status);
61
- CREATE INDEX IF NOT EXISTS idx_decisions_decided_at ON decisions(decided_at DESC);
44
+ this.db.exec(`
45
+ CREATE TABLE IF NOT EXISTS decisions (
46
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
47
+ title TEXT NOT NULL,
48
+ description TEXT NOT NULL,
49
+ rationale TEXT NOT NULL,
50
+ alternatives TEXT NOT NULL DEFAULT '[]',
51
+ consequences TEXT NOT NULL DEFAULT '[]',
52
+ related_files TEXT NOT NULL DEFAULT '[]',
53
+ tags TEXT NOT NULL DEFAULT '[]',
54
+ decided_at INTEGER NOT NULL,
55
+ decided_by TEXT NOT NULL DEFAULT 'agent',
56
+ status TEXT NOT NULL DEFAULT 'active',
57
+ superseded_by INTEGER
58
+ );
59
+
60
+ CREATE INDEX IF NOT EXISTS idx_decisions_status ON decisions(status);
61
+ CREATE INDEX IF NOT EXISTS idx_decisions_decided_at ON decisions(decided_at DESC);
62
62
  `);
63
63
  // FTS5 for full-text search across title, description, rationale
64
64
  try {
65
- this.db.exec(`
66
- CREATE VIRTUAL TABLE IF NOT EXISTS decisions_fts USING fts5(
67
- title,
68
- description,
69
- rationale,
70
- tags,
71
- content='decisions',
72
- content_rowid='id',
73
- tokenize='porter unicode61'
74
- );
65
+ this.db.exec(`
66
+ CREATE VIRTUAL TABLE IF NOT EXISTS decisions_fts USING fts5(
67
+ title,
68
+ description,
69
+ rationale,
70
+ tags,
71
+ content='decisions',
72
+ content_rowid='id',
73
+ tokenize='porter unicode61'
74
+ );
75
75
  `);
76
76
  }
77
77
  catch {
78
78
  // Already exists; ignore
79
79
  }
80
80
  // Sync triggers
81
- this.db.exec(`
82
- CREATE TRIGGER IF NOT EXISTS decisions_ai AFTER INSERT ON decisions BEGIN
83
- INSERT INTO decisions_fts(rowid, title, description, rationale, tags)
84
- VALUES (new.id, new.title, new.description, new.rationale, new.tags);
85
- END;
86
-
87
- CREATE TRIGGER IF NOT EXISTS decisions_ad AFTER DELETE ON decisions BEGIN
88
- INSERT INTO decisions_fts(decisions_fts, rowid, title, description, rationale, tags)
89
- VALUES ('delete', old.id, old.title, old.description, old.rationale, old.tags);
90
- END;
91
-
92
- CREATE TRIGGER IF NOT EXISTS decisions_au
93
- AFTER UPDATE OF title, description, rationale, tags ON decisions BEGIN
94
- INSERT INTO decisions_fts(decisions_fts, rowid, title, description, rationale, tags)
95
- VALUES ('delete', old.id, old.title, old.description, old.rationale, old.tags);
96
- INSERT INTO decisions_fts(rowid, title, description, rationale, tags)
97
- VALUES (new.id, new.title, new.description, new.rationale, new.tags);
98
- END;
81
+ this.db.exec(`
82
+ CREATE TRIGGER IF NOT EXISTS decisions_ai AFTER INSERT ON decisions BEGIN
83
+ INSERT INTO decisions_fts(rowid, title, description, rationale, tags)
84
+ VALUES (new.id, new.title, new.description, new.rationale, new.tags);
85
+ END;
86
+
87
+ CREATE TRIGGER IF NOT EXISTS decisions_ad AFTER DELETE ON decisions BEGIN
88
+ INSERT INTO decisions_fts(decisions_fts, rowid, title, description, rationale, tags)
89
+ VALUES ('delete', old.id, old.title, old.description, old.rationale, old.tags);
90
+ END;
91
+
92
+ CREATE TRIGGER IF NOT EXISTS decisions_au
93
+ AFTER UPDATE OF title, description, rationale, tags ON decisions BEGIN
94
+ INSERT INTO decisions_fts(decisions_fts, rowid, title, description, rationale, tags)
95
+ VALUES ('delete', old.id, old.title, old.description, old.rationale, old.tags);
96
+ INSERT INTO decisions_fts(rowid, title, description, rationale, tags)
97
+ VALUES (new.id, new.title, new.description, new.rationale, new.tags);
98
+ END;
99
99
  `);
100
100
  }
101
101
  prepareStatements() {
102
- this.stmtInsert = this.db.prepare(`
103
- INSERT INTO decisions (title, description, rationale, alternatives, consequences,
104
- related_files, tags, decided_at, decided_by, status)
105
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 'active')
102
+ this.stmtInsert = this.db.prepare(`
103
+ INSERT INTO decisions (title, description, rationale, alternatives, consequences,
104
+ related_files, tags, decided_at, decided_by, status)
105
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 'active')
106
106
  `);
107
107
  this.stmtGetById = this.db.prepare(`SELECT * FROM decisions WHERE id = ?`);
108
108
  this.stmtUpdateStatus = this.db.prepare(`UPDATE decisions SET status = ? WHERE id = ?`);
@@ -112,12 +112,12 @@ export class DecisionLog {
112
112
  this.stmtActive = this.db.prepare(`SELECT * FROM decisions WHERE status = 'active' ORDER BY decided_at DESC`);
113
113
  this.stmtByStatus = this.db.prepare(`SELECT * FROM decisions WHERE status = ? ORDER BY decided_at DESC`);
114
114
  this.stmtCount = this.db.prepare(`SELECT COUNT(*) AS cnt FROM decisions`);
115
- this.stmtSearchFts = this.db.prepare(`
116
- SELECT d.*, bm25(decisions_fts, 10.0, 5.0, 5.0, 2.0) AS rank
117
- FROM decisions_fts f
118
- JOIN decisions d ON d.id = f.rowid
119
- WHERE decisions_fts MATCH ?
120
- ORDER BY rank
115
+ this.stmtSearchFts = this.db.prepare(`
116
+ SELECT d.*, bm25(decisions_fts, 10.0, 5.0, 5.0, 2.0) AS rank
117
+ FROM decisions_fts f
118
+ JOIN decisions d ON d.id = f.rowid
119
+ WHERE decisions_fts MATCH ?
120
+ ORDER BY rank
121
121
  `);
122
122
  }
123
123
  // ────────────────────────────────────────────────────────────
@@ -395,9 +395,9 @@ export class DecisionLog {
395
395
  return;
396
396
  // Remove oldest non-active decisions first
397
397
  const toRemove = this.db
398
- .prepare(`SELECT id FROM decisions
399
- WHERE status != 'active'
400
- ORDER BY decided_at ASC
398
+ .prepare(`SELECT id FROM decisions
399
+ WHERE status != 'active'
400
+ ORDER BY decided_at ASC
401
401
  LIMIT ?`)
402
402
  .all(excess);
403
403
  const txn = this.db.transaction(() => {
@@ -422,8 +422,8 @@ export class DecisionLog {
422
422
  fallbackLikeSearch(text) {
423
423
  const pattern = `%${text}%`;
424
424
  return this.db
425
- .prepare(`SELECT *, 0 AS rank FROM decisions
426
- WHERE title LIKE ? OR description LIKE ? OR rationale LIKE ?
425
+ .prepare(`SELECT *, 0 AS rank FROM decisions
426
+ WHERE title LIKE ? OR description LIKE ? OR rationale LIKE ?
427
427
  ORDER BY decided_at DESC LIMIT 50`)
428
428
  .all(pattern, pattern, pattern);
429
429
  }
@@ -68,82 +68,82 @@ export class PersistentMemory {
68
68
  // Schema
69
69
  // ────────────────────────────────────────────────────────────
70
70
  ensureSchema() {
71
- this.db.exec(`
72
- CREATE TABLE IF NOT EXISTS memories (
73
- id INTEGER PRIMARY KEY AUTOINCREMENT,
74
- category TEXT NOT NULL,
75
- content TEXT NOT NULL,
76
- importance REAL NOT NULL,
77
- tags TEXT NOT NULL DEFAULT '[]',
78
- related_files TEXT NOT NULL DEFAULT '[]',
79
- created_at INTEGER NOT NULL,
80
- last_accessed_at INTEGER NOT NULL,
81
- access_count INTEGER NOT NULL DEFAULT 0,
82
- session_id TEXT NOT NULL DEFAULT '',
83
- source TEXT NOT NULL DEFAULT 'agent'
84
- );
85
-
86
- CREATE INDEX IF NOT EXISTS idx_memories_category ON memories(category);
87
- CREATE INDEX IF NOT EXISTS idx_memories_importance ON memories(importance DESC);
88
- CREATE INDEX IF NOT EXISTS idx_memories_accessed ON memories(last_accessed_at DESC);
71
+ this.db.exec(`
72
+ CREATE TABLE IF NOT EXISTS memories (
73
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
74
+ category TEXT NOT NULL,
75
+ content TEXT NOT NULL,
76
+ importance REAL NOT NULL,
77
+ tags TEXT NOT NULL DEFAULT '[]',
78
+ related_files TEXT NOT NULL DEFAULT '[]',
79
+ created_at INTEGER NOT NULL,
80
+ last_accessed_at INTEGER NOT NULL,
81
+ access_count INTEGER NOT NULL DEFAULT 0,
82
+ session_id TEXT NOT NULL DEFAULT '',
83
+ source TEXT NOT NULL DEFAULT 'agent'
84
+ );
85
+
86
+ CREATE INDEX IF NOT EXISTS idx_memories_category ON memories(category);
87
+ CREATE INDEX IF NOT EXISTS idx_memories_importance ON memories(importance DESC);
88
+ CREATE INDEX IF NOT EXISTS idx_memories_accessed ON memories(last_accessed_at DESC);
89
89
  `);
90
90
  // FTS5 virtual table — created only if it doesn't already exist.
91
91
  // We use a content-sync approach: manual sync via triggers.
92
92
  try {
93
- this.db.exec(`
94
- CREATE VIRTUAL TABLE IF NOT EXISTS memories_fts USING fts5(
95
- content,
96
- category,
97
- tags,
98
- content='memories',
99
- content_rowid='id',
100
- tokenize='porter unicode61'
101
- );
93
+ this.db.exec(`
94
+ CREATE VIRTUAL TABLE IF NOT EXISTS memories_fts USING fts5(
95
+ content,
96
+ category,
97
+ tags,
98
+ content='memories',
99
+ content_rowid='id',
100
+ tokenize='porter unicode61'
101
+ );
102
102
  `);
103
103
  }
104
104
  catch {
105
105
  // FTS table may already exist; ignore duplicate errors.
106
106
  }
107
107
  // Sync triggers — keep FTS in lockstep with the main table.
108
- this.db.exec(`
109
- CREATE TRIGGER IF NOT EXISTS memories_ai AFTER INSERT ON memories BEGIN
110
- INSERT INTO memories_fts(rowid, content, category, tags)
111
- VALUES (new.id, new.content, new.category, new.tags);
112
- END;
113
-
114
- CREATE TRIGGER IF NOT EXISTS memories_ad AFTER DELETE ON memories BEGIN
115
- INSERT INTO memories_fts(memories_fts, rowid, content, category, tags)
116
- VALUES ('delete', old.id, old.content, old.category, old.tags);
117
- END;
118
-
119
- CREATE TRIGGER IF NOT EXISTS memories_au AFTER UPDATE OF content, category, tags ON memories BEGIN
120
- INSERT INTO memories_fts(memories_fts, rowid, content, category, tags)
121
- VALUES ('delete', old.id, old.content, old.category, old.tags);
122
- INSERT INTO memories_fts(rowid, content, category, tags)
123
- VALUES (new.id, new.content, new.category, new.tags);
124
- END;
108
+ this.db.exec(`
109
+ CREATE TRIGGER IF NOT EXISTS memories_ai AFTER INSERT ON memories BEGIN
110
+ INSERT INTO memories_fts(rowid, content, category, tags)
111
+ VALUES (new.id, new.content, new.category, new.tags);
112
+ END;
113
+
114
+ CREATE TRIGGER IF NOT EXISTS memories_ad AFTER DELETE ON memories BEGIN
115
+ INSERT INTO memories_fts(memories_fts, rowid, content, category, tags)
116
+ VALUES ('delete', old.id, old.content, old.category, old.tags);
117
+ END;
118
+
119
+ CREATE TRIGGER IF NOT EXISTS memories_au AFTER UPDATE OF content, category, tags ON memories BEGIN
120
+ INSERT INTO memories_fts(memories_fts, rowid, content, category, tags)
121
+ VALUES ('delete', old.id, old.content, old.category, old.tags);
122
+ INSERT INTO memories_fts(rowid, content, category, tags)
123
+ VALUES (new.id, new.content, new.category, new.tags);
124
+ END;
125
125
  `);
126
126
  }
127
127
  prepareStatements() {
128
- this.stmtInsert = this.db.prepare(`
129
- INSERT INTO memories (category, content, importance, tags, related_files,
130
- created_at, last_accessed_at, access_count, session_id, source)
131
- VALUES (?, ?, ?, ?, ?, ?, ?, 0, ?, ?)
128
+ this.stmtInsert = this.db.prepare(`
129
+ INSERT INTO memories (category, content, importance, tags, related_files,
130
+ created_at, last_accessed_at, access_count, session_id, source)
131
+ VALUES (?, ?, ?, ?, ?, ?, ?, 0, ?, ?)
132
132
  `);
133
- this.stmtUpdate = this.db.prepare(`
134
- UPDATE memories
135
- SET category = ?, content = ?, importance = ?, tags = ?, related_files = ?,
136
- last_accessed_at = ?, session_id = ?, source = ?
137
- WHERE id = ?
133
+ this.stmtUpdate = this.db.prepare(`
134
+ UPDATE memories
135
+ SET category = ?, content = ?, importance = ?, tags = ?, related_files = ?,
136
+ last_accessed_at = ?, session_id = ?, source = ?
137
+ WHERE id = ?
138
138
  `);
139
139
  this.stmtDelete = this.db.prepare(`DELETE FROM memories WHERE id = ?`);
140
140
  this.stmtGetById = this.db.prepare(`SELECT * FROM memories WHERE id = ?`);
141
- this.stmtBumpAccess = this.db.prepare(`
142
- UPDATE memories
143
- SET access_count = access_count + 1,
144
- last_accessed_at = ?,
145
- importance = MIN(1.0, importance + 0.1)
146
- WHERE id = ?
141
+ this.stmtBumpAccess = this.db.prepare(`
142
+ UPDATE memories
143
+ SET access_count = access_count + 1,
144
+ last_accessed_at = ?,
145
+ importance = MIN(1.0, importance + 0.1)
146
+ WHERE id = ?
147
147
  `);
148
148
  this.stmtAll = this.db.prepare(`SELECT * FROM memories ORDER BY importance DESC`);
149
149
  this.stmtCount = this.db.prepare(`SELECT COUNT(*) AS cnt FROM memories`);
@@ -152,18 +152,18 @@ export class PersistentMemory {
152
152
  this.stmtOldest = this.db.prepare(`SELECT MIN(created_at) AS ts FROM memories`);
153
153
  this.stmtNewest = this.db.prepare(`SELECT MAX(created_at) AS ts FROM memories`);
154
154
  this.stmtTotalAccess = this.db.prepare(`SELECT SUM(access_count) AS total FROM memories`);
155
- this.stmtPrunable = this.db.prepare(`
156
- SELECT id FROM memories
157
- WHERE importance < ?
158
- ORDER BY importance ASC, last_accessed_at ASC
159
- LIMIT ?
155
+ this.stmtPrunable = this.db.prepare(`
156
+ SELECT id FROM memories
157
+ WHERE importance < ?
158
+ ORDER BY importance ASC, last_accessed_at ASC
159
+ LIMIT ?
160
160
  `);
161
- this.stmtSearchFts = this.db.prepare(`
162
- SELECT m.*, bm25(memories_fts, 10.0, 5.0, 2.0) AS rank
163
- FROM memories_fts f
164
- JOIN memories m ON m.id = f.rowid
165
- WHERE memories_fts MATCH ?
166
- ORDER BY rank
161
+ this.stmtSearchFts = this.db.prepare(`
162
+ SELECT m.*, bm25(memories_fts, 10.0, 5.0, 2.0) AS rank
163
+ FROM memories_fts f
164
+ JOIN memories m ON m.id = f.rowid
165
+ WHERE memories_fts MATCH ?
166
+ ORDER BY rank
167
167
  `);
168
168
  }
169
169
  // ────────────────────────────────────────────────────────────
@@ -50,71 +50,71 @@ export class SessionMemory {
50
50
  // ────────────────────────────────────────────────────────────
51
51
  /** Create tables if they don't already exist. */
52
52
  ensureSchema() {
53
- this.db.exec(`
54
- CREATE TABLE IF NOT EXISTS sessions (
55
- session_id TEXT PRIMARY KEY,
56
- started_at INTEGER NOT NULL,
57
- ended_at INTEGER,
58
- summary TEXT NOT NULL DEFAULT '',
59
- input_tokens INTEGER NOT NULL DEFAULT 0,
60
- output_tokens INTEGER NOT NULL DEFAULT 0,
61
- context_tokens INTEGER NOT NULL DEFAULT 0,
62
- saved_tokens INTEGER NOT NULL DEFAULT 0
63
- );
64
-
65
- CREATE TABLE IF NOT EXISTS session_facts (
66
- id INTEGER PRIMARY KEY AUTOINCREMENT,
67
- session_id TEXT NOT NULL,
68
- kind TEXT NOT NULL,
69
- content TEXT NOT NULL,
70
- metadata TEXT,
71
- created_at INTEGER NOT NULL,
72
- FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
73
- );
74
-
75
- CREATE INDEX IF NOT EXISTS idx_session_facts_session
76
- ON session_facts(session_id);
77
- CREATE INDEX IF NOT EXISTS idx_session_facts_kind
78
- ON session_facts(session_id, kind);
79
- CREATE INDEX IF NOT EXISTS idx_sessions_started
80
- ON sessions(started_at DESC);
53
+ this.db.exec(`
54
+ CREATE TABLE IF NOT EXISTS sessions (
55
+ session_id TEXT PRIMARY KEY,
56
+ started_at INTEGER NOT NULL,
57
+ ended_at INTEGER,
58
+ summary TEXT NOT NULL DEFAULT '',
59
+ input_tokens INTEGER NOT NULL DEFAULT 0,
60
+ output_tokens INTEGER NOT NULL DEFAULT 0,
61
+ context_tokens INTEGER NOT NULL DEFAULT 0,
62
+ saved_tokens INTEGER NOT NULL DEFAULT 0
63
+ );
64
+
65
+ CREATE TABLE IF NOT EXISTS session_facts (
66
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
67
+ session_id TEXT NOT NULL,
68
+ kind TEXT NOT NULL,
69
+ content TEXT NOT NULL,
70
+ metadata TEXT,
71
+ created_at INTEGER NOT NULL,
72
+ FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
73
+ );
74
+
75
+ CREATE INDEX IF NOT EXISTS idx_session_facts_session
76
+ ON session_facts(session_id);
77
+ CREATE INDEX IF NOT EXISTS idx_session_facts_kind
78
+ ON session_facts(session_id, kind);
79
+ CREATE INDEX IF NOT EXISTS idx_sessions_started
80
+ ON sessions(started_at DESC);
81
81
  `);
82
82
  }
83
83
  /** Prepare reusable statements. */
84
84
  prepareStatements() {
85
- this.stmtInsertSession = this.db.prepare(`
86
- INSERT INTO sessions (session_id, started_at) VALUES (?, ?)
85
+ this.stmtInsertSession = this.db.prepare(`
86
+ INSERT INTO sessions (session_id, started_at) VALUES (?, ?)
87
87
  `);
88
- this.stmtEndSession = this.db.prepare(`
89
- UPDATE sessions SET ended_at = ?, summary = ? WHERE session_id = ?
88
+ this.stmtEndSession = this.db.prepare(`
89
+ UPDATE sessions SET ended_at = ?, summary = ? WHERE session_id = ?
90
90
  `);
91
- this.stmtInsertFact = this.db.prepare(`
92
- INSERT INTO session_facts (session_id, kind, content, metadata, created_at)
93
- VALUES (?, ?, ?, ?, ?)
91
+ this.stmtInsertFact = this.db.prepare(`
92
+ INSERT INTO session_facts (session_id, kind, content, metadata, created_at)
93
+ VALUES (?, ?, ?, ?, ?)
94
94
  `);
95
- this.stmtGetFacts = this.db.prepare(`
96
- SELECT id, session_id AS sessionId, kind, content, metadata, created_at AS createdAt
97
- FROM session_facts WHERE session_id = ? ORDER BY created_at ASC
95
+ this.stmtGetFacts = this.db.prepare(`
96
+ SELECT id, session_id AS sessionId, kind, content, metadata, created_at AS createdAt
97
+ FROM session_facts WHERE session_id = ? ORDER BY created_at ASC
98
98
  `);
99
- this.stmtGetSession = this.db.prepare(`
100
- SELECT session_id AS sessionId, started_at AS startedAt, ended_at AS endedAt,
101
- summary, input_tokens AS inputTokens, output_tokens AS outputTokens,
102
- context_tokens AS contextTokens, saved_tokens AS savedTokens
103
- FROM sessions WHERE session_id = ?
99
+ this.stmtGetSession = this.db.prepare(`
100
+ SELECT session_id AS sessionId, started_at AS startedAt, ended_at AS endedAt,
101
+ summary, input_tokens AS inputTokens, output_tokens AS outputTokens,
102
+ context_tokens AS contextTokens, saved_tokens AS savedTokens
103
+ FROM sessions WHERE session_id = ?
104
104
  `);
105
- this.stmtRecentSessions = this.db.prepare(`
106
- SELECT s.session_id AS sessionId, s.started_at AS startedAt,
107
- s.ended_at AS endedAt, s.summary,
108
- (SELECT COUNT(*) FROM session_facts f WHERE f.session_id = s.session_id) AS totalFacts
109
- FROM sessions s ORDER BY s.started_at DESC LIMIT ?
105
+ this.stmtRecentSessions = this.db.prepare(`
106
+ SELECT s.session_id AS sessionId, s.started_at AS startedAt,
107
+ s.ended_at AS endedAt, s.summary,
108
+ (SELECT COUNT(*) FROM session_facts f WHERE f.session_id = s.session_id) AS totalFacts
109
+ FROM sessions s ORDER BY s.started_at DESC LIMIT ?
110
110
  `);
111
- this.stmtFactCountByKind = this.db.prepare(`
112
- SELECT kind, COUNT(*) AS cnt FROM session_facts WHERE session_id = ? GROUP BY kind
111
+ this.stmtFactCountByKind = this.db.prepare(`
112
+ SELECT kind, COUNT(*) AS cnt FROM session_facts WHERE session_id = ? GROUP BY kind
113
113
  `);
114
- this.stmtUpdateTokenUsage = this.db.prepare(`
115
- UPDATE sessions
116
- SET input_tokens = ?, output_tokens = ?, context_tokens = ?, saved_tokens = ?
117
- WHERE session_id = ?
114
+ this.stmtUpdateTokenUsage = this.db.prepare(`
115
+ UPDATE sessions
116
+ SET input_tokens = ?, output_tokens = ?, context_tokens = ?, saved_tokens = ?
117
+ WHERE session_id = ?
118
118
  `);
119
119
  this.stmtDeleteSession = this.db.prepare(`DELETE FROM sessions WHERE session_id = ?`);
120
120
  this.stmtDeleteFacts = this.db.prepare(`DELETE FROM session_facts WHERE session_id = ?`);
@@ -135,7 +135,7 @@ export function registerContextTools(server, context, indexer, estimator = defau
135
135
  }
136
136
  return mcpText(ok({
137
137
  ...result,
138
- message: `✅ Indexed ${result.filesIndexed} files → ${result.nodesCreated} symbols in ${result.durationMs}ms. Project: ${result.projectRoot}. All tools are now ready.`,
138
+ message: ` Indexed ${result.filesIndexed} files → ${result.nodesCreated} symbols in ${result.durationMs}ms. Project: ${result.projectRoot}. All tools are now ready.`,
139
139
  }, estimator));
140
140
  }
141
141
  catch (err) {
@@ -151,7 +151,7 @@ export function registerContextTools(server, context, indexer, estimator = defau
151
151
  const response = { ...stats };
152
152
  if (stats.indexedFiles === 0 && stats.totalNodes === 0) {
153
153
  response._indexStatus = 'NOT_INDEXED';
154
- response._message = '⚠️ No codebase has been indexed yet. Call mindmap_reindex to index the project.';
154
+ response._message = ' No codebase has been indexed yet. Call mindmap_reindex to index the project.';
155
155
  }
156
156
  else {
157
157
  response._indexStatus = 'READY';
@@ -1 +1 @@
1
- {"version":3,"file":"context-tools.js","sourceRoot":"","sources":["../../src/tools/context-tools.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"context-tools.js","sourceRoot":"","sources":["../../src/tools/context-tools.ts"],"names":[],"mappings":"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"}