@prom.codes/memory-mcp 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.js +194 -46
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -4,10 +4,189 @@
|
|
|
4
4
|
import { McpServer as McpServer2 } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
5
5
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
6
6
|
|
|
7
|
+
// ../shared/dist/types.js
|
|
8
|
+
var GRAMMAR_LANGUAGE_IDS = [
|
|
9
|
+
"typescript",
|
|
10
|
+
"tsx",
|
|
11
|
+
"javascript",
|
|
12
|
+
"python",
|
|
13
|
+
"php",
|
|
14
|
+
"go",
|
|
15
|
+
"rust",
|
|
16
|
+
"java",
|
|
17
|
+
"csharp",
|
|
18
|
+
"c",
|
|
19
|
+
"cpp",
|
|
20
|
+
"ruby",
|
|
21
|
+
"kotlin",
|
|
22
|
+
"html"
|
|
23
|
+
];
|
|
24
|
+
var DOCUMENT_LANGUAGE_IDS = [
|
|
25
|
+
"markdown",
|
|
26
|
+
"text",
|
|
27
|
+
"json",
|
|
28
|
+
"yaml",
|
|
29
|
+
"toml"
|
|
30
|
+
];
|
|
31
|
+
var LANGUAGE_IDS = [
|
|
32
|
+
...GRAMMAR_LANGUAGE_IDS,
|
|
33
|
+
...DOCUMENT_LANGUAGE_IDS
|
|
34
|
+
];
|
|
35
|
+
|
|
36
|
+
// ../shared/dist/update-check.js
|
|
37
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
38
|
+
import { homedir } from "node:os";
|
|
39
|
+
import { join } from "node:path";
|
|
40
|
+
import { fileURLToPath } from "node:url";
|
|
41
|
+
async function packageIdentity(binImportMetaUrl) {
|
|
42
|
+
try {
|
|
43
|
+
const binPath = fileURLToPath(binImportMetaUrl);
|
|
44
|
+
const pkgPath = join(binPath, "..", "..", "package.json");
|
|
45
|
+
const raw = await readFile(pkgPath, "utf8");
|
|
46
|
+
const parsed = JSON.parse(raw);
|
|
47
|
+
if (typeof parsed.name !== "string" || typeof parsed.version !== "string") {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
return { name: parsed.name, version: parsed.version };
|
|
51
|
+
} catch {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
async function maybeNotifyUpdate(binImportMetaUrl, env = process.env) {
|
|
56
|
+
try {
|
|
57
|
+
const id = await packageIdentity(binImportMetaUrl);
|
|
58
|
+
if (id === null)
|
|
59
|
+
return;
|
|
60
|
+
await checkForUpdate({ name: id.name, version: id.version, env });
|
|
61
|
+
} catch {
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
var DEFAULT_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
65
|
+
var DEFAULT_TIMEOUT_MS = 1500;
|
|
66
|
+
var OPT_OUT_RE = /^(1|true|yes|on)$/i;
|
|
67
|
+
function parseSemver(v) {
|
|
68
|
+
const m = /^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?/.exec(v.trim());
|
|
69
|
+
if (m === null)
|
|
70
|
+
return null;
|
|
71
|
+
return {
|
|
72
|
+
core: [Number(m[1]), Number(m[2]), Number(m[3])],
|
|
73
|
+
pre: m[4] ?? null
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
function isNewerVersion(latest, current) {
|
|
77
|
+
const a = parseSemver(latest);
|
|
78
|
+
const b = parseSemver(current);
|
|
79
|
+
if (a === null || b === null)
|
|
80
|
+
return false;
|
|
81
|
+
for (let i = 0; i < 3; i++) {
|
|
82
|
+
if (a.core[i] > b.core[i])
|
|
83
|
+
return true;
|
|
84
|
+
if (a.core[i] < b.core[i])
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
if (a.pre === null && b.pre !== null)
|
|
88
|
+
return true;
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
function cachePath(dir, name) {
|
|
92
|
+
const safe = name.replace(/[^a-zA-Z0-9._-]+/g, "_");
|
|
93
|
+
return join(dir, `.update-check-${safe}.json`);
|
|
94
|
+
}
|
|
95
|
+
async function readCache(path2) {
|
|
96
|
+
try {
|
|
97
|
+
const raw = await readFile(path2, "utf8");
|
|
98
|
+
const parsed = JSON.parse(raw);
|
|
99
|
+
if (typeof parsed.checkedAt !== "number")
|
|
100
|
+
return null;
|
|
101
|
+
return {
|
|
102
|
+
checkedAt: parsed.checkedAt,
|
|
103
|
+
latest: typeof parsed.latest === "string" ? parsed.latest : null
|
|
104
|
+
};
|
|
105
|
+
} catch {
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
async function writeCache(path2, data) {
|
|
110
|
+
try {
|
|
111
|
+
await writeFile(path2, JSON.stringify(data), "utf8");
|
|
112
|
+
} catch {
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
async function fetchLatest(name, fetchImpl, timeoutMs) {
|
|
116
|
+
const controller = new AbortController();
|
|
117
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
118
|
+
timer.unref?.();
|
|
119
|
+
try {
|
|
120
|
+
const url = `https://registry.npmjs.org/${name.replace("/", "%2F")}/latest`;
|
|
121
|
+
const res = await fetchImpl(url, {
|
|
122
|
+
signal: controller.signal,
|
|
123
|
+
headers: { accept: "application/vnd.npm.install-v1+json" }
|
|
124
|
+
});
|
|
125
|
+
if (!res.ok)
|
|
126
|
+
return null;
|
|
127
|
+
const body = await res.json();
|
|
128
|
+
return typeof body.version === "string" ? body.version : null;
|
|
129
|
+
} catch {
|
|
130
|
+
return null;
|
|
131
|
+
} finally {
|
|
132
|
+
clearTimeout(timer);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
async function checkForUpdate(options) {
|
|
136
|
+
const { name, version, env = process.env, log = (line) => process.stderr.write(line), fetch: fetchImpl = globalThis.fetch, cacheDir = join(homedir(), ".prometheus"), cacheTtlMs = DEFAULT_TTL_MS, timeoutMs = DEFAULT_TIMEOUT_MS, force = false } = options;
|
|
137
|
+
const base = {
|
|
138
|
+
latest: null,
|
|
139
|
+
current: version
|
|
140
|
+
};
|
|
141
|
+
if (OPT_OUT_RE.test(env.PROMETHEUS_NO_UPDATE_CHECK ?? "")) {
|
|
142
|
+
return { ...base, checked: false, updateAvailable: false, reason: "opted-out" };
|
|
143
|
+
}
|
|
144
|
+
if (parseSemver(version) === null || version === "0.0.0") {
|
|
145
|
+
return { ...base, checked: false, updateAvailable: false, reason: "invalid-version" };
|
|
146
|
+
}
|
|
147
|
+
if (typeof fetchImpl !== "function") {
|
|
148
|
+
return { ...base, checked: false, updateAvailable: false, reason: "error" };
|
|
149
|
+
}
|
|
150
|
+
const file = cachePath(cacheDir, name);
|
|
151
|
+
const now = Date.now();
|
|
152
|
+
if (!force) {
|
|
153
|
+
const cached = await readCache(file);
|
|
154
|
+
if (cached !== null && now - cached.checkedAt < cacheTtlMs) {
|
|
155
|
+
const updateAvailable2 = cached.latest !== null && isNewerVersion(cached.latest, version);
|
|
156
|
+
if (updateAvailable2)
|
|
157
|
+
notify(log, name, version, cached.latest);
|
|
158
|
+
return {
|
|
159
|
+
...base,
|
|
160
|
+
latest: cached.latest,
|
|
161
|
+
checked: false,
|
|
162
|
+
updateAvailable: updateAvailable2,
|
|
163
|
+
reason: "throttled"
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
await mkdir(cacheDir, { recursive: true }).catch(() => void 0);
|
|
168
|
+
const latest = await fetchLatest(name, fetchImpl, timeoutMs);
|
|
169
|
+
await writeCache(file, { checkedAt: now, latest });
|
|
170
|
+
if (latest === null) {
|
|
171
|
+
return { ...base, checked: true, updateAvailable: false, reason: "error" };
|
|
172
|
+
}
|
|
173
|
+
const updateAvailable = isNewerVersion(latest, version);
|
|
174
|
+
if (updateAvailable)
|
|
175
|
+
notify(log, name, version, latest);
|
|
176
|
+
return { ...base, latest, checked: true, updateAvailable };
|
|
177
|
+
}
|
|
178
|
+
function notify(log, name, current, latest) {
|
|
179
|
+
log(`${name}: a newer version (${latest}) is available \u2014 you are on ${current}. npx users get it automatically on the next restart; for a global install run \`npm update -g ${name}\`. (Set PROMETHEUS_NO_UPDATE_CHECK=1 to silence.)
|
|
180
|
+
`);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// ../shared/dist/index.js
|
|
184
|
+
var PROMETHEUS_VERSION = "0.1.0";
|
|
185
|
+
|
|
7
186
|
// dist/composition.js
|
|
8
187
|
import { createHash } from "node:crypto";
|
|
9
|
-
import { homedir } from "node:os";
|
|
10
|
-
import { basename, join, resolve } from "node:path";
|
|
188
|
+
import { homedir as homedir2 } from "node:os";
|
|
189
|
+
import { basename, join as join2, resolve } from "node:path";
|
|
11
190
|
|
|
12
191
|
// ../embeddings-openai-compat/dist/index.js
|
|
13
192
|
var DEFAULT_BATCH = 96;
|
|
@@ -1695,7 +1874,7 @@ function projectIdFor(workspaceRoot) {
|
|
|
1695
1874
|
return createHash("sha256").update(abs).digest("hex").slice(0, 16);
|
|
1696
1875
|
}
|
|
1697
1876
|
function defaultMemoryDbPath() {
|
|
1698
|
-
return
|
|
1877
|
+
return join2(homedir2(), ".prometheus", "memory.db");
|
|
1699
1878
|
}
|
|
1700
1879
|
function intEnv(env, name, def) {
|
|
1701
1880
|
const raw = env[name];
|
|
@@ -1935,7 +2114,7 @@ function composeFromEnv(opts) {
|
|
|
1935
2114
|
}
|
|
1936
2115
|
|
|
1937
2116
|
// dist/roots.js
|
|
1938
|
-
import { fileURLToPath } from "node:url";
|
|
2117
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
1939
2118
|
async function rootFromClient(server, timeoutMs = 2500) {
|
|
1940
2119
|
let supportsRoots = false;
|
|
1941
2120
|
try {
|
|
@@ -1956,7 +2135,7 @@ async function rootFromClient(server, timeoutMs = 2500) {
|
|
|
1956
2135
|
const uri = typeof r?.uri === "string" ? r.uri : "";
|
|
1957
2136
|
if (uri.startsWith("file://")) {
|
|
1958
2137
|
try {
|
|
1959
|
-
return
|
|
2138
|
+
return fileURLToPath2(uri);
|
|
1960
2139
|
} catch {
|
|
1961
2140
|
}
|
|
1962
2141
|
}
|
|
@@ -1967,38 +2146,6 @@ async function rootFromClient(server, timeoutMs = 2500) {
|
|
|
1967
2146
|
// dist/server.js
|
|
1968
2147
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
1969
2148
|
|
|
1970
|
-
// ../shared/dist/types.js
|
|
1971
|
-
var GRAMMAR_LANGUAGE_IDS = [
|
|
1972
|
-
"typescript",
|
|
1973
|
-
"tsx",
|
|
1974
|
-
"javascript",
|
|
1975
|
-
"python",
|
|
1976
|
-
"php",
|
|
1977
|
-
"go",
|
|
1978
|
-
"rust",
|
|
1979
|
-
"java",
|
|
1980
|
-
"csharp",
|
|
1981
|
-
"c",
|
|
1982
|
-
"cpp",
|
|
1983
|
-
"ruby",
|
|
1984
|
-
"kotlin",
|
|
1985
|
-
"html"
|
|
1986
|
-
];
|
|
1987
|
-
var DOCUMENT_LANGUAGE_IDS = [
|
|
1988
|
-
"markdown",
|
|
1989
|
-
"text",
|
|
1990
|
-
"json",
|
|
1991
|
-
"yaml",
|
|
1992
|
-
"toml"
|
|
1993
|
-
];
|
|
1994
|
-
var LANGUAGE_IDS = [
|
|
1995
|
-
...GRAMMAR_LANGUAGE_IDS,
|
|
1996
|
-
...DOCUMENT_LANGUAGE_IDS
|
|
1997
|
-
];
|
|
1998
|
-
|
|
1999
|
-
// ../shared/dist/index.js
|
|
2000
|
-
var PROMETHEUS_VERSION = "0.1.0";
|
|
2001
|
-
|
|
2002
2149
|
// dist/tools.js
|
|
2003
2150
|
import { z } from "zod";
|
|
2004
2151
|
|
|
@@ -2119,8 +2266,8 @@ function assertNoSecrets(text) {
|
|
|
2119
2266
|
|
|
2120
2267
|
// dist/setup.js
|
|
2121
2268
|
import { existsSync } from "node:fs";
|
|
2122
|
-
import { mkdir as
|
|
2123
|
-
import { dirname as dirname2, join as
|
|
2269
|
+
import { mkdir as mkdir3, readFile as readFile3, writeFile as writeFile3 } from "node:fs/promises";
|
|
2270
|
+
import { dirname as dirname2, join as join4 } from "node:path";
|
|
2124
2271
|
var MEMORY_RUNTIMES = [
|
|
2125
2272
|
"claude-code",
|
|
2126
2273
|
"cursor",
|
|
@@ -2164,13 +2311,13 @@ alwaysApply: true
|
|
|
2164
2311
|
var TARGETS = {
|
|
2165
2312
|
"claude-code": { relPath: "CLAUDE.md", mode: "block", detect: "CLAUDE.md" },
|
|
2166
2313
|
cursor: {
|
|
2167
|
-
relPath:
|
|
2314
|
+
relPath: join4(".cursor", "rules", "prometheus-memory.mdc"),
|
|
2168
2315
|
mode: "file",
|
|
2169
2316
|
fileContent: CURSOR_FRONTMATTER + withMarkers(RULE_BLOCK) + "\n",
|
|
2170
2317
|
detect: ".cursor"
|
|
2171
2318
|
},
|
|
2172
2319
|
augment: {
|
|
2173
|
-
relPath:
|
|
2320
|
+
relPath: join4(".augment", "rules", "prometheus-memory.md"),
|
|
2174
2321
|
mode: "file",
|
|
2175
2322
|
fileContent: withMarkers(RULE_BLOCK) + "\n",
|
|
2176
2323
|
detect: ".augment"
|
|
@@ -2178,7 +2325,7 @@ var TARGETS = {
|
|
|
2178
2325
|
agents: { relPath: "AGENTS.md", mode: "block", detect: "AGENTS.md" }
|
|
2179
2326
|
};
|
|
2180
2327
|
function detectRuntimes(workspaceRoot) {
|
|
2181
|
-
const found = MEMORY_RUNTIMES.filter((rt) => existsSync(
|
|
2328
|
+
const found = MEMORY_RUNTIMES.filter((rt) => existsSync(join4(workspaceRoot, TARGETS[rt].detect)));
|
|
2182
2329
|
return found.length > 0 ? found : ["agents"];
|
|
2183
2330
|
}
|
|
2184
2331
|
function upsertBlock(existing, block) {
|
|
@@ -2193,15 +2340,15 @@ function upsertBlock(existing, block) {
|
|
|
2193
2340
|
}
|
|
2194
2341
|
async function installRuntime(workspaceRoot, runtime) {
|
|
2195
2342
|
const target = TARGETS[runtime];
|
|
2196
|
-
const absPath =
|
|
2343
|
+
const absPath = join4(workspaceRoot, target.relPath);
|
|
2197
2344
|
const exists = existsSync(absPath);
|
|
2198
|
-
const before = exists ? await
|
|
2345
|
+
const before = exists ? await readFile3(absPath, "utf-8") : "";
|
|
2199
2346
|
const after = target.mode === "file" ? target.fileContent : upsertBlock(before, RULE_BLOCK);
|
|
2200
2347
|
if (exists && before === after) {
|
|
2201
2348
|
return { runtime, path: absPath, action: "unchanged" };
|
|
2202
2349
|
}
|
|
2203
|
-
await
|
|
2204
|
-
await
|
|
2350
|
+
await mkdir3(dirname2(absPath), { recursive: true });
|
|
2351
|
+
await writeFile3(absPath, after, "utf-8");
|
|
2205
2352
|
return { runtime, path: absPath, action: exists ? "updated" : "created" };
|
|
2206
2353
|
}
|
|
2207
2354
|
|
|
@@ -2563,6 +2710,7 @@ async function main() {
|
|
|
2563
2710
|
const explicitRoot = (env.PROMETHEUS_WORKSPACE_ROOT ?? "").trim();
|
|
2564
2711
|
const claudeRoot = (env.CLAUDE_PROJECT_DIR ?? "").trim();
|
|
2565
2712
|
const eagerVia = explicitRoot !== "" ? "PROMETHEUS_WORKSPACE_ROOT" : claudeRoot !== "" ? "CLAUDE_PROJECT_DIR" : null;
|
|
2713
|
+
void maybeNotifyUpdate(import.meta.url, env);
|
|
2566
2714
|
const transport = new StdioServerTransport();
|
|
2567
2715
|
const server = new McpServer2(SERVER_IDENTITY, {
|
|
2568
2716
|
capabilities: { tools: {} },
|