@hasna/mementos 0.4.10 → 0.4.12

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/index.d.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  export type { Memory, MemoryWithRelations, MemoryScope, MemoryCategory, MemorySource, MemoryStatus, MemoryFilter, MemorySearchResult, MemoryStats, CreateMemoryInput, UpdateMemoryInput, DedupeMode, Agent, Project, MementosConfig, SyncDirection, SyncOptions, SyncResult, ConflictResolution, Entity, Relation, EntityMemory, EntityType, RelationType, EntityRole, EntityWithRelations, CreateEntityInput, UpdateEntityInput, CreateRelationInput, } from "./types/index.js";
2
2
  export { MemoryNotFoundError, DuplicateMemoryError, MemoryExpiredError, InvalidScopeError, VersionConflictError, EntityNotFoundError, } from "./types/index.js";
3
3
  export { getDatabase, closeDatabase, resetDatabase, getDbPath, resolvePartialId, now, uuid, shortUuid, } from "./db/database.js";
4
- export { createMemory, getMemory, getMemoryByKey, listMemories, updateMemory, deleteMemory, bulkDeleteMemories, touchMemory, cleanExpiredMemories, } from "./db/memories.js";
5
- export { registerAgent, getAgent, listAgents, updateAgent, } from "./db/agents.js";
4
+ export { createMemory, getMemory, getMemoryByKey, getMemoriesByKey, listMemories, updateMemory, deleteMemory, bulkDeleteMemories, touchMemory, cleanExpiredMemories, getMemoryVersions, } from "./db/memories.js";
5
+ export { registerAgent, getAgent, listAgents, listAgentsByProject, updateAgent, touchAgent, } from "./db/agents.js";
6
6
  export { registerProject, getProject, listProjects, } from "./db/projects.js";
7
7
  export { searchMemories } from "./lib/search.js";
8
- export { loadConfig, DEFAULT_CONFIG } from "./lib/config.js";
8
+ export { loadConfig, DEFAULT_CONFIG, getActiveProfile, setActiveProfile, listProfiles, deleteProfile, } from "./lib/config.js";
9
9
  export { MemoryInjector } from "./lib/injector.js";
10
10
  export type { InjectionOptions } from "./lib/injector.js";
11
11
  export { enforceQuotas, archiveStale, archiveUnused, deprioritizeStale, runCleanup } from "./lib/retention.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,YAAY,EACV,MAAM,EACN,mBAAmB,EACnB,WAAW,EACX,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,kBAAkB,EAClB,WAAW,EACX,iBAAiB,EACjB,iBAAiB,EACjB,UAAU,EACV,KAAK,EACL,OAAO,EACP,cAAc,EACd,aAAa,EACb,WAAW,EACX,UAAU,EACV,kBAAkB,EAElB,MAAM,EACN,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,UAAU,EACV,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,iBAAiB,EACjB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,WAAW,EACX,aAAa,EACb,aAAa,EACb,SAAS,EACT,gBAAgB,EAChB,GAAG,EACH,IAAI,EACJ,SAAS,GACV,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,YAAY,EACZ,SAAS,EACT,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,kBAAkB,EAClB,WAAW,EACX,oBAAoB,GACrB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,aAAa,EACb,QAAQ,EACR,UAAU,EACV,WAAW,GACZ,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACL,eAAe,EACf,UAAU,EACV,YAAY,GACb,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGjD,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAG7D,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,YAAY,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAG1D,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAG/G,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAGhE,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAGjE,OAAO,EACL,YAAY,EACZ,SAAS,EACT,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,cAAc,GACf,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,cAAc,EACd,WAAW,EACX,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,QAAQ,EACR,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,EACpB,oBAAoB,EACpB,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EACL,eAAe,EACf,KAAK,eAAe,GACrB,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,YAAY,EACV,MAAM,EACN,mBAAmB,EACnB,WAAW,EACX,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,kBAAkB,EAClB,WAAW,EACX,iBAAiB,EACjB,iBAAiB,EACjB,UAAU,EACV,KAAK,EACL,OAAO,EACP,cAAc,EACd,aAAa,EACb,WAAW,EACX,UAAU,EACV,kBAAkB,EAElB,MAAM,EACN,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,UAAU,EACV,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,iBAAiB,EACjB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,WAAW,EACX,aAAa,EACb,aAAa,EACb,SAAS,EACT,gBAAgB,EAChB,GAAG,EACH,IAAI,EACJ,SAAS,GACV,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,YAAY,EACZ,SAAS,EACT,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,kBAAkB,EAClB,WAAW,EACX,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,aAAa,EACb,QAAQ,EACR,UAAU,EACV,mBAAmB,EACnB,WAAW,EACX,UAAU,GACX,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACL,eAAe,EACf,UAAU,EACV,YAAY,GACb,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGjD,OAAO,EACL,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,aAAa,GACd,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,YAAY,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAG1D,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAG/G,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAGhE,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAGjE,OAAO,EACL,YAAY,EACZ,SAAS,EACT,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,cAAc,GACf,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,cAAc,EACd,WAAW,EACX,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,QAAQ,EACR,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,EACpB,oBAAoB,EACpB,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EACL,eAAe,EACf,KAAK,eAAe,GACrB,MAAM,oBAAoB,CAAC"}
package/dist/index.js CHANGED
@@ -458,6 +458,18 @@ function listAgents(db) {
458
458
  const rows = d.query("SELECT * FROM agents ORDER BY last_seen_at DESC").all();
459
459
  return rows.map(parseAgentRow);
460
460
  }
461
+ function touchAgent(idOrName, db) {
462
+ const d = db || getDatabase();
463
+ const agent = getAgent(idOrName, d);
464
+ if (!agent)
465
+ return;
466
+ d.run("UPDATE agents SET last_seen_at = ? WHERE id = ?", [now(), agent.id]);
467
+ }
468
+ function listAgentsByProject(projectId, db) {
469
+ const d = db || getDatabase();
470
+ const rows = d.query("SELECT * FROM agents WHERE active_project_id = ? ORDER BY last_seen_at DESC").all(projectId);
471
+ return rows.map(parseAgentRow);
472
+ }
461
473
  function updateAgent(id, updates, db) {
462
474
  const d = db || getDatabase();
463
475
  const agent = getAgent(id, d);
@@ -1118,6 +1130,63 @@ function loadConfig() {
1118
1130
  }
1119
1131
  return merged;
1120
1132
  }
1133
+ function profilesDir() {
1134
+ return join2(homedir(), ".mementos", "profiles");
1135
+ }
1136
+ function globalConfigPath() {
1137
+ return join2(homedir(), ".mementos", "config.json");
1138
+ }
1139
+ function readGlobalConfig() {
1140
+ const p = globalConfigPath();
1141
+ if (!existsSync2(p))
1142
+ return {};
1143
+ try {
1144
+ return JSON.parse(readFileSync(p, "utf-8"));
1145
+ } catch {
1146
+ return {};
1147
+ }
1148
+ }
1149
+ function writeGlobalConfig(data) {
1150
+ const p = globalConfigPath();
1151
+ ensureDir2(dirname2(p));
1152
+ writeFileSync(p, JSON.stringify(data, null, 2), "utf-8");
1153
+ }
1154
+ function getActiveProfile() {
1155
+ const envProfile = process.env["MEMENTOS_PROFILE"];
1156
+ if (envProfile)
1157
+ return envProfile.trim();
1158
+ const cfg = readGlobalConfig();
1159
+ return cfg["active_profile"] || null;
1160
+ }
1161
+ function setActiveProfile(name) {
1162
+ const cfg = readGlobalConfig();
1163
+ if (name === null) {
1164
+ delete cfg["active_profile"];
1165
+ } else {
1166
+ cfg["active_profile"] = name;
1167
+ }
1168
+ writeGlobalConfig(cfg);
1169
+ }
1170
+ function listProfiles() {
1171
+ const dir = profilesDir();
1172
+ if (!existsSync2(dir))
1173
+ return [];
1174
+ return readdirSync(dir).filter((f) => f.endsWith(".db")).map((f) => basename(f, ".db")).sort();
1175
+ }
1176
+ function deleteProfile(name) {
1177
+ const dbPath = join2(profilesDir(), `${name}.db`);
1178
+ if (!existsSync2(dbPath))
1179
+ return false;
1180
+ unlinkSync(dbPath);
1181
+ if (getActiveProfile() === name)
1182
+ setActiveProfile(null);
1183
+ return true;
1184
+ }
1185
+ function ensureDir2(dir) {
1186
+ if (!existsSync2(dir)) {
1187
+ mkdirSync2(dir, { recursive: true });
1188
+ }
1189
+ }
1121
1190
 
1122
1191
  // src/db/memories.ts
1123
1192
  function runEntityExtraction(memory, projectId, d) {
@@ -1281,6 +1350,26 @@ function getMemoryByKey(key, scope, agentId, projectId, sessionId, db) {
1281
1350
  return null;
1282
1351
  return parseMemoryRow(row);
1283
1352
  }
1353
+ function getMemoriesByKey(key, scope, agentId, projectId, db) {
1354
+ const d = db || getDatabase();
1355
+ let sql = "SELECT * FROM memories WHERE key = ?";
1356
+ const params = [key];
1357
+ if (scope) {
1358
+ sql += " AND scope = ?";
1359
+ params.push(scope);
1360
+ }
1361
+ if (agentId) {
1362
+ sql += " AND agent_id = ?";
1363
+ params.push(agentId);
1364
+ }
1365
+ if (projectId) {
1366
+ sql += " AND project_id = ?";
1367
+ params.push(projectId);
1368
+ }
1369
+ sql += " AND status = 'active' ORDER BY importance DESC";
1370
+ const rows = d.query(sql).all(...params);
1371
+ return rows.map(parseMemoryRow);
1372
+ }
1284
1373
  function listMemories(filter, db) {
1285
1374
  const d = db || getDatabase();
1286
1375
  const conditions = [];
@@ -1491,6 +1580,28 @@ function cleanExpiredMemories(db) {
1491
1580
  }
1492
1581
  return count;
1493
1582
  }
1583
+ function getMemoryVersions(memoryId, db) {
1584
+ const d = db || getDatabase();
1585
+ try {
1586
+ const rows = d.query("SELECT * FROM memory_versions WHERE memory_id = ? ORDER BY version ASC").all(memoryId);
1587
+ return rows.map((row) => ({
1588
+ id: row["id"],
1589
+ memory_id: row["memory_id"],
1590
+ version: row["version"],
1591
+ value: row["value"],
1592
+ importance: row["importance"],
1593
+ scope: row["scope"],
1594
+ category: row["category"],
1595
+ tags: JSON.parse(row["tags"] || "[]"),
1596
+ summary: row["summary"] || null,
1597
+ pinned: !!row["pinned"],
1598
+ status: row["status"],
1599
+ created_at: row["created_at"]
1600
+ }));
1601
+ } catch {
1602
+ return [];
1603
+ }
1604
+ }
1494
1605
  // src/lib/search.ts
1495
1606
  function parseMemoryRow2(row) {
1496
1607
  return {
@@ -2376,8 +2487,10 @@ export {
2376
2487
  updateAgent,
2377
2488
  unlinkEntityFromMemory,
2378
2489
  touchMemory,
2490
+ touchAgent,
2379
2491
  syncMemories,
2380
2492
  shortUuid,
2493
+ setActiveProfile,
2381
2494
  searchMemories,
2382
2495
  runCleanup,
2383
2496
  resolvePartialId,
@@ -2392,16 +2505,20 @@ export {
2392
2505
  loadConfig,
2393
2506
  listRelations,
2394
2507
  listProjects,
2508
+ listProfiles,
2395
2509
  listMemories,
2396
2510
  listEntities,
2511
+ listAgentsByProject,
2397
2512
  listAgents,
2398
2513
  linkEntityToMemory,
2399
2514
  getRelation,
2400
2515
  getRelatedEntities,
2401
2516
  getProject,
2517
+ getMemoryVersions,
2402
2518
  getMemoryByKey,
2403
2519
  getMemory,
2404
2520
  getMemoriesForEntity,
2521
+ getMemoriesByKey,
2405
2522
  getEntityMemoryLinks,
2406
2523
  getEntityGraph,
2407
2524
  getEntityByName,
@@ -2410,11 +2527,13 @@ export {
2410
2527
  getDbPath,
2411
2528
  getDatabase,
2412
2529
  getAgent,
2530
+ getActiveProfile,
2413
2531
  findPath,
2414
2532
  extractEntities,
2415
2533
  enforceQuotas,
2416
2534
  deprioritizeStale,
2417
2535
  deleteRelation,
2536
+ deleteProfile,
2418
2537
  deleteMemory,
2419
2538
  deleteEntity,
2420
2539
  defaultSyncAgents,
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":";AACA;;;GAGG;AAkkCH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CA2G9C"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":";AACA;;;GAGG;AAkkCH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAkH9C"}
@@ -3,7 +3,7 @@
3
3
 
4
4
  // src/server/index.ts
5
5
  import { existsSync as existsSync3 } from "fs";
6
- import { dirname as dirname3, extname, join as join3 } from "path";
6
+ import { dirname as dirname3, extname, join as join3, resolve as resolve3, sep } from "path";
7
7
  import { fileURLToPath } from "url";
8
8
 
9
9
  // src/types/index.ts
@@ -2832,8 +2832,10 @@ async function findFreePort(start) {
2832
2832
  return start;
2833
2833
  }
2834
2834
  function startServer(port) {
2835
+ const hostname = process.env["MEMENTOS_HOST"] ?? "127.0.0.1";
2835
2836
  Bun.serve({
2836
2837
  port,
2838
+ hostname,
2837
2839
  async fetch(req) {
2838
2840
  const url = new URL(req.url);
2839
2841
  const { pathname } = url;
@@ -2842,7 +2844,7 @@ function startServer(port) {
2842
2844
  }
2843
2845
  if (pathname === "/api/health" || pathname === "/health") {
2844
2846
  const profile = getActiveProfile();
2845
- return json({ status: "ok", version: "0.1.0", profile: profile ?? "default", db_path: getDbPath2() });
2847
+ return json({ status: "ok", version: "0.1.0", profile: profile ?? "default", db_path: getDbPath2(), hostname });
2846
2848
  }
2847
2849
  if (pathname === "/api/profile" && req.method === "GET") {
2848
2850
  const profile = getActiveProfile();
@@ -2892,9 +2894,13 @@ function startServer(port) {
2892
2894
  const dashDir = resolveDashboardDir();
2893
2895
  if (existsSync3(dashDir) && (req.method === "GET" || req.method === "HEAD")) {
2894
2896
  if (pathname !== "/") {
2895
- const staticRes = serveStaticFile(join3(dashDir, pathname));
2896
- if (staticRes)
2897
- return staticRes;
2897
+ const resolvedDash = resolve3(dashDir) + sep;
2898
+ const requestedPath = resolve3(join3(dashDir, pathname));
2899
+ if (requestedPath.startsWith(resolvedDash)) {
2900
+ const staticRes = serveStaticFile(requestedPath);
2901
+ if (staticRes)
2902
+ return staticRes;
2903
+ }
2898
2904
  }
2899
2905
  const indexRes = serveStaticFile(join3(dashDir, "index.html"));
2900
2906
  if (indexRes)
@@ -2911,7 +2917,7 @@ function startServer(port) {
2911
2917
  }
2912
2918
  }
2913
2919
  });
2914
- console.log(`Mementos server listening on http://localhost:${port}`);
2920
+ console.log(`Mementos server listening on http://${hostname}:${port}`);
2915
2921
  }
2916
2922
  async function main() {
2917
2923
  const requestedPort = parsePort();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/mementos",
3
- "version": "0.4.10",
3
+ "version": "0.4.12",
4
4
  "description": "Universal memory system for AI agents - CLI + MCP server + library API",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",