@vheins/local-memory-mcp 0.7.4 → 0.8.0

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.
@@ -172,40 +172,28 @@ function addLogSink(sink) {
172
172
  var LOG_LEVEL_VALUES = Object.keys(LEVELS);
173
173
 
174
174
  // src/mcp/storage/sqlite.ts
175
- import initSqlJs from "sql.js";
175
+ import Database from "better-sqlite3";
176
176
  import path2 from "path";
177
177
  import fs2 from "fs";
178
178
  import os from "os";
179
179
 
180
180
  // src/mcp/storage/migrations.ts
181
181
  var MigrationManager = class {
182
- constructor(db, saveDb) {
182
+ constructor(db) {
183
183
  this.db = db;
184
- this.saveDb = saveDb;
185
184
  }
186
185
  db;
187
- saveDb;
188
186
  run(sql) {
189
- this.db.run(sql);
187
+ this.db.prepare(sql).run();
190
188
  }
191
189
  exec(sql) {
192
190
  this.db.exec(sql);
193
191
  }
194
192
  all(sql) {
195
- const result = this.db.exec(sql);
196
- if (result.length === 0) return [];
197
- const { columns, values } = result[0];
198
- return values.map((row) => {
199
- const obj = {};
200
- columns.forEach((col, i) => {
201
- obj[col] = row[i];
202
- });
203
- return obj;
204
- });
193
+ return this.db.prepare(sql).all();
205
194
  }
206
195
  get(sql) {
207
- const rows = this.all(sql);
208
- return rows[0];
196
+ return this.db.prepare(sql).get();
209
197
  }
210
198
  migrate() {
211
199
  this.exec(`
@@ -427,7 +415,6 @@ var MigrationManager = class {
427
415
  this.run("UPDATE tasks SET task_code = substr(id, 1, 8) WHERE task_code IS NULL");
428
416
  } catch {
429
417
  }
430
- if (this.saveDb) this.saveDb();
431
418
  }
432
419
  ensureMemoryTypeConstraint() {
433
420
  const tableSql = this.get("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'memories'");
@@ -531,7 +518,7 @@ var MigrationManager = class {
531
518
  }
532
519
  ensureMemoryStatusConstraintRemoved() {
533
520
  const tableSql = this.get("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'memories'");
534
- if (tableSql?.sql?.includes("status TEXT NOT NULL DEFAULT 'active' CHECK")) {
521
+ if (typeof tableSql?.sql === "string" && tableSql.sql.includes("status TEXT NOT NULL DEFAULT 'active' CHECK")) {
535
522
  this.ensureMemoryTypeConstraint();
536
523
  }
537
524
  }
@@ -792,36 +779,25 @@ function tokenize(text) {
792
779
 
793
780
  // src/mcp/storage/base.ts
794
781
  var BaseEntity = class {
795
- constructor(db, saveDb) {
782
+ constructor(db) {
796
783
  this.db = db;
797
- this.saveDb = saveDb;
798
784
  }
799
785
  db;
800
- saveDb;
801
786
  run(sql, params = []) {
802
- this.db.run(sql, params);
803
- if (this.saveDb) this.saveDb();
804
- return { changes: this.db.getRowsModified() };
787
+ const stmt = this.db.prepare(sql);
788
+ const result = stmt.run(...params);
789
+ return { changes: result.changes };
805
790
  }
806
791
  exec(sql) {
807
792
  this.db.exec(sql);
808
- if (this.saveDb) this.saveDb();
809
793
  }
810
794
  all(sql, params = []) {
811
- const result = this.db.exec(sql, params);
812
- if (result.length === 0) return [];
813
- const { columns, values } = result[0];
814
- return values.map((row) => {
815
- const obj = {};
816
- columns.forEach((col, i) => {
817
- obj[col] = row[i];
818
- });
819
- return obj;
820
- });
795
+ const stmt = this.db.prepare(sql);
796
+ return stmt.all(...params);
821
797
  }
822
798
  get(sql, params = []) {
823
- const rows = this.all(sql, params);
824
- return rows[0];
799
+ const stmt = this.db.prepare(sql);
800
+ return stmt.get(...params);
825
801
  }
826
802
  safeJSONParse(json, defaultValue) {
827
803
  if (!json) return defaultValue;
@@ -1135,7 +1111,7 @@ var MemoryEntity = class extends BaseEntity {
1135
1111
  }
1136
1112
  return count;
1137
1113
  }
1138
- getRecentMemories(repo, limit, offset = 0, includeArchived = false, excludeTypes = []) {
1114
+ getRecentMemories(repo, limit, offset = 0, includeArchived = false, excludeTypes = [], sortOrder = "DESC") {
1139
1115
  let query = "SELECT * FROM memories WHERE repo = ?";
1140
1116
  const params = [repo];
1141
1117
  if (!includeArchived) {
@@ -1145,7 +1121,7 @@ var MemoryEntity = class extends BaseEntity {
1145
1121
  query += ` AND type NOT IN (${excludeTypes.map(() => "?").join(",")})`;
1146
1122
  params.push(...excludeTypes);
1147
1123
  }
1148
- query += " ORDER BY created_at DESC LIMIT ? OFFSET ?";
1124
+ query += ` ORDER BY importance DESC, created_at ${sortOrder} LIMIT ? OFFSET ?`;
1149
1125
  params.push(limit, offset);
1150
1126
  const rows = this.all(query, params);
1151
1127
  return rows.map((row) => this.rowToMemoryEntry(row));
@@ -1380,8 +1356,28 @@ var TaskEntity = class extends BaseEntity {
1380
1356
  const fields = [];
1381
1357
  const values = [];
1382
1358
  const anyUpdates = updates;
1359
+ const VALID_COLUMNS = /* @__PURE__ */ new Set([
1360
+ "repo",
1361
+ "task_code",
1362
+ "phase",
1363
+ "title",
1364
+ "description",
1365
+ "status",
1366
+ "priority",
1367
+ "agent",
1368
+ "role",
1369
+ "doc_path",
1370
+ "finished_at",
1371
+ "canceled_at",
1372
+ "tags",
1373
+ "metadata",
1374
+ "parent_id",
1375
+ "depends_on",
1376
+ "est_tokens",
1377
+ "in_progress_at"
1378
+ ]);
1383
1379
  Object.keys(updates).forEach((key) => {
1384
- if (key !== "comment" && key !== "model" && anyUpdates[key] !== void 0) {
1380
+ if (VALID_COLUMNS.has(key) && anyUpdates[key] !== void 0) {
1385
1381
  if (key === "tags" || key === "metadata") {
1386
1382
  fields.push(`${key} = ?`);
1387
1383
  values.push(JSON.stringify(anyUpdates[key]));
@@ -1899,32 +1895,6 @@ function resolveDbPath() {
1899
1895
  return standardPath;
1900
1896
  }
1901
1897
  var DB_PATH = resolveDbPath();
1902
- var sqlJsReady = null;
1903
- var sqlJsModule = null;
1904
- async function getSqlJs() {
1905
- if (!sqlJsModule) {
1906
- sqlJsModule = await initSqlJs();
1907
- }
1908
- await sqlJsReady;
1909
- return sqlJsModule;
1910
- }
1911
- function createSaveFunction(db, dbPath) {
1912
- return () => {
1913
- if (dbPath && dbPath !== ":memory:") {
1914
- const data = db.export();
1915
- const buffer = Buffer.from(data);
1916
- fs2.writeFileSync(dbPath, buffer);
1917
- }
1918
- };
1919
- }
1920
- function warmUpSqlJs() {
1921
- if (!sqlJsReady) {
1922
- sqlJsReady = (async () => {
1923
- sqlJsModule = await initSqlJs();
1924
- })();
1925
- }
1926
- return sqlJsReady;
1927
- }
1928
1898
  var SQLiteStore = class _SQLiteStore {
1929
1899
  db;
1930
1900
  memories;
@@ -1932,106 +1902,42 @@ var SQLiteStore = class _SQLiteStore {
1932
1902
  actions;
1933
1903
  system;
1934
1904
  summaries;
1935
- _ready;
1936
- lastLoadedAt = 0;
1937
- saveDbPtr;
1938
1905
  dbPathInstance;
1939
1906
  constructor(dbPath) {
1940
1907
  const finalPath = dbPath ?? DB_PATH;
1941
1908
  this.dbPathInstance = finalPath;
1942
- warmUpSqlJs();
1943
- this.db = {};
1944
- this.memories = {};
1945
- this.tasks = {};
1946
- this.actions = {};
1947
- this.system = {};
1948
- this.summaries = {};
1949
- this._ready = this._init(finalPath);
1950
- }
1951
- async _init(finalPath) {
1952
- const SQL = await getSqlJs();
1953
- let db;
1954
- if (finalPath === ":memory:") {
1955
- db = new SQL.Database();
1956
- } else {
1909
+ if (finalPath !== ":memory:") {
1957
1910
  const dbDir = path2.dirname(finalPath);
1958
1911
  if (!fs2.existsSync(dbDir)) {
1959
1912
  fs2.mkdirSync(dbDir, { recursive: true });
1960
1913
  }
1961
- if (fs2.existsSync(finalPath)) {
1962
- const fileBuffer = fs2.readFileSync(finalPath);
1963
- db = new SQL.Database(fileBuffer);
1964
- } else {
1965
- db = new SQL.Database();
1966
- }
1967
1914
  }
1968
- this.saveDbPtr = createSaveFunction(db, finalPath);
1969
- const wrappedSaveDb = () => {
1970
- if (this.saveDbPtr) {
1971
- this.saveDbPtr();
1972
- this.lastLoadedAt = Date.now();
1973
- }
1974
- };
1975
- db.run("PRAGMA journal_mode = WAL");
1976
- db.run("PRAGMA synchronous = NORMAL");
1977
- db.run("PRAGMA busy_timeout = 5000");
1978
- const migrator = new MigrationManager(db, wrappedSaveDb);
1915
+ this.db = new Database(finalPath);
1916
+ this.db.pragma("journal_mode = WAL");
1917
+ this.db.pragma("synchronous = NORMAL");
1918
+ this.db.pragma("busy_timeout = 5000");
1919
+ this.db.pragma("foreign_keys = ON");
1920
+ const migrator = new MigrationManager(this.db);
1979
1921
  migrator.migrate();
1980
1922
  migrator.addMemoryCodeColumn();
1981
- Object.assign(this, {
1982
- db,
1983
- memories: new MemoryEntity(db, wrappedSaveDb),
1984
- tasks: new TaskEntity(db, wrappedSaveDb),
1985
- actions: new ActionEntity(db, wrappedSaveDb),
1986
- system: new SystemEntity(db, wrappedSaveDb),
1987
- summaries: new SummaryEntity(db, wrappedSaveDb)
1988
- });
1989
- this.lastLoadedAt = Date.now();
1990
- if (finalPath !== ":memory:") {
1991
- wrappedSaveDb();
1992
- }
1993
- }
1994
- async refresh(force = false) {
1995
- const path5 = this.getDbPath();
1996
- if (path5 === ":memory:") return;
1997
- try {
1998
- const stats = fs2.statSync(path5);
1999
- const mtime = stats.mtimeMs;
2000
- if (force || mtime > this.lastLoadedAt) {
2001
- const SQL = await getSqlJs();
2002
- const fileBuffer = fs2.readFileSync(path5);
2003
- const newDb = new SQL.Database(fileBuffer);
2004
- const wrappedSaveDb = () => {
2005
- if (this.saveDbPtr) {
2006
- this.saveDbPtr();
2007
- this.lastLoadedAt = Date.now();
2008
- }
2009
- };
2010
- this.db = newDb;
2011
- this.memories = new MemoryEntity(newDb, wrappedSaveDb);
2012
- this.tasks = new TaskEntity(newDb, wrappedSaveDb);
2013
- this.actions = new ActionEntity(newDb, wrappedSaveDb);
2014
- this.system = new SystemEntity(newDb, wrappedSaveDb);
2015
- this.summaries = new SummaryEntity(newDb, wrappedSaveDb);
2016
- this.lastLoadedAt = Date.now();
2017
- }
2018
- } catch (e) {
2019
- console.error("Failed to refresh database from disk:", e);
2020
- }
1923
+ this.memories = new MemoryEntity(this.db);
1924
+ this.tasks = new TaskEntity(this.db);
1925
+ this.actions = new ActionEntity(this.db);
1926
+ this.system = new SystemEntity(this.db);
1927
+ this.summaries = new SummaryEntity(this.db);
2021
1928
  }
2022
1929
  async ready() {
2023
- await this._ready;
1930
+ }
1931
+ async refresh() {
2024
1932
  }
2025
1933
  static async create(dbPath) {
2026
- const store = new _SQLiteStore(dbPath);
2027
- await store.ready();
2028
- return store;
1934
+ return new _SQLiteStore(dbPath);
2029
1935
  }
2030
1936
  getDbPath() {
2031
1937
  return this.dbPathInstance;
2032
1938
  }
2033
1939
  close() {
2034
- if (this.db && this.db.close) {
1940
+ if (this.db && this.db.open) {
2035
1941
  this.db.close();
2036
1942
  }
2037
1943
  }
@@ -2057,7 +1963,8 @@ function updateSessionFromInitialize(session, params) {
2057
1963
  session.clientCapabilities = capabilities;
2058
1964
  session.supportsRoots = Boolean(capabilities.roots);
2059
1965
  session.supportsSampling = Boolean(capabilities.sampling);
2060
- session.supportsSamplingTools = Boolean(capabilities.sampling?.tools);
1966
+ const sampling = capabilities.sampling;
1967
+ session.supportsSamplingTools = Boolean(sampling?.tools);
2061
1968
  session.supportsElicitation = Boolean(capabilities.elicitation);
2062
1969
  session.supportsElicitationForm = supportsElicitationMode(capabilities.elicitation, "form");
2063
1970
  session.supportsElicitationUrl = supportsElicitationMode(capabilities.elicitation, "url");