@hasna/mementos 0.4.31 → 0.4.33

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/mcp/index.js CHANGED
@@ -6368,6 +6368,42 @@ server.tool("memory_forget", "Delete a memory by ID or key", {
6368
6368
  return { content: [{ type: "text", text: formatError(e) }], isError: true };
6369
6369
  }
6370
6370
  });
6371
+ server.tool("memory_stale", "Find memories not accessed recently. Useful for cleanup or review.", {
6372
+ days: exports_external.coerce.number().optional(),
6373
+ project_id: exports_external.string().optional(),
6374
+ agent_id: exports_external.string().optional(),
6375
+ limit: exports_external.coerce.number().optional()
6376
+ }, async (args) => {
6377
+ try {
6378
+ const days = args.days || 30;
6379
+ const db = getDatabase();
6380
+ const conditions = [
6381
+ "status = 'active'",
6382
+ `(accessed_at IS NULL OR accessed_at < datetime('now', '-${days} days'))`,
6383
+ "pinned = 0"
6384
+ ];
6385
+ const params = [];
6386
+ if (args.project_id) {
6387
+ conditions.push("project_id = ?");
6388
+ params.push(args.project_id);
6389
+ }
6390
+ if (args.agent_id) {
6391
+ conditions.push("agent_id = ?");
6392
+ params.push(args.agent_id);
6393
+ }
6394
+ const limit = args.limit || 20;
6395
+ const rows = db.query(`SELECT id, key, value, importance, scope, category, accessed_at, access_count FROM memories WHERE ${conditions.join(" AND ")} ORDER BY COALESCE(accessed_at, created_at) ASC LIMIT ?`).all(...params, limit);
6396
+ if (rows.length === 0) {
6397
+ return { content: [{ type: "text", text: `No stale memories found (last accessed > ${days} days ago).` }] };
6398
+ }
6399
+ const lines = rows.map((m) => `[${m.importance}] ${m.key} (${m.scope}/${m.category}) \u2014 last accessed: ${m.accessed_at?.slice(0, 10) || "never"}, ${m.access_count} reads`);
6400
+ return { content: [{ type: "text", text: `${rows.length} stale memor${rows.length === 1 ? "y" : "ies"} (not accessed in ${days}+ days):
6401
+ ${lines.join(`
6402
+ `)}` }] };
6403
+ } catch (e) {
6404
+ return { content: [{ type: "text", text: formatError(e) }], isError: true };
6405
+ }
6406
+ });
6371
6407
  server.tool("memory_search", "Search memories by keyword across key, value, summary, and tags", {
6372
6408
  query: exports_external.string(),
6373
6409
  scope: exports_external.enum(["global", "shared", "private"]).optional(),
@@ -6375,6 +6411,7 @@ server.tool("memory_search", "Search memories by keyword across key, value, summ
6375
6411
  tags: exports_external.array(exports_external.string()).optional(),
6376
6412
  agent_id: exports_external.string().optional(),
6377
6413
  project_id: exports_external.string().optional(),
6414
+ session_id: exports_external.string().optional(),
6378
6415
  limit: exports_external.coerce.number().optional()
6379
6416
  }, async (args) => {
6380
6417
  try {
@@ -6384,6 +6421,7 @@ server.tool("memory_search", "Search memories by keyword across key, value, summ
6384
6421
  tags: args.tags,
6385
6422
  agent_id: args.agent_id,
6386
6423
  project_id: args.project_id,
6424
+ session_id: args.session_id,
6387
6425
  search: args.query,
6388
6426
  limit: args.limit || 20
6389
6427
  };
@@ -7349,6 +7387,17 @@ var FULL_SCHEMAS = {
7349
7387
  },
7350
7388
  example: '{"key":"old-preference","scope":"global"}'
7351
7389
  },
7390
+ memory_stale: {
7391
+ description: "Find memories not accessed recently \u2014 useful for cleanup review (same pattern as get_stale_tasks in todos).",
7392
+ category: "memory",
7393
+ params: {
7394
+ days: { type: "number", description: "Stale threshold in days (default 30)" },
7395
+ project_id: { type: "string", description: "Filter by project" },
7396
+ agent_id: { type: "string", description: "Filter by agent" },
7397
+ limit: { type: "number", description: "Max results (default 20)" }
7398
+ },
7399
+ example: '{"days":14,"project_id":"proj-uuid"}'
7400
+ },
7352
7401
  memory_search: {
7353
7402
  description: "Full-text search across key, value, summary, and tags.",
7354
7403
  category: "memory",
@@ -7359,6 +7408,7 @@ var FULL_SCHEMAS = {
7359
7408
  tags: { type: "array", description: "Tag filter", items: { type: "string" } },
7360
7409
  agent_id: { type: "string", description: "Agent UUID filter" },
7361
7410
  project_id: { type: "string", description: "Project UUID filter" },
7411
+ session_id: { type: "string", description: "Session ID filter" },
7362
7412
  limit: { type: "number", description: "Max results (default 20)" }
7363
7413
  },
7364
7414
  example: '{"query":"typescript","scope":"global","limit":10}'
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":";AACA;;;GAGG;AA2qCH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CA6H9C"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":";AACA;;;GAGG;AAosCH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CA6H9C"}
@@ -2293,6 +2293,30 @@ addRoute("GET", "/api/activity", (_req, url) => {
2293
2293
  `).all(...params);
2294
2294
  return json({ activity: rows, days, total: rows.reduce((s, r) => s + r.memories_created, 0) });
2295
2295
  });
2296
+ addRoute("GET", "/api/memories/stale", (_req, url) => {
2297
+ const q = getSearchParams(url);
2298
+ const days = Math.min(parseInt(q["days"] || "30", 10), 365);
2299
+ const projectId = q["project_id"];
2300
+ const agentId = q["agent_id"];
2301
+ const limit = Math.min(parseInt(q["limit"] || "20", 10), 100);
2302
+ const db = getDatabase();
2303
+ const conds = [
2304
+ "status = 'active'",
2305
+ `(accessed_at IS NULL OR accessed_at < datetime('now', '-${days} days'))`,
2306
+ "pinned = 0"
2307
+ ];
2308
+ const params = [];
2309
+ if (projectId) {
2310
+ conds.push("project_id = ?");
2311
+ params.push(projectId);
2312
+ }
2313
+ if (agentId) {
2314
+ conds.push("agent_id = ?");
2315
+ params.push(agentId);
2316
+ }
2317
+ const rows = db.query(`SELECT id, key, value, importance, scope, category, accessed_at, access_count, created_at FROM memories WHERE ${conds.join(" AND ")} ORDER BY COALESCE(accessed_at, created_at) ASC LIMIT ?`).all(...params, limit);
2318
+ return json({ memories: rows, count: rows.length, days });
2319
+ });
2296
2320
  addRoute("GET", "/api/report", (_req, url) => {
2297
2321
  const q = getSearchParams(url);
2298
2322
  const days = Math.min(parseInt(q["days"] || "7", 10), 365);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/mementos",
3
- "version": "0.4.31",
3
+ "version": "0.4.33",
4
4
  "description": "Universal memory system for AI agents - CLI + MCP server + library API",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",