@hasna/mementos 0.14.69 → 0.14.70

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/cli/index.js CHANGED
@@ -2099,6 +2099,27 @@ var require_commander = __commonJS((exports) => {
2099
2099
  exports.InvalidOptionArgumentError = InvalidArgumentError;
2100
2100
  });
2101
2101
 
2102
+ // src/generated/storage-kit/mode.ts
2103
+ function normalizeStorageMode(value) {
2104
+ const normalized = value.trim().toLowerCase().replace(/-/g, "_");
2105
+ if (normalized === "local")
2106
+ return { mode: "local", deprecatedAlias: null };
2107
+ if (normalized === "cloud")
2108
+ return { mode: "cloud", deprecatedAlias: null };
2109
+ if (DEPRECATED_STORAGE_MODE_ALIASES.includes(normalized)) {
2110
+ return { mode: "cloud", deprecatedAlias: normalized };
2111
+ }
2112
+ throw new Error(`Unknown storage mode: ${value}. Use local or cloud.`);
2113
+ }
2114
+ var DEPRECATED_STORAGE_MODE_ALIASES;
2115
+ var init_mode = __esm(() => {
2116
+ DEPRECATED_STORAGE_MODE_ALIASES = [
2117
+ "remote",
2118
+ "hybrid",
2119
+ "self_hosted"
2120
+ ];
2121
+ });
2122
+
2102
2123
  // src/storage.ts
2103
2124
  import { Database } from "bun:sqlite";
2104
2125
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
@@ -2357,18 +2378,20 @@ function warnDeprecatedStorageMode(alias) {
2357
2378
  warnedDeprecatedModes.add(alias);
2358
2379
  process.emitWarning(`${MEMENTOS_STORAGE_ENV.mode}="${alias}" is deprecated; use "cloud". ` + `"${alias}" now maps to pure-remote cloud storage. The local<->remote ` + `sync path is deprecated and is not the fleet cutover path.`, { type: "DeprecationWarning", code: "MEMENTOS_STORAGE_MODE_ALIAS" });
2359
2380
  }
2360
- function normalizeStorageMode(value) {
2361
- if (!value)
2381
+ function normalizeStorageMode2(value, source) {
2382
+ if (!value || !value.trim())
2362
2383
  return null;
2363
- const normalized = value.trim().toLowerCase();
2364
- if (normalized === "local" || normalized === "cloud") {
2365
- return normalized;
2384
+ let normalized;
2385
+ try {
2386
+ normalized = normalizeStorageMode(value);
2387
+ } catch (error) {
2388
+ const detail = error instanceof Error ? error.message : String(error);
2389
+ throw new Error(`mementos: ${source}=${value} is not a valid mode. ${detail}`);
2366
2390
  }
2367
- if (normalized === "remote" || normalized === "hybrid") {
2368
- warnDeprecatedStorageMode(normalized);
2369
- return "cloud";
2391
+ if (normalized.deprecatedAlias) {
2392
+ warnDeprecatedStorageMode(normalized.deprecatedAlias);
2370
2393
  }
2371
- return null;
2394
+ return normalized.mode;
2372
2395
  }
2373
2396
  function readConfigFile() {
2374
2397
  if (!existsSync(STORAGE_CONFIG_PATH)) {
@@ -2398,7 +2421,7 @@ function getStorageDatabaseUrl() {
2398
2421
  }
2399
2422
  function getStorageModeOverride() {
2400
2423
  for (const env of MODE_ENV_NAMES) {
2401
- const value = normalizeStorageMode(readEnv(env.name) ?? undefined);
2424
+ const value = normalizeStorageMode2(readEnv(env.name) ?? undefined, env.name);
2402
2425
  if (value)
2403
2426
  return value;
2404
2427
  }
@@ -2408,7 +2431,7 @@ function getStorageConfig() {
2408
2431
  const fileConfig = readConfigFile();
2409
2432
  const modeOverride = getStorageModeOverride();
2410
2433
  const envConnectionString = getConfiguredConnectionString();
2411
- const fileMode = normalizeStorageMode(fileConfig.mode);
2434
+ const fileMode = normalizeStorageMode2(fileConfig.mode, `${STORAGE_CONFIG_PATH} "mode"`);
2412
2435
  const merged = {
2413
2436
  ...DEFAULT_STORAGE_CONFIG,
2414
2437
  ...fileConfig,
@@ -2819,6 +2842,7 @@ CREATE TABLE IF NOT EXISTS _sync_meta (
2819
2842
  direction TEXT DEFAULT 'push'
2820
2843
  )`;
2821
2844
  var init_storage = __esm(() => {
2845
+ init_mode();
2822
2846
  PgSyncPool = class PgSyncPool {
2823
2847
  worker;
2824
2848
  status;
@@ -3177,7 +3201,24 @@ var init_api_mode = __esm(() => {
3177
3201
  });
3178
3202
 
3179
3203
  // src/db/migrations.ts
3180
- var MIGRATIONS;
3204
+ var MEMORY_VERSION_SNAPSHOT_TRIGGER = `
3205
+ CREATE TRIGGER IF NOT EXISTS memories_version_snapshot
3206
+ BEFORE UPDATE ON memories
3207
+ WHEN NEW.version > OLD.version
3208
+ BEGIN
3209
+ INSERT OR IGNORE INTO memory_versions (
3210
+ id, memory_id, version, value, importance, scope, category, tags,
3211
+ summary, pinned, status, when_to_use, created_at
3212
+ ) VALUES (
3213
+ lower(hex(randomblob(4))) || '-' || lower(hex(randomblob(2))) || '-' ||
3214
+ lower(hex(randomblob(2))) || '-' || lower(hex(randomblob(2))) || '-' ||
3215
+ lower(hex(randomblob(6))),
3216
+ OLD.id, OLD.version, OLD.value, OLD.importance, OLD.scope, OLD.category,
3217
+ OLD.tags, OLD.summary, OLD.pinned, OLD.status, OLD.when_to_use,
3218
+ OLD.updated_at
3219
+ );
3220
+ END;
3221
+ `, MIGRATIONS;
3181
3222
  var init_migrations = __esm(() => {
3182
3223
  MIGRATIONS = [
3183
3224
  `
@@ -4075,6 +4116,10 @@ CREATE INDEX IF NOT EXISTS idx_memory_reflection_lessons_memory ON memory_reflec
4075
4116
  CREATE INDEX IF NOT EXISTS idx_memory_reflection_lessons_kind ON memory_reflection_lessons(kind);
4076
4117
 
4077
4118
  INSERT OR IGNORE INTO _migrations (id) VALUES (35);
4119
+ `,
4120
+ `
4121
+ ${MEMORY_VERSION_SNAPSHOT_TRIGGER}
4122
+ INSERT OR IGNORE INTO _migrations (id) VALUES (36);
4078
4123
  `
4079
4124
  ];
4080
4125
  });
@@ -4089,6 +4134,7 @@ __export(exports_database, {
4089
4134
  now: () => now,
4090
4135
  getDbPath: () => getDbPath,
4091
4136
  getDatabase: () => getDatabase,
4137
+ escapeLikePrefix: () => escapeLikePrefix,
4092
4138
  closeDatabase: () => closeDatabase
4093
4139
  });
4094
4140
  import { existsSync as existsSync2, mkdirSync as mkdirSync2, cpSync } from "fs";
@@ -4263,15 +4309,20 @@ function uuid() {
4263
4309
  function shortUuid() {
4264
4310
  return crypto.randomUUID().slice(0, 8);
4265
4311
  }
4312
+ function escapeLikePrefix(s) {
4313
+ return s.replace(/\\/g, "\\\\").replace(/%/g, "\\%").replace(/_/g, "\\_");
4314
+ }
4266
4315
  function resolvePartialId(db, table, partialId) {
4267
4316
  if (!ALLOWED_TABLES.has(table)) {
4268
4317
  throw new Error(`Invalid table name: ${table}`);
4269
4318
  }
4319
+ if (partialId === "")
4320
+ return null;
4270
4321
  if (partialId.length >= 36) {
4271
4322
  const row = db.query(`SELECT id FROM ${table} WHERE id = ?`).get(partialId);
4272
4323
  return row?.id ?? null;
4273
4324
  }
4274
- const rows = db.query(`SELECT id FROM ${table} WHERE id LIKE ?`).all(`${partialId}%`);
4325
+ const rows = db.query(`SELECT id FROM ${table} WHERE id LIKE ? ESCAPE '\\'`).all(`${escapeLikePrefix(partialId)}%`);
4275
4326
  if (rows.length === 1) {
4276
4327
  return rows[0].id;
4277
4328
  }
@@ -5378,33 +5429,19 @@ function updateMemory(id, input, db) {
5378
5429
  const { status, data } = apiJson("PATCH", `/memories/${encodeURIComponent(id)}`, input, { allow404: true });
5379
5430
  if (status === 404)
5380
5431
  throw new MemoryNotFoundError(id);
5432
+ if (data && typeof input.version === "number" && typeof data.version === "number" && data.version <= input.version) {
5433
+ throw new Error(`Update did not persist for memory ${id}: the server returned success but the record is unchanged ` + `(version still ${data.version}). Your data was NOT written. ` + `The server is likely running a build predating the partial-id fix \u2014 pass the full 36-character id as a workaround.`);
5434
+ }
5381
5435
  return data;
5382
5436
  }
5383
5437
  const d = db || getDatabase();
5384
5438
  const existing = getMemory(id, d);
5385
5439
  if (!existing)
5386
5440
  throw new MemoryNotFoundError(id);
5441
+ const memoryId = existing.id;
5387
5442
  if (existing.version !== input.version) {
5388
5443
  throw new VersionConflictError(id, input.version, existing.version);
5389
5444
  }
5390
- try {
5391
- d.run(`INSERT OR IGNORE INTO memory_versions (id, memory_id, version, value, importance, scope, category, tags, summary, pinned, status, when_to_use, created_at)
5392
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
5393
- uuid(),
5394
- existing.id,
5395
- existing.version,
5396
- existing.value,
5397
- existing.importance,
5398
- existing.scope,
5399
- existing.category,
5400
- JSON.stringify(existing.tags),
5401
- existing.summary,
5402
- existing.pinned ? 1 : 0,
5403
- existing.status,
5404
- existing.when_to_use || null,
5405
- existing.updated_at
5406
- ]);
5407
- } catch {}
5408
5445
  const sets = ["version = version + 1", "updated_at = ?"];
5409
5446
  const params = [now()];
5410
5447
  if (input.value !== undefined) {
@@ -5454,15 +5491,18 @@ function updateMemory(id, input, db) {
5454
5491
  if (input.tags !== undefined) {
5455
5492
  sets.push("tags = ?");
5456
5493
  params.push(JSON.stringify(input.tags));
5457
- d.run("DELETE FROM memory_tags WHERE memory_id = ?", [id]);
5494
+ d.run("DELETE FROM memory_tags WHERE memory_id = ?", [memoryId]);
5458
5495
  const insertTag = d.prepare("INSERT OR IGNORE INTO memory_tags (memory_id, tag) VALUES (?, ?)");
5459
5496
  for (const tag of input.tags) {
5460
- insertTag.run(id, tag);
5497
+ insertTag.run(memoryId, tag);
5461
5498
  }
5462
5499
  }
5463
- params.push(id);
5464
- d.run(`UPDATE memories SET ${sets.join(", ")} WHERE id = ?`, params);
5465
- const updated = getMemory(id, d);
5500
+ params.push(memoryId);
5501
+ const result = d.run(`UPDATE memories SET ${sets.join(", ")} WHERE id = ?`, params);
5502
+ if (result.changes === 0) {
5503
+ throw new Error(`Update affected no rows for memory ${memoryId}: the record was read but not written. ` + `This is a bug in @hasna/mementos, not a bad argument \u2014 please report it.`);
5504
+ }
5505
+ const updated = getMemory(memoryId, d);
5466
5506
  if (input.value !== undefined) {
5467
5507
  try {
5468
5508
  const oldLinks = getEntityMemoryLinks(undefined, updated.id, d);
@@ -5487,10 +5527,11 @@ function deleteMemory(id, db) {
5487
5527
  return status !== 404;
5488
5528
  }
5489
5529
  const d = db || getDatabase();
5490
- const result = d.run("DELETE FROM memories WHERE id = ?", [id]);
5530
+ const memoryId = resolvePartialId(d, "memories", id) ?? id;
5531
+ const result = d.run("DELETE FROM memories WHERE id = ?", [memoryId]);
5491
5532
  if (result.changes > 0) {
5492
5533
  hookRegistry.runHooks("PostMemoryDelete", {
5493
- memoryId: id,
5534
+ memoryId,
5494
5535
  timestamp: Date.now()
5495
5536
  });
5496
5537
  }
@@ -5504,11 +5545,12 @@ function bulkDeleteMemories(ids, db) {
5504
5545
  return data?.deleted ?? 0;
5505
5546
  }
5506
5547
  const d = db || getDatabase();
5507
- const placeholders = ids.map(() => "?").join(",");
5508
- const countRow = d.query(`SELECT COUNT(*) as c FROM memories WHERE id IN (${placeholders})`).get(...ids);
5548
+ const resolvedIds = ids.map((id) => resolvePartialId(d, "memories", id) ?? id);
5549
+ const placeholders = resolvedIds.map(() => "?").join(",");
5550
+ const countRow = d.query(`SELECT COUNT(*) as c FROM memories WHERE id IN (${placeholders})`).get(...resolvedIds);
5509
5551
  const count = countRow.c;
5510
5552
  if (count > 0) {
5511
- d.run(`DELETE FROM memories WHERE id IN (${placeholders})`, ids);
5553
+ d.run(`DELETE FROM memories WHERE id IN (${placeholders})`, resolvedIds);
5512
5554
  }
5513
5555
  return count;
5514
5556
  }
@@ -6639,7 +6681,7 @@ function getAgent(idOrName, db) {
6639
6681
  row = d.query("SELECT * FROM agents WHERE LOWER(name) = ?").get(idOrName.trim().toLowerCase());
6640
6682
  if (row)
6641
6683
  return parseAgentRow(row);
6642
- const rows = d.query("SELECT * FROM agents WHERE id LIKE ?").all(`${idOrName}%`);
6684
+ const rows = d.query("SELECT * FROM agents WHERE id LIKE ? ESCAPE '\\'").all(`${escapeLikePrefix(idOrName)}%`);
6643
6685
  if (rows.length === 1)
6644
6686
  return parseAgentRow(rows[0]);
6645
6687
  return null;
@@ -8233,6 +8275,32 @@ class AutoMemoryQueue {
8233
8275
  getStats() {
8234
8276
  return { ...this.stats, pending: this.queue.length };
8235
8277
  }
8278
+ async waitForIdleForTests(timeoutMs = 3000) {
8279
+ const start = Date.now();
8280
+ while (Date.now() - start < timeoutMs) {
8281
+ if (this.queue.length === 0 && this.activeCount === 0)
8282
+ return;
8283
+ await new Promise((r) => setTimeout(r, 20));
8284
+ }
8285
+ throw new Error("autoMemoryQueue did not become idle before test reset");
8286
+ }
8287
+ resetForTests(handler) {
8288
+ if (this.activeCount !== 0) {
8289
+ throw new Error("Cannot reset autoMemoryQueue while jobs are processing");
8290
+ }
8291
+ this.queue = [];
8292
+ this.running = false;
8293
+ this.stats = {
8294
+ pending: 0,
8295
+ processing: 0,
8296
+ processed: 0,
8297
+ failed: 0,
8298
+ dropped: 0
8299
+ };
8300
+ if (handler !== undefined) {
8301
+ this.handler = handler;
8302
+ }
8303
+ }
8236
8304
  startLoop() {
8237
8305
  this.running = true;
8238
8306
  this.loop();
@@ -8278,6 +8346,7 @@ var init_auto_memory_queue = __esm(() => {
8278
8346
  // src/lib/auto-memory.ts
8279
8347
  var exports_auto_memory = {};
8280
8348
  __export(exports_auto_memory, {
8349
+ resetAutoMemoryForTests: () => resetAutoMemoryForTests,
8281
8350
  processConversationTurn: () => processConversationTurn,
8282
8351
  getAutoMemoryStats: () => getAutoMemoryStats,
8283
8352
  configureAutoMemory: () => configureAutoMemory
@@ -8438,6 +8507,12 @@ function getAutoMemoryStats() {
8438
8507
  function configureAutoMemory(config) {
8439
8508
  providerRegistry.configure(config);
8440
8509
  }
8510
+ async function resetAutoMemoryForTests() {
8511
+ if (autoMemoryQueue.getStats().processing > 0) {
8512
+ await autoMemoryQueue.waitForIdleForTests();
8513
+ }
8514
+ autoMemoryQueue.resetForTests(processJob);
8515
+ }
8441
8516
  var DEDUP_SIMILARITY_THRESHOLD = 0.85;
8442
8517
  var init_auto_memory = __esm(() => {
8443
8518
  init_memories();
@@ -9275,6 +9350,8 @@ var init_built_in_hooks = __esm(() => {
9275
9350
  priority: 100,
9276
9351
  description: "Trigger async LLM entity extraction when a memory is saved",
9277
9352
  handler: async (ctx) => {
9353
+ if (process.env["NODE_ENV"] === "test")
9354
+ return;
9278
9355
  if (ctx.wasUpdated)
9279
9356
  return;
9280
9357
  const processConversationTurn2 = await getAutoMemory();
@@ -12098,6 +12175,31 @@ var init_pg_migrations = __esm(() => {
12098
12175
  );
12099
12176
  CREATE INDEX IF NOT EXISTS idx_task_comments_task ON task_comments(task_id);
12100
12177
  CREATE INDEX IF NOT EXISTS idx_task_comments_agent ON task_comments(agent_id);
12178
+ `,
12179
+ `
12180
+ CREATE OR REPLACE FUNCTION snapshot_memory_version() RETURNS trigger AS $$
12181
+ BEGIN
12182
+ INSERT INTO memory_versions (
12183
+ id, memory_id, version, value, importance, scope, category, tags,
12184
+ summary, pinned, status, when_to_use, created_at
12185
+ ) VALUES (
12186
+ gen_random_uuid()::text,
12187
+ OLD.id, OLD.version, OLD.value, OLD.importance, OLD.scope, OLD.category,
12188
+ OLD.tags, OLD.summary, OLD.pinned, OLD.status, OLD.when_to_use,
12189
+ OLD.updated_at
12190
+ ) ON CONFLICT DO NOTHING;
12191
+ RETURN NEW;
12192
+ END;
12193
+ $$ LANGUAGE plpgsql;
12194
+
12195
+ DROP TRIGGER IF EXISTS memories_version_snapshot ON memories;
12196
+ CREATE TRIGGER memories_version_snapshot
12197
+ BEFORE UPDATE ON memories
12198
+ FOR EACH ROW
12199
+ WHEN (NEW.version > OLD.version)
12200
+ EXECUTE FUNCTION snapshot_memory_version();
12201
+
12202
+ INSERT INTO _migrations (id) VALUES (36) ON CONFLICT DO NOTHING;
12101
12203
  `
12102
12204
  ];
12103
12205
  });
@@ -60042,7 +60144,7 @@ import chalk4 from "chalk";
60042
60144
  import { resolve as resolve4 } from "path";
60043
60145
  function registerTailCommand(program2) {
60044
60146
  const handleError = makeHandleError(program2);
60045
- program2.command("tail").description("Watch for new/updated memories in real-time (like tail -f)").option("--scope <scope>", "Scope filter: global, shared, private").option("-c, --category <cat>", "Category filter: preference, fact, knowledge, history").option("--agent <name>", "Agent filter").option("--project <path>", "Project filter").option("--interval <ms>", "Poll interval in milliseconds (default: 2000)", parseInt).option("--notify", "Send macOS notifications for each change").action((opts) => {
60147
+ program2.command("tail").description("Watch for new/updated memories in real-time (like tail -f)").option("--scope <scope>", "Scope filter: global, shared, private, working").option("-c, --category <cat>", "Category filter: preference, fact, knowledge, history, procedural, resource").option("--agent <name>", "Agent filter").option("--project <path>", "Project filter").option("--interval <ms>", "Poll interval in milliseconds (default: 2000)", parseInt).option("--notify", "Send macOS notifications for each change").action((opts) => {
60046
60148
  try {
60047
60149
  const globalOpts = program2.opts();
60048
60150
  const jsonMode = !!globalOpts.json;
@@ -63013,12 +63115,12 @@ function registerDoctorCommand(program2) {
63013
63115
  const activeProfile = getActiveProfile();
63014
63116
  const profiles = listProfiles();
63015
63117
  if (activeProfile) {
63016
- checks.push({ name: "Active profile", status: "ok", detail: `${activeProfile} (${profiles.length} total)` });
63118
+ checks.push({ name: "Profile metadata", status: "ok", detail: `${activeProfile} active (${profiles.length} total); verify runtime DB with storage mode` });
63017
63119
  } else {
63018
- checks.push({ name: "Active profile", status: "ok", detail: `default (~/.hasna/mementos/mementos.db) \u2014 ${profiles.length} profile(s) available` });
63120
+ checks.push({ name: "Profile metadata", status: "ok", detail: `none active \u2014 ${profiles.length} profile(s) available; verify runtime DB with storage mode` });
63019
63121
  }
63020
63122
  } catch (e) {
63021
- checks.push({ name: "Active profile", status: "warn", detail: e instanceof Error ? e.message : String(e) });
63123
+ checks.push({ name: "Profile metadata", status: "warn", detail: e instanceof Error ? e.message : String(e) });
63022
63124
  }
63023
63125
  try {
63024
63126
  const mementosUrl = process.env["MEMENTOS_URL"] || `http://127.0.0.1:19428`;
@@ -63327,7 +63429,7 @@ function registerConfigCommand(program2) {
63327
63429
  import chalk29 from "chalk";
63328
63430
  init_helpers();
63329
63431
  function registerProfileCommand(program2) {
63330
- const profileCmd = program2.command("profile").description("Manage memory profiles (isolated DBs per context)");
63432
+ const profileCmd = program2.command("profile").description("Manage named profile files and active-profile metadata");
63331
63433
  profileCmd.command("list").description("List all available profiles").action(() => {
63332
63434
  const globalOpts = program2.opts();
63333
63435
  const profiles = listProfiles();
@@ -63347,7 +63449,7 @@ function registerProfileCommand(program2) {
63347
63449
  }
63348
63450
  if (!active) {
63349
63451
  console.log(chalk29.dim(`
63350
- (no active profile \u2014 using default DB)`));
63452
+ (no active-profile metadata set)`));
63351
63453
  }
63352
63454
  });
63353
63455
  profileCmd.command("get").description("Show the currently active profile").action(() => {
@@ -63360,20 +63462,21 @@ function registerProfileCommand(program2) {
63360
63462
  console.log(chalk29.dim("(from MEMENTOS_PROFILE env var)"));
63361
63463
  }
63362
63464
  } else {
63363
- console.log(chalk29.dim("No active profile \u2014 using default DB (~/.hasna/mementos/mementos.db)"));
63465
+ console.log(chalk29.dim("No active-profile metadata set."));
63364
63466
  }
63365
63467
  });
63366
- profileCmd.command("set <name>").description("Switch to a named profile (creates the DB on first use)").action((name) => {
63468
+ profileCmd.command("set <name>").description("Set the active-profile metadata").action((name) => {
63367
63469
  const clean = name.trim().toLowerCase().replace(/[^a-z0-9_-]/g, "-");
63368
63470
  if (!clean) {
63369
63471
  console.error(chalk29.red("Invalid profile name. Use letters, numbers, hyphens, underscores."));
63370
63472
  process.exit(1);
63371
63473
  }
63372
63474
  setActiveProfile(clean);
63373
- console.log(chalk29.green(`\u2713 Switched to profile: ${clean}`));
63374
- console.log(chalk29.dim(` DB: ~/.hasna/mementos/profiles/${clean}.db (created on first use)`));
63475
+ console.log(chalk29.green(`\u2713 Active-profile metadata set: ${clean}`));
63476
+ console.log(chalk29.dim(` Profile file: ~/.hasna/mementos/profiles/${clean}.db`));
63477
+ console.log(chalk29.dim(" Run `mementos storage mode` to verify the live runtime database."));
63375
63478
  });
63376
- profileCmd.command("unset").description("Clear the active profile (revert to default DB)").action(() => {
63479
+ profileCmd.command("unset").description("Clear the active-profile metadata").action(() => {
63377
63480
  const was = getActiveProfile();
63378
63481
  setActiveProfile(null);
63379
63482
  if (was) {
@@ -63381,7 +63484,7 @@ function registerProfileCommand(program2) {
63381
63484
  } else {
63382
63485
  console.log(chalk29.dim("No active profile was set."));
63383
63486
  }
63384
- console.log(chalk29.dim(" Now using default DB: ~/.hasna/mementos/mementos.db"));
63487
+ console.log(chalk29.dim(" Run `mementos storage mode` to verify the live runtime database."));
63385
63488
  });
63386
63489
  profileCmd.command("delete <name>").description("Delete a profile and its DB file (irreversible)").option("-y, --yes", "Skip confirmation prompt").action(async (name, opts) => {
63387
63490
  if (!opts.yes) {
@@ -64174,19 +64277,20 @@ function registerMiscCommands(program2) {
64174
64277
  // src/cli/commands/system-mcp.ts
64175
64278
  import chalk38 from "chalk";
64176
64279
  function registerMcpCommand(program2) {
64177
- program2.command("mcp").description("Install mementos MCP server into Claude Code, Codex, or Gemini").option("--claude", "Install into Claude Code (~/.claude/.mcp.json)").option("--codex", "Install into Codex (~/.codex/config.toml)").option("--gemini", "Install into Gemini (~/.gemini/settings.json)").option("--all", "Install into all supported agents").option("--uninstall", "Remove mementos MCP from config").action((opts) => {
64178
- const { readFileSync: _rfs, writeFileSync: _wfs, existsSync: fileExists } = __require("fs");
64280
+ program2.command("mcp").description("Install mementos MCP server into Claude Code, Codex, Cursor, or Gemini").option("--claude", "Install into Claude Code (~/.claude/.mcp.json)").option("--codex", "Install into Codex (~/.codex/config.toml)").option("--cursor", "Install into Cursor (~/.cursor/mcp.json)").option("--gemini", "Install into Gemini (~/.gemini/settings.json)").option("--all", "Install into all supported agents").option("--uninstall", "Remove mementos MCP from config").action((opts) => {
64281
+ const { readFileSync: _rfs, writeFileSync: _wfs, existsSync: fileExists, mkdirSync: makeDir } = __require("fs");
64179
64282
  const { join: pathJoin } = __require("path");
64180
64283
  const { homedir: getHome } = __require("os");
64181
64284
  const home = getHome();
64182
64285
  const mementosCmd = process.argv[0]?.includes("bun") ? pathJoin(home, ".bun", "bin", "mementos-mcp") : "mementos-mcp";
64183
- const targets = opts.all ? ["claude", "codex", "gemini"] : [
64286
+ const targets = opts.all ? ["claude", "codex", "cursor", "gemini"] : [
64184
64287
  opts.claude ? "claude" : null,
64185
64288
  opts.codex ? "codex" : null,
64289
+ opts.cursor ? "cursor" : null,
64186
64290
  opts.gemini ? "gemini" : null
64187
64291
  ].filter(Boolean);
64188
64292
  if (targets.length === 0) {
64189
- console.log(chalk38.yellow("Specify a target: --claude, --codex, --gemini, or --all"));
64293
+ console.log(chalk38.yellow("Specify a target: --claude, --codex, --cursor, --gemini, or --all"));
64190
64294
  console.log(chalk38.gray("Example: mementos mcp --all"));
64191
64295
  return;
64192
64296
  }
@@ -64232,6 +64336,28 @@ args = []
64232
64336
  console.log(chalk38.yellow(`Codex config not found: ${configPath}`));
64233
64337
  }
64234
64338
  }
64339
+ if (target === "cursor") {
64340
+ const configDir = pathJoin(home, ".cursor");
64341
+ const configPath = pathJoin(configDir, "mcp.json");
64342
+ let config = {};
64343
+ if (fileExists(configPath)) {
64344
+ config = JSON.parse(_rfs(configPath, "utf-8"));
64345
+ } else if (opts.uninstall) {
64346
+ console.log(chalk38.yellow(`mementos was not installed in Cursor: ${configPath}`));
64347
+ continue;
64348
+ }
64349
+ const servers = config["mcpServers"] || {};
64350
+ if (opts.uninstall) {
64351
+ delete servers["mementos"];
64352
+ } else {
64353
+ servers["mementos"] = { command: mementosCmd, args: [] };
64354
+ }
64355
+ config["mcpServers"] = servers;
64356
+ makeDir(configDir, { recursive: true });
64357
+ _wfs(configPath, JSON.stringify(config, null, 2) + `
64358
+ `, "utf-8");
64359
+ console.log(chalk38.green(`${opts.uninstall ? "Removed from" : "Installed into"} Cursor: ${configPath}`));
64360
+ }
64235
64361
  if (target === "gemini") {
64236
64362
  const configPath = pathJoin(home, ".gemini", "settings.json");
64237
64363
  let config = {};
@@ -64263,7 +64389,7 @@ import chalk39 from "chalk";
64263
64389
  import { resolve as resolve19 } from "path";
64264
64390
  function registerWatchCommand(program2) {
64265
64391
  const handleError = makeHandleError(program2);
64266
- program2.command("watch").description("Watch for new and changed memories in real-time").option("--scope <scope>", "Scope filter: global, shared, private").option("-c, --category <cat>", "Category filter: preference, fact, knowledge, history").option("--agent <name>", "Agent filter").option("--project <path>", "Project filter").option("--interval <ms>", "Poll interval in milliseconds", parseInt).action((opts) => {
64392
+ program2.command("watch").description("Watch for new and changed memories in real-time").option("--scope <scope>", "Scope filter: global, shared, private, working").option("-c, --category <cat>", "Category filter: preference, fact, knowledge, history, procedural, resource").option("--agent <name>", "Agent filter").option("--project <path>", "Project filter").option("--interval <ms>", "Poll interval in milliseconds", parseInt).action((opts) => {
64267
64393
  try {
64268
64394
  const globalOpts = program2.opts();
64269
64395
  const agentId = opts.agent || globalOpts.agent;
@@ -64914,7 +65040,18 @@ function printSyncResult(result) {
64914
65040
  function installStorageSubcommands(storage, program2) {
64915
65041
  withoutStartupDbAccess(storage.command("mode").description("Show which store this process will actually read and write (no DB or network access)").option("--json", "Output JSON").action((opts) => {
64916
65042
  const useJson = Boolean(opts.json || program2.opts().json);
64917
- const report = resolveStoreBackend();
65043
+ let report;
65044
+ try {
65045
+ report = resolveStoreBackend();
65046
+ } catch (error) {
65047
+ const message = error instanceof Error ? error.message : String(error);
65048
+ if (useJson)
65049
+ outputJson2(true, { ok: false, error: message });
65050
+ else
65051
+ console.error(chalk40.red(message));
65052
+ process.exitCode = 1;
65053
+ return;
65054
+ }
64918
65055
  if (useJson) {
64919
65056
  outputJson2(true, report);
64920
65057
  return;
@@ -64932,7 +65069,7 @@ function installStorageSubcommands(storage, program2) {
64932
65069
  console.log(`Local SQLite (not authoritative): ${report.db_path}`);
64933
65070
  }
64934
65071
  }));
64935
- storage.command("status").description("Show local database and remote storage sync status").option("--json", "Output JSON").action((opts) => {
65072
+ storage.command("status").description("Show local database, legacy sync, and storage runtime status").option("--json", "Output JSON").action((opts) => {
64936
65073
  const useJson = Boolean(opts.json || program2.opts().json);
64937
65074
  const status = getStorageSyncStatus();
64938
65075
  const config = getStorageConfig();
@@ -65089,7 +65226,7 @@ function installStorageSubcommands(storage, program2) {
65089
65226
  process.exitCode = 1;
65090
65227
  }
65091
65228
  });
65092
- storage.command("feedback").description("Save feedback locally").argument("<message>", "Feedback message").option("--email <email>", "Contact email").option("--category <category>", "Feedback category", "general").option("--json", "Output JSON").action((message, opts) => {
65229
+ storage.command("feedback").description("Save feedback to the selected store").argument("<message>", "Feedback message").option("--email <email>", "Contact email").option("--category <category>", "Feedback category", "general").option("--json", "Output JSON").action((message, opts) => {
65093
65230
  const useJson = Boolean(opts.json || program2.opts().json);
65094
65231
  try {
65095
65232
  const { saveFeedback: saveFeedback2 } = (init_feedback(), __toCommonJS(exports_feedback));
@@ -65116,7 +65253,7 @@ function installStorageSubcommands(storage, program2) {
65116
65253
  });
65117
65254
  }
65118
65255
  function registerStorageCommands(program2) {
65119
- const storage = program2.command("storage").description("Manage mementos local/remote storage sync");
65256
+ const storage = program2.command("storage").description("Inspect storage and manage migrations or legacy row sync");
65120
65257
  installStorageSubcommands(storage, program2);
65121
65258
  }
65122
65259
 
@@ -1 +1 @@
1
- {"version":3,"file":"fail-closed-stub-server.d.ts","sourceRoot":"","sources":["../../../src/db/__fixtures__/fail-closed-stub-server.ts"],"names":[],"mappings":"AAcA,QAAA,MAAM,MAAM,uBAiBV,CAAC"}
1
+ {"version":3,"file":"fail-closed-stub-server.d.ts","sourceRoot":"","sources":["../../../src/db/__fixtures__/fail-closed-stub-server.ts"],"names":[],"mappings":"AAkBA,QAAA,MAAM,MAAM,uBAyBV,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/db/agents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAqB/C,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,SAAS,CAAC,EAAE,MAAM,EAClB,WAAW,CAAC,EAAE,MAAM,EACpB,IAAI,CAAC,EAAE,MAAM,EACb,SAAS,CAAC,EAAE,MAAM,EAClB,EAAE,CAAC,EAAE,QAAQ,GACZ,KAAK,CA0EP;AAED,wBAAgB,QAAQ,CACtB,QAAQ,EAAE,MAAM,EAChB,EAAE,CAAC,EAAE,QAAQ,GACZ,KAAK,GAAG,IAAI,CA2Bd;AAED,wBAAgB,UAAU,CAAC,EAAE,CAAC,EAAE,QAAQ,GAAG,KAAK,EAAE,CAUjD;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,IAAI,CAahE;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,KAAK,EAAE,CAa7E;AAED,wBAAgB,WAAW,CACzB,EAAE,EAAE,MAAM,EACV,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,EACtI,EAAE,CAAC,EAAE,QAAQ,GACZ,KAAK,GAAG,IAAI,CAsDd"}
1
+ {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/db/agents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAqB/C,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,SAAS,CAAC,EAAE,MAAM,EAClB,WAAW,CAAC,EAAE,MAAM,EACpB,IAAI,CAAC,EAAE,MAAM,EACb,SAAS,CAAC,EAAE,MAAM,EAClB,EAAE,CAAC,EAAE,QAAQ,GACZ,KAAK,CA0EP;AAED,wBAAgB,QAAQ,CACtB,QAAQ,EAAE,MAAM,EAChB,EAAE,CAAC,EAAE,QAAQ,GACZ,KAAK,GAAG,IAAI,CA6Bd;AAED,wBAAgB,UAAU,CAAC,EAAE,CAAC,EAAE,QAAQ,GAAG,KAAK,EAAE,CAUjD;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,IAAI,CAahE;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,KAAK,EAAE,CAa7E;AAED,wBAAgB,WAAW,CACzB,EAAE,EAAE,MAAM,EACV,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,EACtI,EAAE,CAAC,EAAE,QAAQ,GACZ,KAAK,GAAG,IAAI,CAsDd"}
@@ -6,5 +6,21 @@ export declare function resetDatabase(): void;
6
6
  export declare function now(): string;
7
7
  export declare function uuid(): string;
8
8
  export declare function shortUuid(): string;
9
+ /**
10
+ * Escape the SQL `LIKE` metacharacters so a caller-supplied id prefix is matched
11
+ * LITERALLY rather than as a pattern.
12
+ *
13
+ * `\` is replaced FIRST, or the backslashes this function itself introduces
14
+ * would be escaped a second time and the pattern would match nothing.
15
+ *
16
+ * Escaping is the right remedy here rather than rejecting any prefix outside the
17
+ * UUID charset `[0-9a-f-]`, because the id space is not UUID-only in practice:
18
+ * `bulkUpsertMemories` writes a caller-supplied `id` verbatim and validates no
19
+ * charset, so an imported row can legitimately carry `_` or `%` in its id. A
20
+ * charset rejection would make exactly those rows unaddressable by prefix, which
21
+ * trades a wrong-row deletion for a silent inability to reach a real row.
22
+ * Escaping fixes the injection at the root while keeping every id addressable.
23
+ */
24
+ export declare function escapeLikePrefix(s: string): string;
9
25
  export declare function resolvePartialId(db: Database, table: string, partialId: string): string | null;
10
26
  //# sourceMappingURL=database.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/db/database.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,IAAI,QAAQ,EAK1B,MAAM,eAAe,CAAC;AAkDvB,wBAAgB,SAAS,IAAI,MAAM,CAoBlC;AAoDD,wBAAgB,WAAW,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,CA4DrD;AAgDD,wBAAgB,aAAa,IAAI,IAAI,CASpC;AAED,wBAAgB,aAAa,IAAI,IAAI,CAGpC;AAED,wBAAgB,GAAG,IAAI,MAAM,CAE5B;AAED,wBAAgB,IAAI,IAAI,MAAM,CAE7B;AAED,wBAAgB,SAAS,IAAI,MAAM,CAElC;AASD,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,QAAQ,EACZ,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,GAChB,MAAM,GAAG,IAAI,CAkBf"}
1
+ {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/db/database.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,IAAI,QAAQ,EAK1B,MAAM,eAAe,CAAC;AAkDvB,wBAAgB,SAAS,IAAI,MAAM,CAoBlC;AAoDD,wBAAgB,WAAW,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,CA4DrD;AAgDD,wBAAgB,aAAa,IAAI,IAAI,CASpC;AAED,wBAAgB,aAAa,IAAI,IAAI,CAGpC;AAED,wBAAgB,GAAG,IAAI,MAAM,CAE5B;AAED,wBAAgB,IAAI,IAAI,MAAM,CAE7B;AAED,wBAAgB,SAAS,IAAI,MAAM,CAElC;AASD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,QAAQ,EACZ,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,GAChB,MAAM,GAAG,IAAI,CAuBf"}
@@ -1 +1 @@
1
- {"version":3,"file":"memories.d.ts","sourceRoot":"","sources":["../../src/db/memories.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"memories.d.ts","sourceRoot":"","sources":["../../src/db/memories.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,3 @@
1
+ export declare const MEMORY_VERSION_SNAPSHOT_TRIGGER = "\nCREATE TRIGGER IF NOT EXISTS memories_version_snapshot\nBEFORE UPDATE ON memories\nWHEN NEW.version > OLD.version\nBEGIN\n INSERT OR IGNORE INTO memory_versions (\n id, memory_id, version, value, importance, scope, category, tags,\n summary, pinned, status, when_to_use, created_at\n ) VALUES (\n lower(hex(randomblob(4))) || '-' || lower(hex(randomblob(2))) || '-' ||\n lower(hex(randomblob(2))) || '-' || lower(hex(randomblob(2))) || '-' ||\n lower(hex(randomblob(6))),\n OLD.id, OLD.version, OLD.value, OLD.importance, OLD.scope, OLD.category,\n OLD.tags, OLD.summary, OLD.pinned, OLD.status, OLD.when_to_use,\n OLD.updated_at\n );\nEND;\n";
1
2
  export declare const MIGRATIONS: string[];
2
3
  //# sourceMappingURL=migrations.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../../src/db/migrations.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,UAAU,EAAE,MAAM,EA88B9B,CAAC"}
1
+ {"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../../src/db/migrations.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,+BAA+B,wqBAiB3C,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,MAAM,EAm9B9B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"pg-migrations.d.ts","sourceRoot":"","sources":["../../src/db/pg-migrations.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,eAAO,MAAM,aAAa,EAAE,MAAM,EAkwBjC,CAAC"}
1
+ {"version":3,"file":"pg-migrations.d.ts","sourceRoot":"","sources":["../../src/db/pg-migrations.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,eAAO,MAAM,aAAa,EAAE,MAAM,EA+xBjC,CAAC"}