@hasna/mementos 0.3.3 → 0.3.5

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
@@ -3581,7 +3581,7 @@ program2.command("recall <key>").description("Recall a memory by key").option("-
3581
3581
  handleError(e);
3582
3582
  }
3583
3583
  });
3584
- program2.command("list").description("List memories with optional filters").option("-s, --scope <scope>", "Scope filter").option("-c, --category <cat>", "Category filter").option("--tags <tags>", "Comma-separated tags filter").option("--importance-min <n>", "Minimum importance", parseInt).option("--pinned", "Show only pinned").option("--agent <name>", "Agent filter").option("--project <path>", "Project filter").option("--limit <n>", "Max results", parseInt).option("--offset <n>", "Offset for pagination", parseInt).option("--status <status>", "Status filter: active, archived, expired").action((opts) => {
3584
+ program2.command("list").description("List memories with optional filters").option("-s, --scope <scope>", "Scope filter").option("-c, --category <cat>", "Category filter").option("--tags <tags>", "Comma-separated tags filter").option("--importance-min <n>", "Minimum importance", parseInt).option("--pinned", "Show only pinned").option("--agent <name>", "Agent filter").option("--project <path>", "Project filter").option("--limit <n>", "Max results", parseInt).option("--offset <n>", "Offset for pagination", parseInt).option("--status <status>", "Status filter: active, archived, expired").option("--format <fmt>", "Output format: compact (default), json, csv").action((opts) => {
3585
3585
  try {
3586
3586
  const globalOpts = program2.opts();
3587
3587
  const agentId = opts.agent || globalOpts.agent;
@@ -3606,10 +3606,19 @@ program2.command("list").description("List memories with optional filters").opti
3606
3606
  session_id: globalOpts.session
3607
3607
  };
3608
3608
  const memories = listMemories(filter);
3609
- if (globalOpts.json) {
3609
+ const fmt = opts.format || (globalOpts.json ? "json" : "compact");
3610
+ if (fmt === "json") {
3610
3611
  outputJson(memories);
3611
3612
  return;
3612
3613
  }
3614
+ if (fmt === "csv") {
3615
+ console.log("key,value,scope,category,importance,id");
3616
+ for (const m of memories) {
3617
+ const v = m.value.replace(/"/g, '""');
3618
+ console.log(`"${m.key}","${v}",${m.scope},${m.category},${m.importance},${m.id.slice(0, 8)}`);
3619
+ }
3620
+ return;
3621
+ }
3613
3622
  if (memories.length === 0) {
3614
3623
  console.log(chalk.yellow("No memories found."));
3615
3624
  return;
@@ -3701,7 +3710,7 @@ program2.command("forget <keyOrId>").description("Delete a memory by key or ID")
3701
3710
  handleError(e);
3702
3711
  }
3703
3712
  });
3704
- program2.command("search <query>").description("Full-text search across memories").option("-s, --scope <scope>", "Scope filter").option("-c, --category <cat>", "Category filter").option("--tags <tags>", "Comma-separated tags filter").option("--limit <n>", "Max results", parseInt).action((query, opts) => {
3713
+ program2.command("search <query>").description("Full-text search across memories").option("-s, --scope <scope>", "Scope filter").option("-c, --category <cat>", "Category filter").option("--tags <tags>", "Comma-separated tags filter").option("--limit <n>", "Max results", parseInt).option("--format <fmt>", "Output format: compact (default), json, csv").action((query, opts) => {
3705
3714
  try {
3706
3715
  const globalOpts = program2.opts();
3707
3716
  const filter = {
@@ -3711,10 +3720,19 @@ program2.command("search <query>").description("Full-text search across memories
3711
3720
  limit: opts.limit || 20
3712
3721
  };
3713
3722
  const results = searchMemories(query, filter);
3714
- if (globalOpts.json) {
3723
+ const fmt = opts.format || (globalOpts.json ? "json" : "compact");
3724
+ if (fmt === "json") {
3715
3725
  outputJson(results);
3716
3726
  return;
3717
3727
  }
3728
+ if (fmt === "csv") {
3729
+ console.log("key,value,scope,category,importance,score,id");
3730
+ for (const r of results) {
3731
+ const v = r.memory.value.replace(/"/g, '""');
3732
+ console.log(`"${r.memory.key}","${v}",${r.memory.scope},${r.memory.category},${r.memory.importance},${r.score.toFixed(1)},${r.memory.id.slice(0, 8)}`);
3733
+ }
3734
+ return;
3735
+ }
3718
3736
  if (results.length === 0) {
3719
3737
  console.log(chalk.yellow(`No memories found matching "${query}".`));
3720
3738
  return;
package/dist/mcp/index.js CHANGED
@@ -4937,19 +4937,19 @@ function formatMemory(m) {
4937
4937
  `);
4938
4938
  }
4939
4939
  server.tool("memory_save", "Save/upsert a memory. scope: global=all agents, shared=project, private=single agent.", {
4940
- key: exports_external.string().describe("Unique key for the memory"),
4941
- value: exports_external.string().describe("Memory content/value"),
4942
- scope: exports_external.enum(["global", "shared", "private"]).optional().describe("Memory scope (default: private)"),
4943
- category: exports_external.enum(["preference", "fact", "knowledge", "history"]).optional().describe("Memory category (default: knowledge)"),
4944
- importance: exports_external.coerce.number().min(1).max(10).optional().describe("Importance 1-10 (default: 5)"),
4945
- tags: exports_external.array(exports_external.string()).optional().describe("Tags for categorization"),
4946
- summary: exports_external.string().optional().describe("Brief summary of the memory"),
4947
- agent_id: exports_external.string().optional().describe("Agent ID (for scoping)"),
4948
- project_id: exports_external.string().optional().describe("Project ID (for scoping)"),
4949
- session_id: exports_external.string().optional().describe("Session ID (for scoping)"),
4950
- ttl_ms: exports_external.coerce.number().optional().describe("Time-to-live in milliseconds"),
4951
- source: exports_external.enum(["user", "agent", "system", "auto", "imported"]).optional().describe("Source of the memory"),
4952
- metadata: exports_external.record(exports_external.unknown()).optional().describe("Arbitrary metadata")
4940
+ key: exports_external.string(),
4941
+ value: exports_external.string(),
4942
+ scope: exports_external.enum(["global", "shared", "private"]).optional(),
4943
+ category: exports_external.enum(["preference", "fact", "knowledge", "history"]).optional(),
4944
+ importance: exports_external.coerce.number().min(1).max(10).optional(),
4945
+ tags: exports_external.array(exports_external.string()).optional(),
4946
+ summary: exports_external.string().optional(),
4947
+ agent_id: exports_external.string().optional(),
4948
+ project_id: exports_external.string().optional(),
4949
+ session_id: exports_external.string().optional(),
4950
+ ttl_ms: exports_external.coerce.number().optional(),
4951
+ source: exports_external.enum(["user", "agent", "system", "auto", "imported"]).optional(),
4952
+ metadata: exports_external.record(exports_external.unknown()).optional()
4953
4953
  }, async (args) => {
4954
4954
  try {
4955
4955
  ensureAutoProject();
@@ -4960,7 +4960,7 @@ server.tool("memory_save", "Save/upsert a memory. scope: global=all agents, shar
4960
4960
  }
4961
4961
  });
4962
4962
  server.tool("memory_recall", "Recall a memory by key. Returns the best matching active memory.", {
4963
- key: exports_external.string().describe("Memory key to recall"),
4963
+ key: exports_external.string(),
4964
4964
  scope: exports_external.enum(["global", "shared", "private"]).optional(),
4965
4965
  agent_id: exports_external.string().optional(),
4966
4966
  project_id: exports_external.string().optional(),
@@ -5006,10 +5006,10 @@ server.tool("memory_list", "List memories. Default: compact lines. full=true for
5006
5006
  project_id: exports_external.string().optional(),
5007
5007
  session_id: exports_external.string().optional(),
5008
5008
  status: exports_external.enum(["active", "archived", "expired"]).optional(),
5009
- limit: exports_external.coerce.number().optional().describe("Max results (default: 10)"),
5009
+ limit: exports_external.coerce.number().optional(),
5010
5010
  offset: exports_external.coerce.number().optional(),
5011
- full: exports_external.boolean().optional().describe("Return full Memory objects as JSON instead of compact lines"),
5012
- fields: exports_external.array(exports_external.string()).optional().describe("Filter fields in full mode: e.g. ['key','value','importance']")
5011
+ full: exports_external.boolean().optional(),
5012
+ fields: exports_external.array(exports_external.string()).optional()
5013
5013
  }, async (args) => {
5014
5014
  try {
5015
5015
  const { full, fields, ...filterArgs } = args;
@@ -5043,7 +5043,7 @@ ${lines.join(`
5043
5043
  }
5044
5044
  });
5045
5045
  server.tool("memory_update", "Update a memory's metadata (value, importance, tags, etc.)", {
5046
- id: exports_external.string().describe("Memory ID (full or partial)"),
5046
+ id: exports_external.string(),
5047
5047
  value: exports_external.string().optional(),
5048
5048
  category: exports_external.enum(["preference", "fact", "knowledge", "history"]).optional(),
5049
5049
  scope: exports_external.enum(["global", "shared", "private"]).optional(),
@@ -5054,7 +5054,7 @@ server.tool("memory_update", "Update a memory's metadata (value, importance, tag
5054
5054
  status: exports_external.enum(["active", "archived", "expired"]).optional(),
5055
5055
  metadata: exports_external.record(exports_external.unknown()).optional(),
5056
5056
  expires_at: exports_external.string().nullable().optional(),
5057
- version: exports_external.coerce.number().describe("Current version (for optimistic locking)")
5057
+ version: exports_external.coerce.number()
5058
5058
  }, async (args) => {
5059
5059
  try {
5060
5060
  const id = resolveId(args.id);
@@ -5067,8 +5067,8 @@ ${formatMemory(memory)}` }] };
5067
5067
  }
5068
5068
  });
5069
5069
  server.tool("memory_forget", "Delete a memory by ID or key", {
5070
- id: exports_external.string().optional().describe("Memory ID (full or partial)"),
5071
- key: exports_external.string().optional().describe("Memory key"),
5070
+ id: exports_external.string().optional(),
5071
+ key: exports_external.string().optional(),
5072
5072
  scope: exports_external.enum(["global", "shared", "private"]).optional(),
5073
5073
  agent_id: exports_external.string().optional(),
5074
5074
  project_id: exports_external.string().optional()
@@ -5093,13 +5093,13 @@ server.tool("memory_forget", "Delete a memory by ID or key", {
5093
5093
  }
5094
5094
  });
5095
5095
  server.tool("memory_search", "Search memories by keyword across key, value, summary, and tags", {
5096
- query: exports_external.string().describe("Search query"),
5096
+ query: exports_external.string(),
5097
5097
  scope: exports_external.enum(["global", "shared", "private"]).optional(),
5098
5098
  category: exports_external.enum(["preference", "fact", "knowledge", "history"]).optional(),
5099
5099
  tags: exports_external.array(exports_external.string()).optional(),
5100
5100
  agent_id: exports_external.string().optional(),
5101
5101
  project_id: exports_external.string().optional(),
5102
- limit: exports_external.coerce.number().optional().describe("Max results (default: 20)")
5102
+ limit: exports_external.coerce.number().optional()
5103
5103
  }, async (args) => {
5104
5104
  try {
5105
5105
  const filter = {
@@ -5195,8 +5195,8 @@ server.tool("memory_import", "Import memories from JSON array", {
5195
5195
  agent_id: exports_external.string().optional(),
5196
5196
  project_id: exports_external.string().optional(),
5197
5197
  metadata: exports_external.record(exports_external.unknown()).optional()
5198
- })).describe("Array of memories to import"),
5199
- overwrite: exports_external.boolean().optional().describe("Overwrite existing (default: true, uses merge dedup)")
5198
+ })),
5199
+ overwrite: exports_external.boolean().optional()
5200
5200
  }, async (args) => {
5201
5201
  try {
5202
5202
  let imported = 0;
@@ -5211,12 +5211,13 @@ server.tool("memory_import", "Import memories from JSON array", {
5211
5211
  }
5212
5212
  });
5213
5213
  server.tool("memory_inject", "Get memory context for system prompt injection. Selects by scope, importance, recency.", {
5214
- agent_id: exports_external.string().optional().describe("Agent ID for scope filtering"),
5215
- project_id: exports_external.string().optional().describe("Project ID for scope filtering"),
5216
- session_id: exports_external.string().optional().describe("Session ID for scope filtering"),
5217
- max_tokens: exports_external.coerce.number().optional().describe("Max approximate token budget (default: 500)"),
5214
+ agent_id: exports_external.string().optional(),
5215
+ project_id: exports_external.string().optional(),
5216
+ session_id: exports_external.string().optional(),
5217
+ max_tokens: exports_external.coerce.number().optional(),
5218
5218
  categories: exports_external.array(exports_external.enum(["preference", "fact", "knowledge", "history"])).optional(),
5219
- min_importance: exports_external.coerce.number().optional().describe("Minimum importance threshold (default: 3)")
5219
+ min_importance: exports_external.coerce.number().optional(),
5220
+ raw: exports_external.boolean().optional()
5220
5221
  }, async (args) => {
5221
5222
  try {
5222
5223
  const maxTokens = args.max_tokens || 500;
@@ -5280,7 +5281,8 @@ server.tool("memory_inject", "Get memory context for system prompt injection. Se
5280
5281
  if (lines.length === 0) {
5281
5282
  return { content: [{ type: "text", text: "No relevant memories found for injection." }] };
5282
5283
  }
5283
- const context = `<agent-memories>
5284
+ const context = args.raw ? lines.join(`
5285
+ `) : `<agent-memories>
5284
5286
  ${lines.join(`
5285
5287
  `)}
5286
5288
  </agent-memories>`;
@@ -5290,9 +5292,9 @@ ${lines.join(`
5290
5292
  }
5291
5293
  });
5292
5294
  server.tool("register_agent", "Register an agent. Idempotent \u2014 same name returns existing agent.", {
5293
- name: exports_external.string().describe("Agent name"),
5294
- description: exports_external.string().optional().describe("Agent description"),
5295
- role: exports_external.string().optional().describe("Agent role")
5295
+ name: exports_external.string(),
5296
+ description: exports_external.string().optional(),
5297
+ role: exports_external.string().optional()
5296
5298
  }, async (args) => {
5297
5299
  try {
5298
5300
  const agent = registerAgent(args.name, args.description, args.role);
@@ -5326,7 +5328,7 @@ ${lines.join(`
5326
5328
  }
5327
5329
  });
5328
5330
  server.tool("get_agent", "Get agent details by ID or name", {
5329
- id: exports_external.string().describe("Agent ID or name")
5331
+ id: exports_external.string()
5330
5332
  }, async (args) => {
5331
5333
  try {
5332
5334
  const agent = getAgent(args.id);
@@ -5350,11 +5352,11 @@ Last seen: ${agent.last_seen_at}`
5350
5352
  }
5351
5353
  });
5352
5354
  server.tool("update_agent", "Update agent name, description, role, or metadata.", {
5353
- id: exports_external.string().describe("Agent ID or name"),
5354
- name: exports_external.string().optional().describe("New agent name"),
5355
- description: exports_external.string().optional().describe("New description"),
5356
- role: exports_external.string().optional().describe("New role"),
5357
- metadata: exports_external.record(exports_external.unknown()).optional().describe("Updated metadata")
5355
+ id: exports_external.string(),
5356
+ name: exports_external.string().optional(),
5357
+ description: exports_external.string().optional(),
5358
+ role: exports_external.string().optional(),
5359
+ metadata: exports_external.record(exports_external.unknown()).optional()
5358
5360
  }, async (args) => {
5359
5361
  try {
5360
5362
  const { id, ...updates } = args;
@@ -5379,8 +5381,8 @@ Last seen: ${agent.last_seen_at}`
5379
5381
  }
5380
5382
  });
5381
5383
  server.tool("register_project", "Register a project for memory scoping", {
5382
- name: exports_external.string().describe("Project name"),
5383
- path: exports_external.string().describe("Absolute path to project"),
5384
+ name: exports_external.string(),
5385
+ path: exports_external.string(),
5384
5386
  description: exports_external.string().optional(),
5385
5387
  memory_prefix: exports_external.string().optional()
5386
5388
  }, async (args) => {
@@ -5415,7 +5417,7 @@ ${lines.join(`
5415
5417
  }
5416
5418
  });
5417
5419
  server.tool("bulk_forget", "Delete multiple memories by IDs", {
5418
- ids: exports_external.array(exports_external.string()).describe("Memory IDs to delete")
5420
+ ids: exports_external.array(exports_external.string())
5419
5421
  }, async (args) => {
5420
5422
  try {
5421
5423
  const resolvedIds = args.ids.map((id) => resolveId(id));
@@ -5426,7 +5428,7 @@ server.tool("bulk_forget", "Delete multiple memories by IDs", {
5426
5428
  }
5427
5429
  });
5428
5430
  server.tool("bulk_update", "Update multiple memories with the same changes", {
5429
- ids: exports_external.array(exports_external.string()).describe("Memory IDs to update"),
5431
+ ids: exports_external.array(exports_external.string()),
5430
5432
  importance: exports_external.coerce.number().min(1).max(10).optional(),
5431
5433
  tags: exports_external.array(exports_external.string()).optional(),
5432
5434
  pinned: exports_external.boolean().optional(),
@@ -5460,8 +5462,8 @@ server.tool("clean_expired", "Remove expired memories from the database", {}, as
5460
5462
  server.tool("memory_context", "Get memories relevant to current context, filtered by scope/importance/recency.", {
5461
5463
  agent_id: exports_external.string().optional(),
5462
5464
  project_id: exports_external.string().optional(),
5463
- scope: exports_external.enum(["global", "shared", "private"]).optional().describe("Limit to specific scope"),
5464
- limit: exports_external.coerce.number().optional().describe("Max memories (default: 30)")
5465
+ scope: exports_external.enum(["global", "shared", "private"]).optional(),
5466
+ limit: exports_external.coerce.number().optional()
5465
5467
  }, async (args) => {
5466
5468
  try {
5467
5469
  const filter = {
@@ -5507,7 +5509,7 @@ var TOOL_REGISTRY = [
5507
5509
  { name: "describe_tools", description: "Get full schemas for specific tools by name.", category: "meta" }
5508
5510
  ];
5509
5511
  server.tool("search_tools", "Search available tools by name or keyword. Returns names only.", {
5510
- query: exports_external.string().describe("Search term to match against tool names and descriptions"),
5512
+ query: exports_external.string(),
5511
5513
  category: exports_external.enum(["memory", "agent", "project", "bulk", "utility", "meta"]).optional()
5512
5514
  }, async (args) => {
5513
5515
  const q = args.query.toLowerCase();
@@ -5518,7 +5520,7 @@ server.tool("search_tools", "Search available tools by name or keyword. Returns
5518
5520
  `) }] };
5519
5521
  });
5520
5522
  server.tool("describe_tools", "Get full schemas for specific tools by name.", {
5521
- names: exports_external.array(exports_external.string()).describe("Tool names to describe")
5523
+ names: exports_external.array(exports_external.string())
5522
5524
  }, async (args) => {
5523
5525
  const found = TOOL_REGISTRY.filter((t) => args.names.includes(t.name));
5524
5526
  if (found.length === 0)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/mementos",
3
- "version": "0.3.3",
3
+ "version": "0.3.5",
4
4
  "description": "Universal memory system for AI agents - CLI + MCP server + library API",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",