@hasna/mementos 0.14.13 → 0.14.15

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 +158 -152
  2. package/package.json +1 -1
package/dist/cli/index.js CHANGED
@@ -15088,6 +15088,155 @@ var init_projects = __esm(() => {
15088
15088
  init_database();
15089
15089
  });
15090
15090
 
15091
+ // src/db/agents.ts
15092
+ var exports_agents = {};
15093
+ __export(exports_agents, {
15094
+ updateAgent: () => updateAgent,
15095
+ touchAgent: () => touchAgent,
15096
+ registerAgent: () => registerAgent,
15097
+ listAgentsByProject: () => listAgentsByProject,
15098
+ listAgents: () => listAgents,
15099
+ getAgent: () => getAgent
15100
+ });
15101
+ function parseAgentRow(row) {
15102
+ return {
15103
+ id: row["id"],
15104
+ name: row["name"],
15105
+ session_id: row["session_id"] || null,
15106
+ description: row["description"] || null,
15107
+ role: row["role"] || null,
15108
+ metadata: JSON.parse(row["metadata"] || "{}"),
15109
+ active_project_id: row["active_project_id"] || null,
15110
+ created_at: row["created_at"],
15111
+ last_seen_at: row["last_seen_at"]
15112
+ };
15113
+ }
15114
+ function registerAgent(name, sessionId, description, role, projectId, db) {
15115
+ const d = db || getDatabase();
15116
+ const timestamp = now();
15117
+ const normalizedName = name.trim().toLowerCase();
15118
+ if (projectId) {
15119
+ const resolvedProjectId = resolvePartialId(d, "projects", projectId);
15120
+ if (!resolvedProjectId) {
15121
+ throw new Error(`Project not found: ${projectId}`);
15122
+ }
15123
+ projectId = resolvedProjectId;
15124
+ }
15125
+ const existing = d.query("SELECT * FROM agents WHERE LOWER(name) = ?").get(normalizedName);
15126
+ if (existing) {
15127
+ const existingId = existing["id"];
15128
+ const existingSessionId = existing["session_id"] || null;
15129
+ const existingLastSeen = existing["last_seen_at"];
15130
+ if (sessionId && existingSessionId && existingSessionId !== sessionId) {
15131
+ const lastSeenMs = new Date(existingLastSeen).getTime();
15132
+ const nowMs = Date.now();
15133
+ if (nowMs - lastSeenMs < CONFLICT_WINDOW_MS) {
15134
+ throw new AgentConflictError({
15135
+ existing_id: existingId,
15136
+ existing_name: normalizedName,
15137
+ last_seen_at: existingLastSeen,
15138
+ session_hint: existingSessionId.slice(0, 8),
15139
+ working_dir: null
15140
+ });
15141
+ }
15142
+ }
15143
+ d.run("UPDATE agents SET last_seen_at = ?, session_id = ? WHERE id = ?", [
15144
+ timestamp,
15145
+ sessionId ?? existingSessionId,
15146
+ existingId
15147
+ ]);
15148
+ if (description) {
15149
+ d.run("UPDATE agents SET description = ? WHERE id = ?", [description, existingId]);
15150
+ }
15151
+ if (role) {
15152
+ d.run("UPDATE agents SET role = ? WHERE id = ?", [role, existingId]);
15153
+ }
15154
+ if (projectId !== undefined) {
15155
+ d.run("UPDATE agents SET active_project_id = ? WHERE id = ?", [projectId, existingId]);
15156
+ }
15157
+ return getAgent(existingId, d);
15158
+ }
15159
+ const id = shortUuid();
15160
+ d.run("INSERT INTO agents (id, name, session_id, description, role, active_project_id, created_at, last_seen_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", [id, normalizedName, sessionId ?? null, description || null, role || "agent", projectId ?? null, timestamp, timestamp]);
15161
+ return getAgent(id, d);
15162
+ }
15163
+ function getAgent(idOrName, db) {
15164
+ const d = db || getDatabase();
15165
+ let row = d.query("SELECT * FROM agents WHERE id = ?").get(idOrName);
15166
+ if (row)
15167
+ return parseAgentRow(row);
15168
+ row = d.query("SELECT * FROM agents WHERE LOWER(name) = ?").get(idOrName.trim().toLowerCase());
15169
+ if (row)
15170
+ return parseAgentRow(row);
15171
+ const rows = d.query("SELECT * FROM agents WHERE id LIKE ?").all(`${idOrName}%`);
15172
+ if (rows.length === 1)
15173
+ return parseAgentRow(rows[0]);
15174
+ return null;
15175
+ }
15176
+ function listAgents(db) {
15177
+ const d = db || getDatabase();
15178
+ const rows = d.query("SELECT * FROM agents ORDER BY last_seen_at DESC").all();
15179
+ return rows.map(parseAgentRow);
15180
+ }
15181
+ function touchAgent(idOrName, db) {
15182
+ const d = db || getDatabase();
15183
+ const agent = getAgent(idOrName, d);
15184
+ if (!agent)
15185
+ return;
15186
+ d.run("UPDATE agents SET last_seen_at = ? WHERE id = ?", [now(), agent.id]);
15187
+ }
15188
+ function listAgentsByProject(projectId, db) {
15189
+ const d = db || getDatabase();
15190
+ const resolvedId = resolvePartialId(d, "projects", projectId) || projectId;
15191
+ const rows = d.query("SELECT * FROM agents WHERE active_project_id = ? ORDER BY last_seen_at DESC").all(resolvedId);
15192
+ return rows.map(parseAgentRow);
15193
+ }
15194
+ function updateAgent(id, updates, db) {
15195
+ const d = db || getDatabase();
15196
+ const agent = getAgent(id, d);
15197
+ if (!agent)
15198
+ return null;
15199
+ const timestamp = now();
15200
+ if (updates.name) {
15201
+ const normalizedNewName = updates.name.trim().toLowerCase();
15202
+ if (normalizedNewName !== agent.name) {
15203
+ const existing = d.query("SELECT id FROM agents WHERE LOWER(name) = ? AND id != ?").get(normalizedNewName, agent.id);
15204
+ if (existing) {
15205
+ throw new Error(`Agent name already taken: ${normalizedNewName}`);
15206
+ }
15207
+ d.run("UPDATE agents SET name = ? WHERE id = ?", [normalizedNewName, agent.id]);
15208
+ }
15209
+ }
15210
+ if (updates.description !== undefined) {
15211
+ d.run("UPDATE agents SET description = ? WHERE id = ?", [updates.description, agent.id]);
15212
+ }
15213
+ if (updates.role !== undefined) {
15214
+ d.run("UPDATE agents SET role = ? WHERE id = ?", [updates.role, agent.id]);
15215
+ }
15216
+ if (updates.metadata !== undefined) {
15217
+ d.run("UPDATE agents SET metadata = ? WHERE id = ?", [JSON.stringify(updates.metadata), agent.id]);
15218
+ }
15219
+ if ("active_project_id" in updates) {
15220
+ let resolvedProjectId = updates.active_project_id ?? null;
15221
+ if (resolvedProjectId) {
15222
+ const fullId = resolvePartialId(d, "projects", resolvedProjectId);
15223
+ if (!fullId) {
15224
+ throw new Error(`Project not found: ${resolvedProjectId}`);
15225
+ }
15226
+ resolvedProjectId = fullId;
15227
+ }
15228
+ d.run("UPDATE agents SET active_project_id = ? WHERE id = ?", [resolvedProjectId, agent.id]);
15229
+ }
15230
+ d.run("UPDATE agents SET last_seen_at = ? WHERE id = ?", [timestamp, agent.id]);
15231
+ return getAgent(agent.id, d);
15232
+ }
15233
+ var CONFLICT_WINDOW_MS;
15234
+ var init_agents = __esm(() => {
15235
+ init_types2();
15236
+ init_database();
15237
+ CONFLICT_WINDOW_MS = 30 * 60 * 1000;
15238
+ });
15239
+
15091
15240
  // src/db/entities.ts
15092
15241
  function parseEntityRow(row) {
15093
15242
  return {
@@ -16369,155 +16518,6 @@ var init_helpers = __esm(() => {
16369
16518
  VALID_CATEGORIES = ["preference", "fact", "knowledge", "history"];
16370
16519
  });
16371
16520
 
16372
- // src/db/agents.ts
16373
- var exports_agents = {};
16374
- __export(exports_agents, {
16375
- updateAgent: () => updateAgent,
16376
- touchAgent: () => touchAgent,
16377
- registerAgent: () => registerAgent,
16378
- listAgentsByProject: () => listAgentsByProject,
16379
- listAgents: () => listAgents,
16380
- getAgent: () => getAgent
16381
- });
16382
- function parseAgentRow(row) {
16383
- return {
16384
- id: row["id"],
16385
- name: row["name"],
16386
- session_id: row["session_id"] || null,
16387
- description: row["description"] || null,
16388
- role: row["role"] || null,
16389
- metadata: JSON.parse(row["metadata"] || "{}"),
16390
- active_project_id: row["active_project_id"] || null,
16391
- created_at: row["created_at"],
16392
- last_seen_at: row["last_seen_at"]
16393
- };
16394
- }
16395
- function registerAgent(name, sessionId, description, role, projectId, db) {
16396
- const d = db || getDatabase();
16397
- const timestamp = now();
16398
- const normalizedName = name.trim().toLowerCase();
16399
- if (projectId) {
16400
- const resolvedProjectId = resolvePartialId(d, "projects", projectId);
16401
- if (!resolvedProjectId) {
16402
- throw new Error(`Project not found: ${projectId}`);
16403
- }
16404
- projectId = resolvedProjectId;
16405
- }
16406
- const existing = d.query("SELECT * FROM agents WHERE LOWER(name) = ?").get(normalizedName);
16407
- if (existing) {
16408
- const existingId = existing["id"];
16409
- const existingSessionId = existing["session_id"] || null;
16410
- const existingLastSeen = existing["last_seen_at"];
16411
- if (sessionId && existingSessionId && existingSessionId !== sessionId) {
16412
- const lastSeenMs = new Date(existingLastSeen).getTime();
16413
- const nowMs = Date.now();
16414
- if (nowMs - lastSeenMs < CONFLICT_WINDOW_MS) {
16415
- throw new AgentConflictError({
16416
- existing_id: existingId,
16417
- existing_name: normalizedName,
16418
- last_seen_at: existingLastSeen,
16419
- session_hint: existingSessionId.slice(0, 8),
16420
- working_dir: null
16421
- });
16422
- }
16423
- }
16424
- d.run("UPDATE agents SET last_seen_at = ?, session_id = ? WHERE id = ?", [
16425
- timestamp,
16426
- sessionId ?? existingSessionId,
16427
- existingId
16428
- ]);
16429
- if (description) {
16430
- d.run("UPDATE agents SET description = ? WHERE id = ?", [description, existingId]);
16431
- }
16432
- if (role) {
16433
- d.run("UPDATE agents SET role = ? WHERE id = ?", [role, existingId]);
16434
- }
16435
- if (projectId !== undefined) {
16436
- d.run("UPDATE agents SET active_project_id = ? WHERE id = ?", [projectId, existingId]);
16437
- }
16438
- return getAgent(existingId, d);
16439
- }
16440
- const id = shortUuid();
16441
- d.run("INSERT INTO agents (id, name, session_id, description, role, active_project_id, created_at, last_seen_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", [id, normalizedName, sessionId ?? null, description || null, role || "agent", projectId ?? null, timestamp, timestamp]);
16442
- return getAgent(id, d);
16443
- }
16444
- function getAgent(idOrName, db) {
16445
- const d = db || getDatabase();
16446
- let row = d.query("SELECT * FROM agents WHERE id = ?").get(idOrName);
16447
- if (row)
16448
- return parseAgentRow(row);
16449
- row = d.query("SELECT * FROM agents WHERE LOWER(name) = ?").get(idOrName.trim().toLowerCase());
16450
- if (row)
16451
- return parseAgentRow(row);
16452
- const rows = d.query("SELECT * FROM agents WHERE id LIKE ?").all(`${idOrName}%`);
16453
- if (rows.length === 1)
16454
- return parseAgentRow(rows[0]);
16455
- return null;
16456
- }
16457
- function listAgents(db) {
16458
- const d = db || getDatabase();
16459
- const rows = d.query("SELECT * FROM agents ORDER BY last_seen_at DESC").all();
16460
- return rows.map(parseAgentRow);
16461
- }
16462
- function touchAgent(idOrName, db) {
16463
- const d = db || getDatabase();
16464
- const agent = getAgent(idOrName, d);
16465
- if (!agent)
16466
- return;
16467
- d.run("UPDATE agents SET last_seen_at = ? WHERE id = ?", [now(), agent.id]);
16468
- }
16469
- function listAgentsByProject(projectId, db) {
16470
- const d = db || getDatabase();
16471
- const resolvedId = resolvePartialId(d, "projects", projectId) || projectId;
16472
- const rows = d.query("SELECT * FROM agents WHERE active_project_id = ? ORDER BY last_seen_at DESC").all(resolvedId);
16473
- return rows.map(parseAgentRow);
16474
- }
16475
- function updateAgent(id, updates, db) {
16476
- const d = db || getDatabase();
16477
- const agent = getAgent(id, d);
16478
- if (!agent)
16479
- return null;
16480
- const timestamp = now();
16481
- if (updates.name) {
16482
- const normalizedNewName = updates.name.trim().toLowerCase();
16483
- if (normalizedNewName !== agent.name) {
16484
- const existing = d.query("SELECT id FROM agents WHERE LOWER(name) = ? AND id != ?").get(normalizedNewName, agent.id);
16485
- if (existing) {
16486
- throw new Error(`Agent name already taken: ${normalizedNewName}`);
16487
- }
16488
- d.run("UPDATE agents SET name = ? WHERE id = ?", [normalizedNewName, agent.id]);
16489
- }
16490
- }
16491
- if (updates.description !== undefined) {
16492
- d.run("UPDATE agents SET description = ? WHERE id = ?", [updates.description, agent.id]);
16493
- }
16494
- if (updates.role !== undefined) {
16495
- d.run("UPDATE agents SET role = ? WHERE id = ?", [updates.role, agent.id]);
16496
- }
16497
- if (updates.metadata !== undefined) {
16498
- d.run("UPDATE agents SET metadata = ? WHERE id = ?", [JSON.stringify(updates.metadata), agent.id]);
16499
- }
16500
- if ("active_project_id" in updates) {
16501
- let resolvedProjectId = updates.active_project_id ?? null;
16502
- if (resolvedProjectId) {
16503
- const fullId = resolvePartialId(d, "projects", resolvedProjectId);
16504
- if (!fullId) {
16505
- throw new Error(`Project not found: ${resolvedProjectId}`);
16506
- }
16507
- resolvedProjectId = fullId;
16508
- }
16509
- d.run("UPDATE agents SET active_project_id = ? WHERE id = ?", [resolvedProjectId, agent.id]);
16510
- }
16511
- d.run("UPDATE agents SET last_seen_at = ? WHERE id = ?", [timestamp, agent.id]);
16512
- return getAgent(agent.id, d);
16513
- }
16514
- var CONFLICT_WINDOW_MS;
16515
- var init_agents = __esm(() => {
16516
- init_types2();
16517
- init_database();
16518
- CONFLICT_WINDOW_MS = 30 * 60 * 1000;
16519
- });
16520
-
16521
16521
  // src/lib/poll.ts
16522
16522
  var exports_poll = {};
16523
16523
  __export(exports_poll, {
@@ -20957,6 +20957,7 @@ import { fileURLToPath as fileURLToPath3 } from "url";
20957
20957
  init_database();
20958
20958
  init_memories();
20959
20959
  init_projects();
20960
+ init_agents();
20960
20961
  init_search();
20961
20962
  import chalk2 from "chalk";
20962
20963
  import { resolve as resolve3 } from "path";
@@ -21048,6 +21049,11 @@ function registerMemoryCommands(program2) {
21048
21049
  }
21049
21050
  const explicitTags = opts.tags ? opts.tags.split(",").map((t) => t.trim()) : undefined;
21050
21051
  const mergedTags = explicitTags ? explicitTags : templateDefaults?.tags && templateDefaults.tags.length > 0 ? templateDefaults.tags : undefined;
21052
+ let resolvedAgentId;
21053
+ if (globalOpts.agent) {
21054
+ const ag = getAgent(globalOpts.agent);
21055
+ resolvedAgentId = ag?.id;
21056
+ }
21051
21057
  const input = {
21052
21058
  key,
21053
21059
  value,
@@ -21058,7 +21064,7 @@ function registerMemoryCommands(program2) {
21058
21064
  summary: opts.summary,
21059
21065
  ttl_ms: opts.ttl ? parseDuration(opts.ttl) : undefined,
21060
21066
  source: opts.source,
21061
- agent_id: globalOpts.agent,
21067
+ agent_id: resolvedAgentId,
21062
21068
  session_id: globalOpts.session
21063
21069
  };
21064
21070
  if (globalOpts.project) {
@@ -22384,7 +22390,7 @@ function registerIoCommands(program2) {
22384
22390
  if (!Array.isArray(memories)) {
22385
22391
  throw new Error("JSON file must contain an array of memories");
22386
22392
  }
22387
- const dedupeMode = opts.overwrite ? "merge" : "create";
22393
+ const dedupeMode = opts.overwrite ? "create" : "merge";
22388
22394
  let imported = 0;
22389
22395
  for (const mem of memories) {
22390
22396
  createMemory({ ...mem, source: mem.source || "imported" }, dedupeMode);
@@ -24543,7 +24549,7 @@ session_end = "bun ${script}"`));
24543
24549
  const { fileURLToPath: _ftu } = await import("url");
24544
24550
  const { dirname: _dir, join: _join } = await import("path");
24545
24551
  const { readFileSync: _rfs } = await import("fs");
24546
- const pkg = JSON.parse(_rfs(_join(_dir(_ftu(import.meta.url)), "../../../package.json"), "utf-8"));
24552
+ const pkg = JSON.parse(_rfs(_join(_dir(_ftu(import.meta.url)), "../../package.json"), "utf-8"));
24547
24553
  db.run("INSERT INTO feedback (message, email, category, version) VALUES (?, ?, ?, ?)", [
24548
24554
  message,
24549
24555
  opts.email || null,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/mementos",
3
- "version": "0.14.13",
3
+ "version": "0.14.15",
4
4
  "description": "Universal memory system for AI agents - CLI + MCP server + library API",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",