@hasna/mementos 0.4.37 → 0.4.38

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/cli/index.js +76 -4
  2. package/package.json +1 -1
package/dist/cli/index.js CHANGED
@@ -5214,6 +5214,65 @@ mementos report \u2014 last ${days} days
5214
5214
  process.exit(1);
5215
5215
  }
5216
5216
  });
5217
+ program2.command("stale").description("Find memories not accessed recently (for cleanup/review)").option("--days <n>", "Stale threshold in days (default: 30)", parseInt).option("--project <path>", "Project filter").option("--agent <name>", "Agent filter").option("--limit <n>", "Max results (default: 20)", parseInt).option("--format <fmt>", "Output format: compact (default), json").action((opts) => {
5218
+ try {
5219
+ const globalOpts = program2.opts();
5220
+ const days = opts.days || 30;
5221
+ const limit = opts.limit || 20;
5222
+ const projectPath = opts.project || globalOpts.project;
5223
+ let projectId;
5224
+ if (projectPath) {
5225
+ const project = getProject(resolve3(projectPath));
5226
+ if (project)
5227
+ projectId = project.id;
5228
+ }
5229
+ const agentName = opts.agent || globalOpts.agent;
5230
+ let agentId;
5231
+ if (agentName) {
5232
+ const agent = getAgent(agentName);
5233
+ if (agent)
5234
+ agentId = agent.id;
5235
+ }
5236
+ const db = getDatabase();
5237
+ const conds = [
5238
+ "status = 'active'",
5239
+ `(accessed_at IS NULL OR accessed_at < datetime('now', '-${days} days'))`,
5240
+ "pinned = 0"
5241
+ ];
5242
+ const params = [];
5243
+ if (projectId) {
5244
+ conds.push("project_id = ?");
5245
+ params.push(projectId);
5246
+ }
5247
+ if (agentId) {
5248
+ conds.push("agent_id = ?");
5249
+ params.push(agentId);
5250
+ }
5251
+ const rows = db.query(`SELECT id, key, value, importance, scope, category, accessed_at, access_count FROM memories WHERE ${conds.join(" AND ")} ORDER BY COALESCE(accessed_at, created_at) ASC LIMIT ?`).all(...params, limit);
5252
+ const fmt = getOutputFormat(opts.format);
5253
+ if (fmt === "json") {
5254
+ outputJson({ memories: rows, count: rows.length, days });
5255
+ return;
5256
+ }
5257
+ if (rows.length === 0) {
5258
+ console.log(chalk.green(`No stale memories (not accessed in ${days}+ days).`));
5259
+ return;
5260
+ }
5261
+ console.log(chalk.bold(`
5262
+ Stale memories (not accessed in ${days}+ days):
5263
+ `));
5264
+ for (const m of rows) {
5265
+ const lastAccess = m.accessed_at ? m.accessed_at.slice(0, 10) : chalk.dim("never");
5266
+ console.log(` ${chalk.dim(`[${m.importance}]`)} ${chalk.bold(m.key)} ${chalk.dim(`(${m.scope}/${m.category})`)}`);
5267
+ console.log(` Last accessed: ${lastAccess} \xB7 ${m.access_count} reads \xB7 ${m.value.slice(0, 80)}${m.value.length > 80 ? "..." : ""}`);
5268
+ }
5269
+ console.log(`
5270
+ ${chalk.dim(`${rows.length} result(s). Run 'mementos archive <key>' or 'mementos forget <key>' to clean up.`)}`);
5271
+ } catch (e) {
5272
+ console.error(chalk.red(`stale failed: ${e instanceof Error ? e.message : String(e)}`));
5273
+ process.exit(1);
5274
+ }
5275
+ });
5217
5276
  program2.command("export").description("Export memories as JSON").option("-s, --scope <scope>", "Scope filter").option("-c, --category <cat>", "Category filter").option("--agent <name>", "Agent filter").option("--project <path>", "Project filter").action((opts) => {
5218
5277
  try {
5219
5278
  const globalOpts = program2.opts();
@@ -5566,7 +5625,7 @@ program2.command("bulk <action> <ids...>").description("Batch operations: forget
5566
5625
  handleError(e);
5567
5626
  }
5568
5627
  });
5569
- program2.command("doctor").description("Diagnose common issues with the mementos installation").action(() => {
5628
+ program2.command("doctor").description("Diagnose common issues with the mementos installation").action(async () => {
5570
5629
  const globalOpts = program2.opts();
5571
5630
  const checks = [];
5572
5631
  const version = getPackageVersion();
@@ -5693,9 +5752,22 @@ program2.command("doctor").description("Diagnose common issues with the mementos
5693
5752
  }
5694
5753
  try {
5695
5754
  const mementosUrl = process.env["MEMENTOS_URL"] || `http://127.0.0.1:19428`;
5696
- checks.push({ name: "REST server URL", status: "ok", detail: `${mementosUrl} (use 'mementos-serve' to start)` });
5755
+ let serverStatus = "warn";
5756
+ let serverDetail = `${mementosUrl} \u2014 not reachable (run 'mementos-serve' to start)`;
5757
+ try {
5758
+ const controller = new AbortController;
5759
+ const timeout = setTimeout(() => controller.abort(), 1000);
5760
+ const res = await fetch(`${mementosUrl}/api/health`, { signal: controller.signal });
5761
+ clearTimeout(timeout);
5762
+ if (res.ok) {
5763
+ const data = await res.json();
5764
+ serverStatus = "ok";
5765
+ serverDetail = `${mementosUrl} \u2014 running v${data.version || "?"} (${data.status || "ok"})`;
5766
+ }
5767
+ } catch {}
5768
+ checks.push({ name: "REST server", status: serverStatus, detail: serverDetail });
5697
5769
  } catch {
5698
- checks.push({ name: "REST server URL", status: "ok", detail: "http://127.0.0.1:19428" });
5770
+ checks.push({ name: "REST server", status: "warn", detail: "Could not check REST server" });
5699
5771
  }
5700
5772
  outputDoctorResults(globalOpts, checks);
5701
5773
  });
@@ -6551,7 +6623,7 @@ function diffLines(oldText, newText) {
6551
6623
  }
6552
6624
  }
6553
6625
  program2.command("completions <shell>").description("Output shell completion script (bash, zsh, fish)").action((shell) => {
6554
- const commands = "save recall list update forget search stats export import clean inject context pin unpin archive versions doctor tail diff init agents projects bulk completions config backup restore report profile mcp";
6626
+ const commands = "save recall list update forget search stats export import clean inject context pin unpin archive versions stale doctor tail diff init agents projects bulk completions config backup restore report profile mcp";
6555
6627
  const commandList = commands.split(" ");
6556
6628
  switch (shell.toLowerCase()) {
6557
6629
  case "bash": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/mementos",
3
- "version": "0.4.37",
3
+ "version": "0.4.38",
4
4
  "description": "Universal memory system for AI agents - CLI + MCP server + library API",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",