@prom.codes/memory-mcp 0.14.0 → 0.15.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.
Files changed (2) hide show
  1. package/dist/bin.js +94 -46
  2. package/package.json +12 -2
package/dist/bin.js CHANGED
@@ -209,15 +209,15 @@ async function checkForUpdate(options) {
209
209
  const file = cachePath(cacheDir, name);
210
210
  const now = Date.now();
211
211
  if (!force) {
212
- const cached = await readCache(file);
213
- if (cached !== null && now - cached.checkedAt < cacheTtlMs && !cachedLatestIsStale(cached.latest, version)) {
214
- const updateAvailable2 = cached.latest !== null && isNewerVersion(cached.latest, version);
212
+ const cached2 = await readCache(file);
213
+ if (cached2 !== null && now - cached2.checkedAt < cacheTtlMs && !cachedLatestIsStale(cached2.latest, version)) {
214
+ const updateAvailable2 = cached2.latest !== null && isNewerVersion(cached2.latest, version);
215
215
  if (updateAvailable2)
216
- notify(log, name, version, cached.latest);
217
- await syncAvailabilityMarker(cacheDir, name, version, cached.latest, updateAvailable2);
216
+ notify(log, name, version, cached2.latest);
217
+ await syncAvailabilityMarker(cacheDir, name, version, cached2.latest, updateAvailable2);
218
218
  return {
219
219
  ...base,
220
- latest: cached.latest,
220
+ latest: cached2.latest,
221
221
  checked: false,
222
222
  updateAvailable: updateAvailable2,
223
223
  reason: "throttled"
@@ -239,14 +239,14 @@ async function checkForUpdate(options) {
239
239
  async function getLatestVersion(name, options = {}) {
240
240
  const { env = process.env, fetch: fetchImpl = globalThis.fetch, cacheDir = join(homedir(), ".prometheus"), cacheTtlMs = DEFAULT_TTL_MS, timeoutMs = DEFAULT_TIMEOUT_MS, minVersion } = options;
241
241
  const file = cachePath(cacheDir, name);
242
- const cached = await readCache(file);
242
+ const cached2 = await readCache(file);
243
243
  const now = Date.now();
244
- const stale = cachedLatestIsStale(cached?.latest ?? null, minVersion);
245
- if (cached !== null && cached.latest !== null && now - cached.checkedAt < cacheTtlMs && !stale) {
246
- return cached.latest;
244
+ const stale = cachedLatestIsStale(cached2?.latest ?? null, minVersion);
245
+ if (cached2 !== null && cached2.latest !== null && now - cached2.checkedAt < cacheTtlMs && !stale) {
246
+ return cached2.latest;
247
247
  }
248
248
  if (OPT_OUT_RE.test(env.PROMETHEUS_NO_UPDATE_CHECK ?? "") || typeof fetchImpl !== "function") {
249
- return stale ? null : cached?.latest ?? null;
249
+ return stale ? null : cached2?.latest ?? null;
250
250
  }
251
251
  const latest = await fetchLatest(name, fetchImpl, timeoutMs);
252
252
  if (latest !== null) {
@@ -254,7 +254,7 @@ async function getLatestVersion(name, options = {}) {
254
254
  await writeCache(file, { checkedAt: now, latest });
255
255
  return latest;
256
256
  }
257
- return stale ? null : cached?.latest ?? null;
257
+ return stale ? null : cached2?.latest ?? null;
258
258
  }
259
259
  function notify(log, name, current, latest) {
260
260
  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.)
@@ -426,10 +426,58 @@ function createIdleWatchdog(options) {
426
426
  };
427
427
  }
428
428
 
429
+ // ../shared/dist/native-binding.js
430
+ import { createRequire } from "node:module";
431
+ import { dirname as dirname2, join as join4 } from "node:path";
432
+ import { existsSync } from "node:fs";
433
+ var require_ = createRequire(import.meta.url);
434
+ function isMusl() {
435
+ try {
436
+ const report = process.report?.getReport();
437
+ const header = typeof report === "object" && report !== null ? report : {};
438
+ return header.header?.glibcVersionRuntime === void 0;
439
+ } catch {
440
+ return false;
441
+ }
442
+ }
443
+ function platformToken(platform = process.platform, arch = process.arch, musl = platform === "linux" && isMusl()) {
444
+ const os = platform === "linux" && musl ? "linuxmusl" : platform;
445
+ return `${os}-${arch}`;
446
+ }
447
+ function nativePackageName(token = platformToken()) {
448
+ return `@prom.codes/native-${token}`;
449
+ }
450
+ function addonFileName(abi = process.versions.modules) {
451
+ return `better_sqlite3/node-v${abi}.node`;
452
+ }
453
+ var cached;
454
+ function resolveNativeBinding() {
455
+ if (cached !== void 0)
456
+ return cached ?? void 0;
457
+ cached = null;
458
+ const override = process.env.PROMETHEUS_SQLITE_NATIVE_BINDING?.trim();
459
+ if (override) {
460
+ cached = existsSync(override) ? override : null;
461
+ return cached ?? void 0;
462
+ }
463
+ try {
464
+ const manifest = require_.resolve(`${nativePackageName()}/package.json`);
465
+ const candidate = join4(dirname2(manifest), addonFileName());
466
+ cached = existsSync(candidate) ? candidate : null;
467
+ } catch {
468
+ cached = null;
469
+ }
470
+ return cached ?? void 0;
471
+ }
472
+ function nativeBindingOption() {
473
+ const p = resolveNativeBinding();
474
+ return p ? { nativeBinding: p } : {};
475
+ }
476
+
429
477
  // dist/composition.js
430
478
  import { createHash } from "node:crypto";
431
479
  import { homedir as homedir5 } from "node:os";
432
- import { basename, join as join6, resolve as resolve2 } from "node:path";
480
+ import { basename, join as join7, resolve as resolve2 } from "node:path";
433
481
 
434
482
  // ../embeddings-openai-compat/dist/index.js
435
483
  var DEFAULT_BATCH = 96;
@@ -1763,7 +1811,7 @@ var OpenAICompatRewriter = class {
1763
1811
  // dist/sqlite.js
1764
1812
  import { randomUUID } from "node:crypto";
1765
1813
  import { mkdirSync as mkdirSync3, readdirSync as readdirSync2, readFileSync as readFileSync3, rmSync as rmSync2 } from "node:fs";
1766
- import { dirname as dirname3, join as join5 } from "node:path";
1814
+ import { dirname as dirname4, join as join6 } from "node:path";
1767
1815
  import Database from "better-sqlite3";
1768
1816
 
1769
1817
  // dist/security.js
@@ -1810,9 +1858,9 @@ function assertNoSecrets(text) {
1810
1858
  }
1811
1859
 
1812
1860
  // dist/recorder.js
1813
- import { copyFileSync, existsSync, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "node:fs";
1861
+ import { copyFileSync, existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "node:fs";
1814
1862
  import { homedir as homedir4 } from "node:os";
1815
- import { dirname as dirname2, join as join4 } from "node:path";
1863
+ import { dirname as dirname3, join as join5 } from "node:path";
1816
1864
  var SPOOL_VERSION = 1;
1817
1865
  var SECRET_PATTERN_SOURCES = [
1818
1866
  "sk-proj-[A-Za-z0-9_-]{20,}",
@@ -1840,8 +1888,8 @@ var REDACT_RE = new RegExp(`(${SECRET_PATTERN_SOURCES.join(")|(")})`, "gi");
1840
1888
  var EVENT_CAP_BYTES = 4 * 1024;
1841
1889
  var SPOOL_CAP_BYTES = 4 * 1024 * 1024;
1842
1890
  function recorderRoot(env = process.env) {
1843
- const base = env.PROMETHEUS_DIR && env.PROMETHEUS_DIR !== "" ? env.PROMETHEUS_DIR : join4(homedir4(), ".prometheus");
1844
- return join4(base, "recorder");
1891
+ const base = env.PROMETHEUS_DIR && env.PROMETHEUS_DIR !== "" ? env.PROMETHEUS_DIR : join5(homedir4(), ".prometheus");
1892
+ return join5(base, "recorder");
1845
1893
  }
1846
1894
  function sanitizeSegment(s) {
1847
1895
  return s.replace(/[^A-Za-z0-9._-]/g, "_").slice(0, 128) || "_";
@@ -2001,20 +2049,20 @@ function resolveSettingsPath(opts) {
2001
2049
  return opts.settingsPathOverride;
2002
2050
  const root = opts.projectRoot ?? process.cwd();
2003
2051
  if (opts.scope === "project")
2004
- return join4(root, ".claude", "settings.json");
2052
+ return join5(root, ".claude", "settings.json");
2005
2053
  if (opts.scope === "project-local")
2006
- return join4(root, ".claude", "settings.local.json");
2007
- return join4(homedir4(), ".claude", "settings.json");
2054
+ return join5(root, ".claude", "settings.local.json");
2055
+ return join5(homedir4(), ".claude", "settings.json");
2008
2056
  }
2009
2057
  function resolveHookPath(opts) {
2010
- const dir = opts.hookDirOverride ?? join4(homedir4(), ".prometheus", "hooks");
2011
- return join4(dir, RECORDER_HOOK_FILENAME);
2058
+ const dir = opts.hookDirOverride ?? join5(homedir4(), ".prometheus", "hooks");
2059
+ return join5(dir, RECORDER_HOOK_FILENAME);
2012
2060
  }
2013
2061
  function ownsEntry(entry) {
2014
2062
  return Array.isArray(entry.hooks) && entry.hooks.some((h) => typeof h?.command === "string" && h.command.includes(RECORDER_HOOK_FILENAME));
2015
2063
  }
2016
2064
  function readSettings(settingsPath) {
2017
- if (!existsSync(settingsPath))
2065
+ if (!existsSync2(settingsPath))
2018
2066
  return {};
2019
2067
  const raw = readFileSync2(settingsPath, "utf8").replace(/^/, "");
2020
2068
  if (raw.trim() === "")
@@ -2026,7 +2074,7 @@ function readSettings(settingsPath) {
2026
2074
  return parsed;
2027
2075
  }
2028
2076
  function backupSettings(settingsPath) {
2029
- if (!existsSync(settingsPath))
2077
+ if (!existsSync2(settingsPath))
2030
2078
  return null;
2031
2079
  const d = /* @__PURE__ */ new Date();
2032
2080
  const p = (n) => String(n).padStart(2, "0");
@@ -2054,7 +2102,7 @@ function recorderStatus(opts = {}) {
2054
2102
  scope: opts.scope ?? "user",
2055
2103
  events: installedEvents,
2056
2104
  settingsPath,
2057
- hookScriptPresent: existsSync(hookPath)
2105
+ hookScriptPresent: existsSync2(hookPath)
2058
2106
  };
2059
2107
  }
2060
2108
  function applyRecorderHooks(opts = {}) {
@@ -2076,7 +2124,7 @@ function applyRecorderHooks(opts = {}) {
2076
2124
  }
2077
2125
  }
2078
2126
  if (!opts.uninstall) {
2079
- mkdirSync2(dirname2(hookPath), { recursive: true });
2127
+ mkdirSync2(dirname3(hookPath), { recursive: true });
2080
2128
  writeFileSync2(hookPath, RECORDER_HOOK_SCRIPT, "utf8");
2081
2129
  for (const ev of RECORDER_EVENTS) {
2082
2130
  const matcher = ev === "PostToolUse" ? "*" : "";
@@ -2088,7 +2136,7 @@ function applyRecorderHooks(opts = {}) {
2088
2136
  }
2089
2137
  if (settings.hooks && Object.keys(settings.hooks).length === 0)
2090
2138
  delete settings.hooks;
2091
- mkdirSync2(dirname2(settingsPath), { recursive: true });
2139
+ mkdirSync2(dirname3(settingsPath), { recursive: true });
2092
2140
  writeFileSync2(settingsPath, `${JSON.stringify(settings, null, 2)}
2093
2141
  `, "utf8");
2094
2142
  JSON.parse(readFileSync2(settingsPath, "utf8"));
@@ -2539,9 +2587,9 @@ var SqliteMemoryBackend = class {
2539
2587
  closed = false;
2540
2588
  constructor(dbPath, opts = {}) {
2541
2589
  if (dbPath !== ":memory:") {
2542
- mkdirSync3(dirname3(dbPath), { recursive: true });
2590
+ mkdirSync3(dirname4(dbPath), { recursive: true });
2543
2591
  }
2544
- this.db = new Database(dbPath);
2592
+ this.db = new Database(dbPath, { ...nativeBindingOption() });
2545
2593
  this.db.pragma("journal_mode = WAL");
2546
2594
  this.db.pragma("synchronous = NORMAL");
2547
2595
  this.db.exec(SCHEMA);
@@ -2987,7 +3035,7 @@ ${h.record.value}`
2987
3035
  * spool never aborts the sweep. Returns roll-up counts.
2988
3036
  */
2989
3037
  async ingestSpoolDir(projectId, env = process.env) {
2990
- const dir = join5(recorderRoot(env), sanitizeSegment(projectId));
3038
+ const dir = join6(recorderRoot(env), sanitizeSegment(projectId));
2991
3039
  let sessions = 0;
2992
3040
  let events = 0;
2993
3041
  let deletedSpools = 0;
@@ -2998,7 +3046,7 @@ ${h.record.value}`
2998
3046
  return { sessions: 0, events: 0, deletedSpools: 0 };
2999
3047
  }
3000
3048
  for (const file of files) {
3001
- const full = join5(dir, file);
3049
+ const full = join6(dir, file);
3002
3050
  try {
3003
3051
  const raw = readFileSync3(full, "utf8");
3004
3052
  const parsed = parseSpool(raw);
@@ -3171,7 +3219,7 @@ function projectIdFor(workspaceRoot) {
3171
3219
  return createHash("sha256").update(abs).digest("hex").slice(0, 16);
3172
3220
  }
3173
3221
  function defaultMemoryDbPath() {
3174
- return join6(homedir5(), ".prometheus", "memory.db");
3222
+ return join7(homedir5(), ".prometheus", "memory.db");
3175
3223
  }
3176
3224
  function intEnv(env, name, def) {
3177
3225
  const raw = env[name];
@@ -3764,9 +3812,9 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3764
3812
  import { z } from "zod";
3765
3813
 
3766
3814
  // dist/setup.js
3767
- import { existsSync as existsSync2, readFileSync as readFileSync4 } from "node:fs";
3815
+ import { existsSync as existsSync3, readFileSync as readFileSync4 } from "node:fs";
3768
3816
  import { mkdir as mkdir3, readFile as readFile3, writeFile as writeFile3 } from "node:fs/promises";
3769
- import { dirname as dirname4, join as join8 } from "node:path";
3817
+ import { dirname as dirname5, join as join9 } from "node:path";
3770
3818
  var MEMORY_RUNTIMES = [
3771
3819
  "claude-code",
3772
3820
  "cursor",
@@ -3810,13 +3858,13 @@ alwaysApply: true
3810
3858
  var TARGETS = {
3811
3859
  "claude-code": { relPath: "CLAUDE.md", mode: "block", detect: "CLAUDE.md" },
3812
3860
  cursor: {
3813
- relPath: join8(".cursor", "rules", "prometheus-memory.mdc"),
3861
+ relPath: join9(".cursor", "rules", "prometheus-memory.mdc"),
3814
3862
  mode: "file",
3815
3863
  fileContent: CURSOR_FRONTMATTER + withMarkers(RULE_BLOCK) + "\n",
3816
3864
  detect: ".cursor"
3817
3865
  },
3818
3866
  augment: {
3819
- relPath: join8(".augment", "rules", "prometheus-memory.md"),
3867
+ relPath: join9(".augment", "rules", "prometheus-memory.md"),
3820
3868
  mode: "file",
3821
3869
  fileContent: withMarkers(RULE_BLOCK) + "\n",
3822
3870
  detect: ".augment"
@@ -3824,16 +3872,16 @@ var TARGETS = {
3824
3872
  agents: { relPath: "AGENTS.md", mode: "block", detect: "AGENTS.md" }
3825
3873
  };
3826
3874
  function detectRuntimes(workspaceRoot) {
3827
- const found = MEMORY_RUNTIMES.filter((rt) => existsSync2(join8(workspaceRoot, TARGETS[rt].detect)));
3875
+ const found = MEMORY_RUNTIMES.filter((rt) => existsSync3(join9(workspaceRoot, TARGETS[rt].detect)));
3828
3876
  return found.length > 0 ? found : ["agents"];
3829
3877
  }
3830
3878
  function existingRuntimes(workspaceRoot) {
3831
- return MEMORY_RUNTIMES.filter((rt) => existsSync2(join8(workspaceRoot, TARGETS[rt].detect)));
3879
+ return MEMORY_RUNTIMES.filter((rt) => existsSync3(join9(workspaceRoot, TARGETS[rt].detect)));
3832
3880
  }
3833
3881
  function installedRuntimes(workspaceRoot) {
3834
3882
  return MEMORY_RUNTIMES.filter((rt) => {
3835
- const p = join8(workspaceRoot, TARGETS[rt].relPath);
3836
- if (!existsSync2(p))
3883
+ const p = join9(workspaceRoot, TARGETS[rt].relPath);
3884
+ if (!existsSync3(p))
3837
3885
  return false;
3838
3886
  try {
3839
3887
  return readFileSync4(p, "utf-8").includes(BLOCK_START);
@@ -3861,14 +3909,14 @@ function upsertBlock(existing, block) {
3861
3909
  }
3862
3910
  async function installRuntime(workspaceRoot, runtime) {
3863
3911
  const target = TARGETS[runtime];
3864
- const absPath = join8(workspaceRoot, target.relPath);
3865
- const exists = existsSync2(absPath);
3912
+ const absPath = join9(workspaceRoot, target.relPath);
3913
+ const exists = existsSync3(absPath);
3866
3914
  const before = exists ? await readFile3(absPath, "utf-8") : "";
3867
3915
  const after = target.mode === "file" ? target.fileContent : upsertBlock(before, RULE_BLOCK);
3868
3916
  if (exists && before === after) {
3869
3917
  return { runtime, path: absPath, action: "unchanged" };
3870
3918
  }
3871
- await mkdir3(dirname4(absPath), { recursive: true });
3919
+ await mkdir3(dirname5(absPath), { recursive: true });
3872
3920
  await writeFile3(absPath, after, "utf-8");
3873
3921
  return { runtime, path: absPath, action: exists ? "updated" : "created" };
3874
3922
  }
@@ -4389,7 +4437,7 @@ ${f.value}`);
4389
4437
  embeddingsError = err instanceof Error ? err.message : String(err);
4390
4438
  }
4391
4439
  }
4392
- const update = await buildUpdateStatus("@prom.codes/memory-mcp", "0.14.0", { isDevBuild: false });
4440
+ const update = await buildUpdateStatus("@prom.codes/memory-mcp", "0.15.0", { isDevBuild: false });
4393
4441
  let recorder;
4394
4442
  try {
4395
4443
  const scopes = ["project-local", "project", "user"];
@@ -4471,7 +4519,7 @@ ${f.value}`);
4471
4519
  // dist/server.js
4472
4520
  var SERVER_IDENTITY = {
4473
4521
  name: "prometheus-memory-mcp",
4474
- version: "0.14.0",
4522
+ version: "0.15.0",
4475
4523
  title: "prom.codes Memory"
4476
4524
  };
4477
4525
  var SERVER_INSTRUCTIONS = "Persistent agent memory for this workspace \u2014 USE IT PROACTIVELY; the user will not tell you to. Protocol:\n1. ONE-TIME: if this workspace has no Prometheus memory rule yet, call memory_setup now (idempotent) so the protocol is installed into the runtime rule files and survives future sessions. (The server also auto-installs it on startup when a project rule file already exists \u2014 memory_setup covers the rest.)\n2. SESSION START: before any non-trivial task, call memory_read to recall facts, decisions and procedures from earlier sessions.\n3. DURING WORK: when the user states a durable preference, decision, correction or project fact, store it with memory_write (semantic for facts, procedural for how-tos) \u2014 without being asked.\n4. LOOK-UP: use memory_search for keyword recall when memory_read is not specific enough.\n5. SESSION END: consolidate what was learned with memory_capture.\nCall memory_status anytime to check what is stored and whether the rule is installed. Never store secrets, API keys or credentials \u2014 such writes are rejected.";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prom.codes/memory-mcp",
3
- "version": "0.14.0",
3
+ "version": "0.15.0",
4
4
  "description": "prom.codes Memory — persistent, local-first agent memory as an MCP server.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -10,7 +10,7 @@
10
10
  "dist"
11
11
  ],
12
12
  "engines": {
13
- "node": ">=20.10"
13
+ "node": ">=22"
14
14
  },
15
15
  "license": "UNLICENSED",
16
16
  "homepage": "https://prom.codes",
@@ -28,5 +28,15 @@
28
28
  "@modelcontextprotocol/sdk": "^1.29.0",
29
29
  "better-sqlite3": "^12.10.0",
30
30
  "zod": "^4.4.3"
31
+ },
32
+ "optionalDependencies": {
33
+ "@prom.codes/native-darwin-arm64": "0.19.0",
34
+ "@prom.codes/native-darwin-x64": "0.19.0",
35
+ "@prom.codes/native-linux-arm64": "0.19.0",
36
+ "@prom.codes/native-linux-x64": "0.19.0",
37
+ "@prom.codes/native-linuxmusl-arm64": "0.19.0",
38
+ "@prom.codes/native-linuxmusl-x64": "0.19.0",
39
+ "@prom.codes/native-win32-arm64": "0.19.0",
40
+ "@prom.codes/native-win32-x64": "0.19.0"
31
41
  }
32
42
  }