@hasna/mementos 0.1.1 → 0.1.2
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 +412 -91
- package/dist/db/agents.d.ts +6 -0
- package/dist/db/agents.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +26 -0
- package/dist/lib/poll.d.ts +17 -0
- package/dist/lib/poll.d.ts.map +1 -0
- package/dist/mcp/index.js +54 -0
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -4,6 +4,7 @@ var __create = Object.create;
|
|
|
4
4
|
var __getProtoOf = Object.getPrototypeOf;
|
|
5
5
|
var __defProp = Object.defineProperty;
|
|
6
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
7
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
9
|
var __toESM = (mod, isNodeMode, target) => {
|
|
9
10
|
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
@@ -16,7 +17,31 @@ var __toESM = (mod, isNodeMode, target) => {
|
|
|
16
17
|
});
|
|
17
18
|
return to;
|
|
18
19
|
};
|
|
20
|
+
var __moduleCache = /* @__PURE__ */ new WeakMap;
|
|
21
|
+
var __toCommonJS = (from) => {
|
|
22
|
+
var entry = __moduleCache.get(from), desc;
|
|
23
|
+
if (entry)
|
|
24
|
+
return entry;
|
|
25
|
+
entry = __defProp({}, "__esModule", { value: true });
|
|
26
|
+
if (from && typeof from === "object" || typeof from === "function")
|
|
27
|
+
__getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
|
|
28
|
+
get: () => from[key],
|
|
29
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
30
|
+
}));
|
|
31
|
+
__moduleCache.set(from, entry);
|
|
32
|
+
return entry;
|
|
33
|
+
};
|
|
19
34
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
35
|
+
var __export = (target, all) => {
|
|
36
|
+
for (var name in all)
|
|
37
|
+
__defProp(target, name, {
|
|
38
|
+
get: all[name],
|
|
39
|
+
enumerable: true,
|
|
40
|
+
configurable: true,
|
|
41
|
+
set: (newValue) => all[name] = () => newValue
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
20
45
|
var __require = import.meta.require;
|
|
21
46
|
|
|
22
47
|
// node_modules/commander/lib/error.js
|
|
@@ -2053,28 +2078,6 @@ var require_commander = __commonJS((exports) => {
|
|
|
2053
2078
|
exports.InvalidOptionArgumentError = InvalidArgumentError;
|
|
2054
2079
|
});
|
|
2055
2080
|
|
|
2056
|
-
// node_modules/commander/esm.mjs
|
|
2057
|
-
var import__ = __toESM(require_commander(), 1);
|
|
2058
|
-
var {
|
|
2059
|
-
program,
|
|
2060
|
-
createCommand,
|
|
2061
|
-
createArgument,
|
|
2062
|
-
createOption,
|
|
2063
|
-
CommanderError,
|
|
2064
|
-
InvalidArgumentError,
|
|
2065
|
-
InvalidOptionArgumentError,
|
|
2066
|
-
Command,
|
|
2067
|
-
Argument,
|
|
2068
|
-
Option,
|
|
2069
|
-
Help
|
|
2070
|
-
} = import__.default;
|
|
2071
|
-
|
|
2072
|
-
// src/cli/index.tsx
|
|
2073
|
-
import chalk from "chalk";
|
|
2074
|
-
import { readFileSync as readFileSync2 } from "fs";
|
|
2075
|
-
import { dirname as dirname3, join as join3, resolve as resolve3 } from "path";
|
|
2076
|
-
import { fileURLToPath } from "url";
|
|
2077
|
-
|
|
2078
2081
|
// src/db/database.ts
|
|
2079
2082
|
import { Database } from "bun:sqlite";
|
|
2080
2083
|
import { existsSync, mkdirSync } from "fs";
|
|
@@ -2132,8 +2135,59 @@ function ensureDir(filePath) {
|
|
|
2132
2135
|
mkdirSync(dir, { recursive: true });
|
|
2133
2136
|
}
|
|
2134
2137
|
}
|
|
2135
|
-
|
|
2136
|
-
|
|
2138
|
+
function getDatabase(dbPath) {
|
|
2139
|
+
if (_db)
|
|
2140
|
+
return _db;
|
|
2141
|
+
const path = dbPath || getDbPath();
|
|
2142
|
+
ensureDir(path);
|
|
2143
|
+
_db = new Database(path, { create: true });
|
|
2144
|
+
_db.run("PRAGMA journal_mode = WAL");
|
|
2145
|
+
_db.run("PRAGMA busy_timeout = 5000");
|
|
2146
|
+
_db.run("PRAGMA foreign_keys = ON");
|
|
2147
|
+
runMigrations(_db);
|
|
2148
|
+
return _db;
|
|
2149
|
+
}
|
|
2150
|
+
function runMigrations(db) {
|
|
2151
|
+
try {
|
|
2152
|
+
const result = db.query("SELECT MAX(id) as max_id FROM _migrations").get();
|
|
2153
|
+
const currentLevel = result?.max_id ?? 0;
|
|
2154
|
+
for (let i = currentLevel;i < MIGRATIONS.length; i++) {
|
|
2155
|
+
try {
|
|
2156
|
+
db.exec(MIGRATIONS[i]);
|
|
2157
|
+
} catch {}
|
|
2158
|
+
}
|
|
2159
|
+
} catch {
|
|
2160
|
+
for (const migration of MIGRATIONS) {
|
|
2161
|
+
try {
|
|
2162
|
+
db.exec(migration);
|
|
2163
|
+
} catch {}
|
|
2164
|
+
}
|
|
2165
|
+
}
|
|
2166
|
+
}
|
|
2167
|
+
function now() {
|
|
2168
|
+
return new Date().toISOString();
|
|
2169
|
+
}
|
|
2170
|
+
function uuid() {
|
|
2171
|
+
return crypto.randomUUID();
|
|
2172
|
+
}
|
|
2173
|
+
function shortUuid() {
|
|
2174
|
+
return crypto.randomUUID().slice(0, 8);
|
|
2175
|
+
}
|
|
2176
|
+
function resolvePartialId(db, table, partialId) {
|
|
2177
|
+
if (partialId.length >= 36) {
|
|
2178
|
+
const row = db.query(`SELECT id FROM ${table} WHERE id = ?`).get(partialId);
|
|
2179
|
+
return row?.id ?? null;
|
|
2180
|
+
}
|
|
2181
|
+
const rows = db.query(`SELECT id FROM ${table} WHERE id LIKE ?`).all(`${partialId}%`);
|
|
2182
|
+
if (rows.length === 1) {
|
|
2183
|
+
return rows[0].id;
|
|
2184
|
+
}
|
|
2185
|
+
return null;
|
|
2186
|
+
}
|
|
2187
|
+
var MIGRATIONS, _db = null;
|
|
2188
|
+
var init_database = __esm(() => {
|
|
2189
|
+
MIGRATIONS = [
|
|
2190
|
+
`
|
|
2137
2191
|
CREATE TABLE IF NOT EXISTS projects (
|
|
2138
2192
|
id TEXT PRIMARY KEY,
|
|
2139
2193
|
name TEXT NOT NULL,
|
|
@@ -2220,75 +2274,29 @@ var MIGRATIONS = [
|
|
|
2220
2274
|
|
|
2221
2275
|
INSERT OR IGNORE INTO _migrations (id) VALUES (1);
|
|
2222
2276
|
`
|
|
2223
|
-
];
|
|
2224
|
-
|
|
2225
|
-
function getDatabase(dbPath) {
|
|
2226
|
-
if (_db)
|
|
2227
|
-
return _db;
|
|
2228
|
-
const path = dbPath || getDbPath();
|
|
2229
|
-
ensureDir(path);
|
|
2230
|
-
_db = new Database(path, { create: true });
|
|
2231
|
-
_db.run("PRAGMA journal_mode = WAL");
|
|
2232
|
-
_db.run("PRAGMA busy_timeout = 5000");
|
|
2233
|
-
_db.run("PRAGMA foreign_keys = ON");
|
|
2234
|
-
runMigrations(_db);
|
|
2235
|
-
return _db;
|
|
2236
|
-
}
|
|
2237
|
-
function runMigrations(db) {
|
|
2238
|
-
try {
|
|
2239
|
-
const result = db.query("SELECT MAX(id) as max_id FROM _migrations").get();
|
|
2240
|
-
const currentLevel = result?.max_id ?? 0;
|
|
2241
|
-
for (let i = currentLevel;i < MIGRATIONS.length; i++) {
|
|
2242
|
-
try {
|
|
2243
|
-
db.exec(MIGRATIONS[i]);
|
|
2244
|
-
} catch {}
|
|
2245
|
-
}
|
|
2246
|
-
} catch {
|
|
2247
|
-
for (const migration of MIGRATIONS) {
|
|
2248
|
-
try {
|
|
2249
|
-
db.exec(migration);
|
|
2250
|
-
} catch {}
|
|
2251
|
-
}
|
|
2252
|
-
}
|
|
2253
|
-
}
|
|
2254
|
-
function now() {
|
|
2255
|
-
return new Date().toISOString();
|
|
2256
|
-
}
|
|
2257
|
-
function uuid() {
|
|
2258
|
-
return crypto.randomUUID();
|
|
2259
|
-
}
|
|
2260
|
-
function shortUuid() {
|
|
2261
|
-
return crypto.randomUUID().slice(0, 8);
|
|
2262
|
-
}
|
|
2263
|
-
function resolvePartialId(db, table, partialId) {
|
|
2264
|
-
if (partialId.length >= 36) {
|
|
2265
|
-
const row = db.query(`SELECT id FROM ${table} WHERE id = ?`).get(partialId);
|
|
2266
|
-
return row?.id ?? null;
|
|
2267
|
-
}
|
|
2268
|
-
const rows = db.query(`SELECT id FROM ${table} WHERE id LIKE ?`).all(`${partialId}%`);
|
|
2269
|
-
if (rows.length === 1) {
|
|
2270
|
-
return rows[0].id;
|
|
2271
|
-
}
|
|
2272
|
-
return null;
|
|
2273
|
-
}
|
|
2277
|
+
];
|
|
2278
|
+
});
|
|
2274
2279
|
|
|
2275
2280
|
// src/types/index.ts
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2281
|
+
var MemoryNotFoundError, VersionConflictError;
|
|
2282
|
+
var init_types = __esm(() => {
|
|
2283
|
+
MemoryNotFoundError = class MemoryNotFoundError extends Error {
|
|
2284
|
+
constructor(id) {
|
|
2285
|
+
super(`Memory not found: ${id}`);
|
|
2286
|
+
this.name = "MemoryNotFoundError";
|
|
2287
|
+
}
|
|
2288
|
+
};
|
|
2289
|
+
VersionConflictError = class VersionConflictError extends Error {
|
|
2290
|
+
expected;
|
|
2291
|
+
actual;
|
|
2292
|
+
constructor(id, expected, actual) {
|
|
2293
|
+
super(`Version conflict for memory ${id}: expected ${expected}, got ${actual}`);
|
|
2294
|
+
this.name = "VersionConflictError";
|
|
2295
|
+
this.expected = expected;
|
|
2296
|
+
this.actual = actual;
|
|
2297
|
+
}
|
|
2298
|
+
};
|
|
2299
|
+
});
|
|
2292
2300
|
|
|
2293
2301
|
// src/db/memories.ts
|
|
2294
2302
|
function parseMemoryRow(row) {
|
|
@@ -2591,8 +2599,150 @@ function cleanExpiredMemories(db) {
|
|
|
2591
2599
|
const result = d.run("DELETE FROM memories WHERE expires_at IS NOT NULL AND expires_at < ?", [timestamp]);
|
|
2592
2600
|
return result.changes;
|
|
2593
2601
|
}
|
|
2602
|
+
var init_memories = __esm(() => {
|
|
2603
|
+
init_types();
|
|
2604
|
+
init_database();
|
|
2605
|
+
});
|
|
2606
|
+
|
|
2607
|
+
// src/lib/poll.ts
|
|
2608
|
+
var exports_poll = {};
|
|
2609
|
+
__export(exports_poll, {
|
|
2610
|
+
startPolling: () => startPolling
|
|
2611
|
+
});
|
|
2612
|
+
function startPolling(opts) {
|
|
2613
|
+
const interval = opts.interval_ms ?? 500;
|
|
2614
|
+
const db = opts.db ?? getDatabase();
|
|
2615
|
+
let stopped = false;
|
|
2616
|
+
let inFlight = false;
|
|
2617
|
+
let lastSeen = null;
|
|
2618
|
+
const seedLastSeen = () => {
|
|
2619
|
+
try {
|
|
2620
|
+
const latest = listMemories({
|
|
2621
|
+
scope: opts.scope,
|
|
2622
|
+
category: opts.category,
|
|
2623
|
+
agent_id: opts.agent_id,
|
|
2624
|
+
project_id: opts.project_id,
|
|
2625
|
+
limit: 1
|
|
2626
|
+
}, db);
|
|
2627
|
+
if (latest.length > 0 && latest[0]) {
|
|
2628
|
+
lastSeen = latest[0].updated_at;
|
|
2629
|
+
}
|
|
2630
|
+
} catch (err) {
|
|
2631
|
+
opts.on_error?.(err instanceof Error ? err : new Error(String(err)));
|
|
2632
|
+
}
|
|
2633
|
+
};
|
|
2634
|
+
const poll = () => {
|
|
2635
|
+
if (stopped || inFlight)
|
|
2636
|
+
return;
|
|
2637
|
+
inFlight = true;
|
|
2638
|
+
try {
|
|
2639
|
+
const conditions = ["status = 'active'"];
|
|
2640
|
+
const params = [];
|
|
2641
|
+
if (lastSeen) {
|
|
2642
|
+
conditions.push("(updated_at > ? OR created_at > ?)");
|
|
2643
|
+
params.push(lastSeen, lastSeen);
|
|
2644
|
+
}
|
|
2645
|
+
if (opts.scope) {
|
|
2646
|
+
conditions.push("scope = ?");
|
|
2647
|
+
params.push(opts.scope);
|
|
2648
|
+
}
|
|
2649
|
+
if (opts.category) {
|
|
2650
|
+
conditions.push("category = ?");
|
|
2651
|
+
params.push(opts.category);
|
|
2652
|
+
}
|
|
2653
|
+
if (opts.agent_id) {
|
|
2654
|
+
conditions.push("agent_id = ?");
|
|
2655
|
+
params.push(opts.agent_id);
|
|
2656
|
+
}
|
|
2657
|
+
if (opts.project_id) {
|
|
2658
|
+
conditions.push("project_id = ?");
|
|
2659
|
+
params.push(opts.project_id);
|
|
2660
|
+
}
|
|
2661
|
+
const sql = `SELECT * FROM memories WHERE ${conditions.join(" AND ")} ORDER BY updated_at ASC`;
|
|
2662
|
+
const rows = db.query(sql).all(...params);
|
|
2663
|
+
if (rows.length > 0) {
|
|
2664
|
+
const memories = rows.map(parseMemoryRow3);
|
|
2665
|
+
const lastRow = memories[memories.length - 1];
|
|
2666
|
+
if (lastRow) {
|
|
2667
|
+
lastSeen = lastRow.updated_at;
|
|
2668
|
+
}
|
|
2669
|
+
try {
|
|
2670
|
+
opts.on_memories(memories);
|
|
2671
|
+
} catch (err) {
|
|
2672
|
+
opts.on_error?.(err instanceof Error ? err : new Error(String(err)));
|
|
2673
|
+
}
|
|
2674
|
+
}
|
|
2675
|
+
} catch (err) {
|
|
2676
|
+
opts.on_error?.(err instanceof Error ? err : new Error(String(err)));
|
|
2677
|
+
} finally {
|
|
2678
|
+
inFlight = false;
|
|
2679
|
+
}
|
|
2680
|
+
};
|
|
2681
|
+
seedLastSeen();
|
|
2682
|
+
const timer = setInterval(poll, interval);
|
|
2683
|
+
return {
|
|
2684
|
+
stop: () => {
|
|
2685
|
+
stopped = true;
|
|
2686
|
+
clearInterval(timer);
|
|
2687
|
+
}
|
|
2688
|
+
};
|
|
2689
|
+
}
|
|
2690
|
+
function parseMemoryRow3(row) {
|
|
2691
|
+
return {
|
|
2692
|
+
id: row["id"],
|
|
2693
|
+
key: row["key"],
|
|
2694
|
+
value: row["value"],
|
|
2695
|
+
category: row["category"],
|
|
2696
|
+
scope: row["scope"],
|
|
2697
|
+
summary: row["summary"] || null,
|
|
2698
|
+
tags: JSON.parse(row["tags"] || "[]"),
|
|
2699
|
+
importance: row["importance"],
|
|
2700
|
+
source: row["source"],
|
|
2701
|
+
status: row["status"],
|
|
2702
|
+
pinned: !!row["pinned"],
|
|
2703
|
+
agent_id: row["agent_id"] || null,
|
|
2704
|
+
project_id: row["project_id"] || null,
|
|
2705
|
+
session_id: row["session_id"] || null,
|
|
2706
|
+
metadata: JSON.parse(row["metadata"] || "{}"),
|
|
2707
|
+
access_count: row["access_count"],
|
|
2708
|
+
version: row["version"],
|
|
2709
|
+
expires_at: row["expires_at"] || null,
|
|
2710
|
+
created_at: row["created_at"],
|
|
2711
|
+
updated_at: row["updated_at"],
|
|
2712
|
+
accessed_at: row["accessed_at"] || null
|
|
2713
|
+
};
|
|
2714
|
+
}
|
|
2715
|
+
var init_poll = __esm(() => {
|
|
2716
|
+
init_memories();
|
|
2717
|
+
init_database();
|
|
2718
|
+
});
|
|
2719
|
+
|
|
2720
|
+
// node_modules/commander/esm.mjs
|
|
2721
|
+
var import__ = __toESM(require_commander(), 1);
|
|
2722
|
+
var {
|
|
2723
|
+
program,
|
|
2724
|
+
createCommand,
|
|
2725
|
+
createArgument,
|
|
2726
|
+
createOption,
|
|
2727
|
+
CommanderError,
|
|
2728
|
+
InvalidArgumentError,
|
|
2729
|
+
InvalidOptionArgumentError,
|
|
2730
|
+
Command,
|
|
2731
|
+
Argument,
|
|
2732
|
+
Option,
|
|
2733
|
+
Help
|
|
2734
|
+
} = import__.default;
|
|
2735
|
+
|
|
2736
|
+
// src/cli/index.tsx
|
|
2737
|
+
init_database();
|
|
2738
|
+
init_memories();
|
|
2739
|
+
import chalk from "chalk";
|
|
2740
|
+
import { readFileSync as readFileSync2 } from "fs";
|
|
2741
|
+
import { dirname as dirname3, join as join3, resolve as resolve3 } from "path";
|
|
2742
|
+
import { fileURLToPath } from "url";
|
|
2594
2743
|
|
|
2595
2744
|
// src/db/agents.ts
|
|
2745
|
+
init_database();
|
|
2596
2746
|
function parseAgentRow(row) {
|
|
2597
2747
|
return {
|
|
2598
2748
|
id: row["id"],
|
|
@@ -2650,8 +2800,34 @@ function listAgents(db) {
|
|
|
2650
2800
|
const rows = d.query("SELECT * FROM agents ORDER BY last_seen_at DESC").all();
|
|
2651
2801
|
return rows.map(parseAgentRow);
|
|
2652
2802
|
}
|
|
2803
|
+
function updateAgent(id, updates, db) {
|
|
2804
|
+
const d = db || getDatabase();
|
|
2805
|
+
const agent = getAgent(id, d);
|
|
2806
|
+
if (!agent)
|
|
2807
|
+
return null;
|
|
2808
|
+
const timestamp = now();
|
|
2809
|
+
if (updates.name && updates.name !== agent.name) {
|
|
2810
|
+
const existing = d.query("SELECT id FROM agents WHERE name = ? AND id != ?").get(updates.name, agent.id);
|
|
2811
|
+
if (existing) {
|
|
2812
|
+
throw new Error(`Agent name already taken: ${updates.name}`);
|
|
2813
|
+
}
|
|
2814
|
+
d.run("UPDATE agents SET name = ? WHERE id = ?", [updates.name, agent.id]);
|
|
2815
|
+
}
|
|
2816
|
+
if (updates.description !== undefined) {
|
|
2817
|
+
d.run("UPDATE agents SET description = ? WHERE id = ?", [updates.description, agent.id]);
|
|
2818
|
+
}
|
|
2819
|
+
if (updates.role !== undefined) {
|
|
2820
|
+
d.run("UPDATE agents SET role = ? WHERE id = ?", [updates.role, agent.id]);
|
|
2821
|
+
}
|
|
2822
|
+
if (updates.metadata !== undefined) {
|
|
2823
|
+
d.run("UPDATE agents SET metadata = ? WHERE id = ?", [JSON.stringify(updates.metadata), agent.id]);
|
|
2824
|
+
}
|
|
2825
|
+
d.run("UPDATE agents SET last_seen_at = ? WHERE id = ?", [timestamp, agent.id]);
|
|
2826
|
+
return getAgent(agent.id, d);
|
|
2827
|
+
}
|
|
2653
2828
|
|
|
2654
2829
|
// src/db/projects.ts
|
|
2830
|
+
init_database();
|
|
2655
2831
|
function parseProjectRow(row) {
|
|
2656
2832
|
return {
|
|
2657
2833
|
id: row["id"],
|
|
@@ -2696,6 +2872,7 @@ function listProjects(db) {
|
|
|
2696
2872
|
}
|
|
2697
2873
|
|
|
2698
2874
|
// src/lib/search.ts
|
|
2875
|
+
init_database();
|
|
2699
2876
|
function parseMemoryRow2(row) {
|
|
2700
2877
|
return {
|
|
2701
2878
|
id: row["id"],
|
|
@@ -2929,6 +3106,8 @@ function loadConfig() {
|
|
|
2929
3106
|
}
|
|
2930
3107
|
|
|
2931
3108
|
// src/lib/retention.ts
|
|
3109
|
+
init_database();
|
|
3110
|
+
init_memories();
|
|
2932
3111
|
function enforceQuotas(config, db) {
|
|
2933
3112
|
const d = db || getDatabase();
|
|
2934
3113
|
let totalEvicted = 0;
|
|
@@ -3440,6 +3619,47 @@ program2.command("agents").description("List all registered agents").action(() =
|
|
|
3440
3619
|
handleError(e);
|
|
3441
3620
|
}
|
|
3442
3621
|
});
|
|
3622
|
+
program2.command("agent-update <id>").description("Update an agent's name, description, or role").option("--name <name>", "New agent name").option("-d, --description <text>", "New description").option("-r, --role <role>", "New role").action((id, opts) => {
|
|
3623
|
+
try {
|
|
3624
|
+
const globalOpts = program2.opts();
|
|
3625
|
+
const updates = {};
|
|
3626
|
+
if (opts.name !== undefined)
|
|
3627
|
+
updates.name = opts.name;
|
|
3628
|
+
if (opts.description !== undefined)
|
|
3629
|
+
updates.description = opts.description;
|
|
3630
|
+
if (opts.role !== undefined)
|
|
3631
|
+
updates.role = opts.role;
|
|
3632
|
+
if (Object.keys(updates).length === 0) {
|
|
3633
|
+
if (globalOpts.json) {
|
|
3634
|
+
outputJson({ error: "No updates provided. Use --name, --description, or --role." });
|
|
3635
|
+
} else {
|
|
3636
|
+
console.error(chalk.red("No updates provided. Use --name, --description, or --role."));
|
|
3637
|
+
}
|
|
3638
|
+
process.exit(1);
|
|
3639
|
+
}
|
|
3640
|
+
const agent = updateAgent(id, updates);
|
|
3641
|
+
if (!agent) {
|
|
3642
|
+
if (globalOpts.json) {
|
|
3643
|
+
outputJson({ error: `Agent not found: ${id}` });
|
|
3644
|
+
} else {
|
|
3645
|
+
console.error(chalk.red(`Agent not found: ${id}`));
|
|
3646
|
+
}
|
|
3647
|
+
process.exit(1);
|
|
3648
|
+
}
|
|
3649
|
+
if (globalOpts.json) {
|
|
3650
|
+
outputJson(agent);
|
|
3651
|
+
} else {
|
|
3652
|
+
console.log(chalk.green("Agent updated:"));
|
|
3653
|
+
console.log(` ${chalk.bold("ID:")} ${agent.id}`);
|
|
3654
|
+
console.log(` ${chalk.bold("Name:")} ${agent.name}`);
|
|
3655
|
+
console.log(` ${chalk.bold("Description:")} ${agent.description || "-"}`);
|
|
3656
|
+
console.log(` ${chalk.bold("Role:")} ${agent.role || "agent"}`);
|
|
3657
|
+
console.log(` ${chalk.bold("Last seen:")} ${agent.last_seen_at}`);
|
|
3658
|
+
}
|
|
3659
|
+
} catch (e) {
|
|
3660
|
+
handleError(e);
|
|
3661
|
+
}
|
|
3662
|
+
});
|
|
3443
3663
|
program2.command("projects").description("Manage projects").option("--add", "Add a new project").option("--name <name>", "Project name").option("--path <path>", "Project path").option("--description <text>", "Project description").action((opts) => {
|
|
3444
3664
|
try {
|
|
3445
3665
|
const globalOpts = program2.opts();
|
|
@@ -3717,4 +3937,105 @@ args = []
|
|
|
3717
3937
|
}
|
|
3718
3938
|
}
|
|
3719
3939
|
});
|
|
3940
|
+
program2.command("watch").description("Watch for new and changed memories in real-time").option("-s, --scope <scope>", "Scope filter: global, shared, private").option("-c, --category <cat>", "Category filter: preference, fact, knowledge, history").option("--agent <name>", "Agent filter").option("--project <path>", "Project filter").option("--interval <ms>", "Poll interval in milliseconds", parseInt).action((opts) => {
|
|
3941
|
+
try {
|
|
3942
|
+
const globalOpts = program2.opts();
|
|
3943
|
+
const agentId = opts.agent || globalOpts.agent;
|
|
3944
|
+
const projectPath = opts.project || globalOpts.project;
|
|
3945
|
+
let projectId;
|
|
3946
|
+
if (projectPath) {
|
|
3947
|
+
const project = getProject(resolve3(projectPath));
|
|
3948
|
+
if (project)
|
|
3949
|
+
projectId = project.id;
|
|
3950
|
+
}
|
|
3951
|
+
const intervalMs = opts.interval || 500;
|
|
3952
|
+
console.log(chalk.bold.cyan("Watching memories...") + chalk.dim(" (Ctrl+C to stop)"));
|
|
3953
|
+
const filters = [];
|
|
3954
|
+
if (opts.scope)
|
|
3955
|
+
filters.push(`scope=${colorScope(opts.scope)}`);
|
|
3956
|
+
if (opts.category)
|
|
3957
|
+
filters.push(`category=${colorCategory(opts.category)}`);
|
|
3958
|
+
if (agentId)
|
|
3959
|
+
filters.push(`agent=${chalk.dim(agentId)}`);
|
|
3960
|
+
if (projectId)
|
|
3961
|
+
filters.push(`project=${chalk.dim(projectId)}`);
|
|
3962
|
+
if (filters.length > 0) {
|
|
3963
|
+
console.log(chalk.dim("Filters: ") + filters.join(chalk.dim(" | ")));
|
|
3964
|
+
}
|
|
3965
|
+
console.log(chalk.dim(`Poll interval: ${intervalMs}ms`));
|
|
3966
|
+
console.log();
|
|
3967
|
+
const filter = {
|
|
3968
|
+
scope: opts.scope,
|
|
3969
|
+
category: opts.category,
|
|
3970
|
+
agent_id: agentId,
|
|
3971
|
+
project_id: projectId,
|
|
3972
|
+
limit: 20
|
|
3973
|
+
};
|
|
3974
|
+
const recent = listMemories(filter);
|
|
3975
|
+
if (recent.length > 0) {
|
|
3976
|
+
console.log(chalk.bold.dim(`Recent (${recent.length}):`));
|
|
3977
|
+
for (const m of recent.reverse()) {
|
|
3978
|
+
console.log(formatWatchLine(m));
|
|
3979
|
+
}
|
|
3980
|
+
} else {
|
|
3981
|
+
console.log(chalk.dim("No recent memories."));
|
|
3982
|
+
}
|
|
3983
|
+
console.log(chalk.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Live \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
3984
|
+
console.log();
|
|
3985
|
+
const { startPolling: startPolling2 } = (init_poll(), __toCommonJS(exports_poll));
|
|
3986
|
+
const handle = startPolling2({
|
|
3987
|
+
interval_ms: intervalMs,
|
|
3988
|
+
scope: opts.scope,
|
|
3989
|
+
category: opts.category,
|
|
3990
|
+
agent_id: agentId,
|
|
3991
|
+
project_id: projectId,
|
|
3992
|
+
on_memories: (memories) => {
|
|
3993
|
+
for (const m of memories) {
|
|
3994
|
+
console.log(formatWatchLine(m));
|
|
3995
|
+
sendNotification(m);
|
|
3996
|
+
}
|
|
3997
|
+
},
|
|
3998
|
+
on_error: (err) => {
|
|
3999
|
+
console.error(chalk.red(`Poll error: ${err.message}`));
|
|
4000
|
+
}
|
|
4001
|
+
});
|
|
4002
|
+
const cleanup = () => {
|
|
4003
|
+
handle.stop();
|
|
4004
|
+
console.log();
|
|
4005
|
+
console.log(chalk.dim("Stopped watching."));
|
|
4006
|
+
process.exit(0);
|
|
4007
|
+
};
|
|
4008
|
+
process.on("SIGINT", cleanup);
|
|
4009
|
+
process.on("SIGTERM", cleanup);
|
|
4010
|
+
} catch (e) {
|
|
4011
|
+
handleError(e);
|
|
4012
|
+
}
|
|
4013
|
+
});
|
|
4014
|
+
function formatWatchLine(m) {
|
|
4015
|
+
const scope = colorScope(m.scope);
|
|
4016
|
+
const cat = colorCategory(m.category);
|
|
4017
|
+
const imp = colorImportance(m.importance);
|
|
4018
|
+
const value = m.value.length > 100 ? m.value.slice(0, 100) + "..." : m.value;
|
|
4019
|
+
const main = ` [${scope}/${cat}] ${chalk.bold(m.key)} = ${value} ${chalk.dim(`(importance: ${imp})`)}`;
|
|
4020
|
+
const parts = [];
|
|
4021
|
+
if (m.tags.length > 0)
|
|
4022
|
+
parts.push(`Tags: ${m.tags.join(", ")}`);
|
|
4023
|
+
if (m.agent_id)
|
|
4024
|
+
parts.push(`Agent: ${m.agent_id}`);
|
|
4025
|
+
parts.push(`Updated: ${m.updated_at}`);
|
|
4026
|
+
const detail = chalk.dim(` ${parts.join(" | ")}`);
|
|
4027
|
+
return `${main}
|
|
4028
|
+
${detail}`;
|
|
4029
|
+
}
|
|
4030
|
+
function sendNotification(m) {
|
|
4031
|
+
if (process.platform !== "darwin")
|
|
4032
|
+
return;
|
|
4033
|
+
try {
|
|
4034
|
+
const title = "Mementos";
|
|
4035
|
+
const msg = `[${m.scope}/${m.category}] ${m.key} = ${m.value.slice(0, 60)}`;
|
|
4036
|
+
const escaped = msg.replace(/"/g, "\\\"");
|
|
4037
|
+
const { execSync } = __require("child_process");
|
|
4038
|
+
execSync(`osascript -e 'display notification "${escaped}" with title "${title}"'`, { stdio: "ignore", timeout: 2000 });
|
|
4039
|
+
} catch {}
|
|
4040
|
+
}
|
|
3720
4041
|
program2.parse(process.argv);
|
package/dist/db/agents.d.ts
CHANGED
|
@@ -3,4 +3,10 @@ import type { Agent } from "../types/index.js";
|
|
|
3
3
|
export declare function registerAgent(name: string, description?: string, role?: string, db?: Database): Agent;
|
|
4
4
|
export declare function getAgent(idOrName: string, db?: Database): Agent | null;
|
|
5
5
|
export declare function listAgents(db?: Database): Agent[];
|
|
6
|
+
export declare function updateAgent(id: string, updates: {
|
|
7
|
+
name?: string;
|
|
8
|
+
description?: string;
|
|
9
|
+
role?: string;
|
|
10
|
+
metadata?: Record<string, unknown>;
|
|
11
|
+
}, db?: Database): Agent | null;
|
|
6
12
|
//# sourceMappingURL=agents.d.ts.map
|
package/dist/db/agents.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/db/agents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAe/C,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,WAAW,CAAC,EAAE,MAAM,EACpB,IAAI,CAAC,EAAE,MAAM,EACb,EAAE,CAAC,EAAE,QAAQ,GACZ,KAAK,CAqCP;AAED,wBAAgB,QAAQ,CACtB,QAAQ,EAAE,MAAM,EAChB,EAAE,CAAC,EAAE,QAAQ,GACZ,KAAK,GAAG,IAAI,CAsBd;AAED,wBAAgB,UAAU,CAAC,EAAE,CAAC,EAAE,QAAQ,GAAG,KAAK,EAAE,CAMjD"}
|
|
1
|
+
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/db/agents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAe/C,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,WAAW,CAAC,EAAE,MAAM,EACpB,IAAI,CAAC,EAAE,MAAM,EACb,EAAE,CAAC,EAAE,QAAQ,GACZ,KAAK,CAqCP;AAED,wBAAgB,QAAQ,CACtB,QAAQ,EAAE,MAAM,EAChB,EAAE,CAAC,EAAE,QAAQ,GACZ,KAAK,GAAG,IAAI,CAsBd;AAED,wBAAgB,UAAU,CAAC,EAAE,CAAC,EAAE,QAAQ,GAAG,KAAK,EAAE,CAMjD;AAED,wBAAgB,WAAW,CACzB,EAAE,EAAE,MAAM,EACV,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,EACnG,EAAE,CAAC,EAAE,QAAQ,GACZ,KAAK,GAAG,IAAI,CAkCd"}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ export type { Memory, MemoryWithRelations, MemoryScope, MemoryCategory, MemorySo
|
|
|
2
2
|
export { MemoryNotFoundError, DuplicateMemoryError, MemoryExpiredError, InvalidScopeError, VersionConflictError, } from "./types/index.js";
|
|
3
3
|
export { getDatabase, closeDatabase, resetDatabase, getDbPath, resolvePartialId, now, uuid, shortUuid, } from "./db/database.js";
|
|
4
4
|
export { createMemory, getMemory, getMemoryByKey, listMemories, updateMemory, deleteMemory, bulkDeleteMemories, touchMemory, cleanExpiredMemories, } from "./db/memories.js";
|
|
5
|
-
export { registerAgent, getAgent, listAgents, } from "./db/agents.js";
|
|
5
|
+
export { registerAgent, getAgent, listAgents, updateAgent, } from "./db/agents.js";
|
|
6
6
|
export { registerProject, getProject, listProjects, } from "./db/projects.js";
|
|
7
7
|
export { searchMemories } from "./lib/search.js";
|
|
8
8
|
export { loadConfig, DEFAULT_CONFIG } from "./lib/config.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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,GACnB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,iBAAiB,EACjB,oBAAoB,GACrB,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,
|
|
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,GACnB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,iBAAiB,EACjB,oBAAoB,GACrB,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,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAG7E,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -602,6 +602,31 @@ function listAgents(db) {
|
|
|
602
602
|
const rows = d.query("SELECT * FROM agents ORDER BY last_seen_at DESC").all();
|
|
603
603
|
return rows.map(parseAgentRow);
|
|
604
604
|
}
|
|
605
|
+
function updateAgent(id, updates, db) {
|
|
606
|
+
const d = db || getDatabase();
|
|
607
|
+
const agent = getAgent(id, d);
|
|
608
|
+
if (!agent)
|
|
609
|
+
return null;
|
|
610
|
+
const timestamp = now();
|
|
611
|
+
if (updates.name && updates.name !== agent.name) {
|
|
612
|
+
const existing = d.query("SELECT id FROM agents WHERE name = ? AND id != ?").get(updates.name, agent.id);
|
|
613
|
+
if (existing) {
|
|
614
|
+
throw new Error(`Agent name already taken: ${updates.name}`);
|
|
615
|
+
}
|
|
616
|
+
d.run("UPDATE agents SET name = ? WHERE id = ?", [updates.name, agent.id]);
|
|
617
|
+
}
|
|
618
|
+
if (updates.description !== undefined) {
|
|
619
|
+
d.run("UPDATE agents SET description = ? WHERE id = ?", [updates.description, agent.id]);
|
|
620
|
+
}
|
|
621
|
+
if (updates.role !== undefined) {
|
|
622
|
+
d.run("UPDATE agents SET role = ? WHERE id = ?", [updates.role, agent.id]);
|
|
623
|
+
}
|
|
624
|
+
if (updates.metadata !== undefined) {
|
|
625
|
+
d.run("UPDATE agents SET metadata = ? WHERE id = ?", [JSON.stringify(updates.metadata), agent.id]);
|
|
626
|
+
}
|
|
627
|
+
d.run("UPDATE agents SET last_seen_at = ? WHERE id = ?", [timestamp, agent.id]);
|
|
628
|
+
return getAgent(agent.id, d);
|
|
629
|
+
}
|
|
605
630
|
// src/db/projects.ts
|
|
606
631
|
function parseProjectRow(row) {
|
|
607
632
|
return {
|
|
@@ -1136,6 +1161,7 @@ var defaultSyncAgents = ["claude", "codex", "gemini"];
|
|
|
1136
1161
|
export {
|
|
1137
1162
|
uuid,
|
|
1138
1163
|
updateMemory,
|
|
1164
|
+
updateAgent,
|
|
1139
1165
|
touchMemory,
|
|
1140
1166
|
syncMemories,
|
|
1141
1167
|
shortUuid,
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Database } from "bun:sqlite";
|
|
2
|
+
import type { Memory, MemoryScope, MemoryCategory } from "../types/index.js";
|
|
3
|
+
export interface PollOptions {
|
|
4
|
+
interval_ms?: number;
|
|
5
|
+
scope?: MemoryScope;
|
|
6
|
+
category?: MemoryCategory;
|
|
7
|
+
agent_id?: string;
|
|
8
|
+
project_id?: string;
|
|
9
|
+
on_memories: (memories: Memory[]) => void;
|
|
10
|
+
on_error?: (error: Error) => void;
|
|
11
|
+
db?: Database;
|
|
12
|
+
}
|
|
13
|
+
export interface PollHandle {
|
|
14
|
+
stop: () => void;
|
|
15
|
+
}
|
|
16
|
+
export declare function startPolling(opts: PollOptions): PollHandle;
|
|
17
|
+
//# sourceMappingURL=poll.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"poll.d.ts","sourceRoot":"","sources":["../../src/lib/poll.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAQ7E,MAAM,WAAW,WAAW;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IAC1C,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAClC,EAAE,CAAC,EAAE,QAAQ,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,IAAI,CAAC;CAClB;AAMD,wBAAgB,YAAY,CAAC,IAAI,EAAE,WAAW,GAAG,UAAU,CA0F1D"}
|
package/dist/mcp/index.js
CHANGED
|
@@ -4577,6 +4577,31 @@ function listAgents(db) {
|
|
|
4577
4577
|
const rows = d.query("SELECT * FROM agents ORDER BY last_seen_at DESC").all();
|
|
4578
4578
|
return rows.map(parseAgentRow);
|
|
4579
4579
|
}
|
|
4580
|
+
function updateAgent(id, updates, db) {
|
|
4581
|
+
const d = db || getDatabase();
|
|
4582
|
+
const agent = getAgent(id, d);
|
|
4583
|
+
if (!agent)
|
|
4584
|
+
return null;
|
|
4585
|
+
const timestamp = now();
|
|
4586
|
+
if (updates.name && updates.name !== agent.name) {
|
|
4587
|
+
const existing = d.query("SELECT id FROM agents WHERE name = ? AND id != ?").get(updates.name, agent.id);
|
|
4588
|
+
if (existing) {
|
|
4589
|
+
throw new Error(`Agent name already taken: ${updates.name}`);
|
|
4590
|
+
}
|
|
4591
|
+
d.run("UPDATE agents SET name = ? WHERE id = ?", [updates.name, agent.id]);
|
|
4592
|
+
}
|
|
4593
|
+
if (updates.description !== undefined) {
|
|
4594
|
+
d.run("UPDATE agents SET description = ? WHERE id = ?", [updates.description, agent.id]);
|
|
4595
|
+
}
|
|
4596
|
+
if (updates.role !== undefined) {
|
|
4597
|
+
d.run("UPDATE agents SET role = ? WHERE id = ?", [updates.role, agent.id]);
|
|
4598
|
+
}
|
|
4599
|
+
if (updates.metadata !== undefined) {
|
|
4600
|
+
d.run("UPDATE agents SET metadata = ? WHERE id = ?", [JSON.stringify(updates.metadata), agent.id]);
|
|
4601
|
+
}
|
|
4602
|
+
d.run("UPDATE agents SET last_seen_at = ? WHERE id = ?", [timestamp, agent.id]);
|
|
4603
|
+
return getAgent(agent.id, d);
|
|
4604
|
+
}
|
|
4580
4605
|
|
|
4581
4606
|
// src/db/projects.ts
|
|
4582
4607
|
function parseProjectRow(row) {
|
|
@@ -5059,6 +5084,35 @@ Last seen: ${agent.last_seen_at}`
|
|
|
5059
5084
|
return { content: [{ type: "text", text: formatError(e) }], isError: true };
|
|
5060
5085
|
}
|
|
5061
5086
|
});
|
|
5087
|
+
server.tool("update_agent", "Update an agent's name, description, role, or metadata. Agents can update themselves.", {
|
|
5088
|
+
id: exports_external.string().describe("Agent ID or name"),
|
|
5089
|
+
name: exports_external.string().optional().describe("New agent name"),
|
|
5090
|
+
description: exports_external.string().optional().describe("New description"),
|
|
5091
|
+
role: exports_external.string().optional().describe("New role"),
|
|
5092
|
+
metadata: exports_external.record(exports_external.unknown()).optional().describe("Updated metadata")
|
|
5093
|
+
}, async (args) => {
|
|
5094
|
+
try {
|
|
5095
|
+
const { id, ...updates } = args;
|
|
5096
|
+
const agent = updateAgent(id, updates);
|
|
5097
|
+
if (!agent) {
|
|
5098
|
+
return { content: [{ type: "text", text: `Agent not found: ${id}` }] };
|
|
5099
|
+
}
|
|
5100
|
+
return {
|
|
5101
|
+
content: [{
|
|
5102
|
+
type: "text",
|
|
5103
|
+
text: `Agent updated:
|
|
5104
|
+
ID: ${agent.id}
|
|
5105
|
+
Name: ${agent.name}
|
|
5106
|
+
Description: ${agent.description || "-"}
|
|
5107
|
+
Role: ${agent.role || "agent"}
|
|
5108
|
+
Metadata: ${JSON.stringify(agent.metadata)}
|
|
5109
|
+
Last seen: ${agent.last_seen_at}`
|
|
5110
|
+
}]
|
|
5111
|
+
};
|
|
5112
|
+
} catch (e) {
|
|
5113
|
+
return { content: [{ type: "text", text: formatError(e) }], isError: true };
|
|
5114
|
+
}
|
|
5115
|
+
});
|
|
5062
5116
|
server.tool("register_project", "Register a project for memory scoping", {
|
|
5063
5117
|
name: exports_external.string().describe("Project name"),
|
|
5064
5118
|
path: exports_external.string().describe("Absolute path to project"),
|