@vheins/local-memory-mcp 0.8.16 → 0.8.18
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.
|
@@ -1,16 +1,26 @@
|
|
|
1
1
|
// src/mcp/capabilities.ts
|
|
2
2
|
import { fileURLToPath } from "url";
|
|
3
3
|
import path from "path";
|
|
4
|
-
import fs from "fs";
|
|
5
4
|
var __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
6
|
-
var pkgPath = path.join(__dirname, "../../package.json");
|
|
7
5
|
var pkgVersion = "0.1.0";
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
if ("0.8.18") {
|
|
7
|
+
pkgVersion = "0.8.18";
|
|
8
|
+
} else {
|
|
9
|
+
let searchDir = __dirname;
|
|
10
|
+
for (let i = 0; i < 5; i++) {
|
|
11
|
+
const candidate = path.join(searchDir, "package.json");
|
|
12
|
+
try {
|
|
13
|
+
if (fs.existsSync(candidate)) {
|
|
14
|
+
const pkg = JSON.parse(fs.readFileSync(candidate, "utf8"));
|
|
15
|
+
if (pkg.name === "@vheins/local-memory-mcp" && pkg.version) {
|
|
16
|
+
pkgVersion = pkg.version;
|
|
17
|
+
break;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
} catch {
|
|
21
|
+
}
|
|
22
|
+
searchDir = path.dirname(searchDir);
|
|
12
23
|
}
|
|
13
|
-
} catch {
|
|
14
24
|
}
|
|
15
25
|
var MCP_PROTOCOL_VERSION = "2025-11-25";
|
|
16
26
|
var CAPABILITIES = {
|
|
@@ -35,7 +45,7 @@ var CAPABILITIES = {
|
|
|
35
45
|
};
|
|
36
46
|
|
|
37
47
|
// src/mcp/utils/logger.ts
|
|
38
|
-
import
|
|
48
|
+
import fs from "fs";
|
|
39
49
|
var LEVELS = {
|
|
40
50
|
debug: 0,
|
|
41
51
|
info: 1,
|
|
@@ -155,11 +165,11 @@ function addLogSink(sink) {
|
|
|
155
165
|
}
|
|
156
166
|
var LOG_LEVEL_VALUES = Object.keys(LEVELS);
|
|
157
167
|
function createFileSink(logDir, maxFiles = 5) {
|
|
158
|
-
|
|
159
|
-
const existing =
|
|
168
|
+
fs.mkdirSync(logDir, { recursive: true });
|
|
169
|
+
const existing = fs.readdirSync(logDir).filter((f) => f.startsWith("mcp-") && f.endsWith(".log")).sort();
|
|
160
170
|
while (existing.length >= maxFiles) {
|
|
161
171
|
try {
|
|
162
|
-
|
|
172
|
+
fs.unlinkSync(`${logDir}/${existing.shift()}`);
|
|
163
173
|
} catch {
|
|
164
174
|
}
|
|
165
175
|
}
|
|
@@ -169,7 +179,7 @@ function createFileSink(logDir, maxFiles = 5) {
|
|
|
169
179
|
const line = `${(/* @__PURE__ */ new Date()).toISOString()} [${payload.level.toUpperCase()}] [pid:${process.pid}] ${JSON.stringify(payload.data)}
|
|
170
180
|
`;
|
|
171
181
|
try {
|
|
172
|
-
|
|
182
|
+
fs.appendFileSync(logFile, line);
|
|
173
183
|
} catch {
|
|
174
184
|
}
|
|
175
185
|
};
|
|
@@ -178,7 +188,7 @@ function createFileSink(logDir, maxFiles = 5) {
|
|
|
178
188
|
// src/mcp/storage/sqlite.ts
|
|
179
189
|
import Database from "better-sqlite3";
|
|
180
190
|
import path3 from "path";
|
|
181
|
-
import
|
|
191
|
+
import fs3 from "fs";
|
|
182
192
|
import os from "os";
|
|
183
193
|
|
|
184
194
|
// src/mcp/storage/migrations.ts
|
|
@@ -1900,7 +1910,7 @@ var SummaryEntity = class extends BaseEntity {
|
|
|
1900
1910
|
// src/mcp/storage/write-lock.ts
|
|
1901
1911
|
import lockfile from "proper-lockfile";
|
|
1902
1912
|
import path2 from "path";
|
|
1903
|
-
import
|
|
1913
|
+
import fs2 from "fs";
|
|
1904
1914
|
var LOCK_STALE_MS = 3e4;
|
|
1905
1915
|
var LOCK_RETRY_DELAY_MS = 200;
|
|
1906
1916
|
var LOCK_RETRY_COUNT = 250;
|
|
@@ -1909,9 +1919,9 @@ var WriteLock = class {
|
|
|
1909
1919
|
locked = false;
|
|
1910
1920
|
constructor(dbPath) {
|
|
1911
1921
|
this.lockTarget = dbPath;
|
|
1912
|
-
if (!
|
|
1913
|
-
|
|
1914
|
-
|
|
1922
|
+
if (!fs2.existsSync(dbPath)) {
|
|
1923
|
+
fs2.mkdirSync(path2.dirname(dbPath), { recursive: true });
|
|
1924
|
+
fs2.writeFileSync(dbPath, "");
|
|
1915
1925
|
}
|
|
1916
1926
|
}
|
|
1917
1927
|
/**
|
|
@@ -1965,11 +1975,11 @@ function resolveDbPath() {
|
|
|
1965
1975
|
if (process.env.MEMORY_DB_PATH) return process.env.MEMORY_DB_PATH;
|
|
1966
1976
|
const standardConfigDir = process.platform === "win32" ? path3.join(os.homedir(), ".local-memory-mcp") : process.platform === "darwin" ? path3.join(os.homedir(), "Library", "Application Support", "local-memory-mcp") : path3.join(os.homedir(), ".config", "local-memory-mcp");
|
|
1967
1977
|
const standardPath = path3.join(standardConfigDir, "memory.db");
|
|
1968
|
-
if (
|
|
1978
|
+
if (fs3.existsSync(standardPath)) return standardPath;
|
|
1969
1979
|
const legacyPath = path3.join(os.homedir(), ".config", "local-memory-mcp", "memory.db");
|
|
1970
|
-
if (
|
|
1980
|
+
if (fs3.existsSync(legacyPath)) return legacyPath;
|
|
1971
1981
|
const localCwdFile = path3.join(process.cwd(), "storage", "memory.db");
|
|
1972
|
-
if (
|
|
1982
|
+
if (fs3.existsSync(localCwdFile)) return localCwdFile;
|
|
1973
1983
|
return standardPath;
|
|
1974
1984
|
}
|
|
1975
1985
|
var DB_PATH = resolveDbPath();
|
|
@@ -1987,8 +1997,8 @@ var SQLiteStore = class _SQLiteStore {
|
|
|
1987
1997
|
this.dbPathInstance = finalPath;
|
|
1988
1998
|
if (finalPath !== ":memory:") {
|
|
1989
1999
|
const dbDir = path3.dirname(finalPath);
|
|
1990
|
-
if (!
|
|
1991
|
-
|
|
2000
|
+
if (!fs3.existsSync(dbDir)) {
|
|
2001
|
+
fs3.mkdirSync(dbDir, { recursive: true });
|
|
1992
2002
|
}
|
|
1993
2003
|
}
|
|
1994
2004
|
this.db = new Database(finalPath);
|
|
@@ -2040,12 +2050,12 @@ var SQLiteStore = class _SQLiteStore {
|
|
|
2040
2050
|
*/
|
|
2041
2051
|
_attemptRecovery(dbPath) {
|
|
2042
2052
|
const backupPath = dbPath + ".backup";
|
|
2043
|
-
if (
|
|
2053
|
+
if (fs3.existsSync(backupPath)) {
|
|
2044
2054
|
logger.warn("[SQLiteStore] Attempting recovery from backup", { backupPath });
|
|
2045
2055
|
try {
|
|
2046
2056
|
const corruptPath = `${dbPath}.corrupt_${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "").slice(0, 15)}`;
|
|
2047
|
-
|
|
2048
|
-
|
|
2057
|
+
fs3.copyFileSync(dbPath, corruptPath);
|
|
2058
|
+
fs3.copyFileSync(backupPath, dbPath);
|
|
2049
2059
|
logger.warn("[SQLiteStore] Recovery successful. Corrupt file saved to", { corruptPath });
|
|
2050
2060
|
} catch (err) {
|
|
2051
2061
|
logger.error("[SQLiteStore] Recovery failed", { error: String(err) });
|
|
@@ -2063,7 +2073,7 @@ var SQLiteStore = class _SQLiteStore {
|
|
|
2063
2073
|
try {
|
|
2064
2074
|
this.db.pragma("wal_checkpoint(PASSIVE)");
|
|
2065
2075
|
const backupPath = this.dbPathInstance + ".backup";
|
|
2066
|
-
|
|
2076
|
+
fs3.copyFileSync(this.dbPathInstance, backupPath);
|
|
2067
2077
|
} catch (err) {
|
|
2068
2078
|
logger.warn("[SQLiteStore] Backup failed", { error: String(err) });
|
|
2069
2079
|
}
|
|
@@ -3670,7 +3680,7 @@ function invalidCompletionParams(message) {
|
|
|
3670
3680
|
}
|
|
3671
3681
|
|
|
3672
3682
|
// src/mcp/prompts/loader.ts
|
|
3673
|
-
import
|
|
3683
|
+
import fs4 from "fs";
|
|
3674
3684
|
import path5 from "path";
|
|
3675
3685
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
3676
3686
|
import matter from "gray-matter";
|
|
@@ -3686,8 +3696,8 @@ function findPromptDir() {
|
|
|
3686
3696
|
"./definitions"
|
|
3687
3697
|
].map((relPath) => path5.resolve(__dirname2, relPath));
|
|
3688
3698
|
for (const dir of candidates) {
|
|
3689
|
-
if (
|
|
3690
|
-
const files =
|
|
3699
|
+
if (fs4.existsSync(dir)) {
|
|
3700
|
+
const files = fs4.readdirSync(dir);
|
|
3691
3701
|
if (files.some((f) => f.endsWith(".md"))) {
|
|
3692
3702
|
return dir;
|
|
3693
3703
|
}
|
|
@@ -3697,15 +3707,15 @@ function findPromptDir() {
|
|
|
3697
3707
|
}
|
|
3698
3708
|
var PROMPT_DIR = findPromptDir();
|
|
3699
3709
|
function listPromptFiles() {
|
|
3700
|
-
if (!
|
|
3701
|
-
return
|
|
3710
|
+
if (!fs4.existsSync(PROMPT_DIR)) return [];
|
|
3711
|
+
return fs4.readdirSync(PROMPT_DIR).filter((file) => file.endsWith(".md")).map((file) => file.replace(/\.md$/, "")).sort();
|
|
3702
3712
|
}
|
|
3703
3713
|
function loadPromptFromMarkdown(name) {
|
|
3704
3714
|
const filePath = path5.join(PROMPT_DIR, `${name}.md`);
|
|
3705
|
-
if (!
|
|
3715
|
+
if (!fs4.existsSync(filePath)) {
|
|
3706
3716
|
throw new Error(`Prompt file not found: ${filePath}`);
|
|
3707
3717
|
}
|
|
3708
|
-
const fileContent =
|
|
3718
|
+
const fileContent = fs4.readFileSync(filePath, "utf-8");
|
|
3709
3719
|
const { data, content } = matter(fileContent);
|
|
3710
3720
|
return {
|
|
3711
3721
|
name: data.name || name,
|
package/dist/dashboard/server.js
CHANGED
package/dist/mcp/server.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vheins/local-memory-mcp",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.18",
|
|
4
4
|
"description": "MCP Local Memory Service for coding copilot agents",
|
|
5
5
|
"mcpName": "io.github.vheins/local-memory-mcp",
|
|
6
6
|
"type": "module",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"author": "Muhammad Rheza Alfin <m.rheza.alfin@gmail.com>",
|
|
28
28
|
"license": "MIT",
|
|
29
29
|
"scripts": {
|
|
30
|
-
"build": "rm -rf dist && npm run dashboard:build && tsup
|
|
30
|
+
"build": "rm -rf dist && npm run dashboard:build && tsup --config tsup.config.ts && mkdir -p bin && cp -r src/mcp/prompts/definitions dist/prompts/ && printf \"#!/usr/bin/env node\\nimport '../dist/dashboard/server.js';\\n\" > bin/mcp-memory-dashboard.js && shx chmod +x dist/mcp/server.js dist/dashboard/server.js bin/mcp-memory-server.js bin/mcp-memory-dashboard.js",
|
|
31
31
|
"dashboard:build": "vite build --config src/dashboard/ui/vite.config.ts",
|
|
32
32
|
"dashboard:dev": "vite dev --config src/dashboard/ui/vite.config.ts",
|
|
33
33
|
"prepare": "npm run build",
|