@membank/cli 0.13.1 → 0.14.0
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.mjs +79 -6
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { cancel, confirm, intro, isCancel, multiselect, note, outro } from "@clack/prompts";
|
|
3
|
-
import { DatabaseManager, EmbeddingService, MIGRATIONS, MODEL_NAME, MemoryTypeSchema, MemoryTypeSchema as MemoryTypeSchema$1, ModelDownloader, PIN_BUDGET_THRESHOLD, QueryEngine, SessionContextBuilder, createMemoryRepository, createProjectRepository, createSynthesisRepository, resolveProject, runScopeToProjectsMigration, saveMemory } from "@membank/core";
|
|
3
|
+
import { ACTIVITY_EVENT_TYPE_VALUES, ActivityEventTypeSchema, DatabaseManager, EmbeddingService, GLOBAL_SCOPE_HASH, MIGRATIONS, MODEL_NAME, MemoryTypeSchema, MemoryTypeSchema as MemoryTypeSchema$1, ModelDownloader, PIN_BUDGET_THRESHOLD, QueryEngine, SessionContextBuilder, createActivityLogger, createActivityRepository, createMemoryRepository, createProjectRepository, createSynthesisRepository, deleteMemory, listEvents, resolveProject, runScopeToProjectsMigration, saveMemory } from "@membank/core";
|
|
4
4
|
import { runExtraction, runSynthesis, startServer } from "@membank/mcp";
|
|
5
5
|
import chalk from "chalk";
|
|
6
6
|
import { Command } from "commander";
|
|
@@ -13,6 +13,63 @@ import Table from "cli-table3";
|
|
|
13
13
|
import { execFile } from "node:child_process";
|
|
14
14
|
import { promisify } from "node:util";
|
|
15
15
|
import { createInterface } from "node:readline";
|
|
16
|
+
//#region src/commands/activity.ts
|
|
17
|
+
const EVENT_COLORS = {
|
|
18
|
+
"memory.created": chalk.green,
|
|
19
|
+
"memory.updated": chalk.cyan,
|
|
20
|
+
"memory.deleted": chalk.red,
|
|
21
|
+
"memory.flagged": chalk.yellow,
|
|
22
|
+
"memory.queried": chalk.dim
|
|
23
|
+
};
|
|
24
|
+
function formatEvent(event) {
|
|
25
|
+
return ` ${(EVENT_COLORS[event.eventType] ?? chalk.white)(event.eventType.padEnd(16))} ${new Date(event.createdAt).toLocaleTimeString()}${event.memoryId !== null ? chalk.dim(` [${event.memoryId.slice(0, 8)}]`) : ""}`;
|
|
26
|
+
}
|
|
27
|
+
async function activityCommand(options, formatter) {
|
|
28
|
+
const db = DatabaseManager.open();
|
|
29
|
+
try {
|
|
30
|
+
const activityRepo = createActivityRepository(db);
|
|
31
|
+
let scope;
|
|
32
|
+
if (options.scope !== void 0) scope = options.scope;
|
|
33
|
+
else if (options.global === true) scope = GLOBAL_SCOPE_HASH;
|
|
34
|
+
else scope = (await resolveProject()).hash;
|
|
35
|
+
let validatedType;
|
|
36
|
+
if (options.type !== void 0) {
|
|
37
|
+
const parsed = ActivityEventTypeSchema.safeParse(options.type);
|
|
38
|
+
if (!parsed.success) {
|
|
39
|
+
formatter.error(`Invalid event type: "${options.type}". Valid values: ${ACTIVITY_EVENT_TYPE_VALUES.join(", ")}`);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
validatedType = parsed.data;
|
|
43
|
+
}
|
|
44
|
+
const events = listEvents({
|
|
45
|
+
scope,
|
|
46
|
+
type: validatedType,
|
|
47
|
+
since: options.since,
|
|
48
|
+
limit: options.limit !== void 0 ? parseInt(options.limit, 10) : 50
|
|
49
|
+
}, activityRepo);
|
|
50
|
+
if (formatter.isJson) {
|
|
51
|
+
process.stdout.write(`${JSON.stringify(events)}\n`);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
if (events.length === 0) {
|
|
55
|
+
process.stdout.write(chalk.dim(" No activity found.\n"));
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
let lastDay = "";
|
|
59
|
+
for (const event of events) {
|
|
60
|
+
const day = event.createdAt.slice(0, 10);
|
|
61
|
+
if (day !== lastDay) {
|
|
62
|
+
lastDay = day;
|
|
63
|
+
process.stdout.write(`\n${chalk.bold(day)}\n`);
|
|
64
|
+
}
|
|
65
|
+
process.stdout.write(`${formatEvent(event)}\n`);
|
|
66
|
+
}
|
|
67
|
+
process.stdout.write("\n");
|
|
68
|
+
} finally {
|
|
69
|
+
db.close();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
//#endregion
|
|
16
73
|
//#region src/schemas.ts
|
|
17
74
|
const SETUP_HARNESS_VALUES = [
|
|
18
75
|
"claude-code",
|
|
@@ -59,6 +116,7 @@ async function addCommand(content, options, formatter, db, embeddingService) {
|
|
|
59
116
|
try {
|
|
60
117
|
const embedder = embeddingService ?? new EmbeddingService();
|
|
61
118
|
const repo = createMemoryRepository(resolvedDb, createProjectRepository(resolvedDb));
|
|
119
|
+
const activityLogger = createActivityLogger(resolvedDb);
|
|
62
120
|
const tags = options.tags !== void 0 ? options.tags.split(",").map((t) => t.trim()) : [];
|
|
63
121
|
const projectScope = options.global ? void 0 : await resolveProject();
|
|
64
122
|
const spinner = formatter.isJson ? null : ora("Saving memory…").start();
|
|
@@ -69,7 +127,8 @@ async function addCommand(content, options, formatter, db, embeddingService) {
|
|
|
69
127
|
projectScope
|
|
70
128
|
}, {
|
|
71
129
|
repo,
|
|
72
|
-
embedder
|
|
130
|
+
embedder,
|
|
131
|
+
activityLogger
|
|
73
132
|
});
|
|
74
133
|
spinner?.succeed("Memory saved");
|
|
75
134
|
formatter.outputMemory(memory);
|
|
@@ -160,7 +219,7 @@ async function deleteCommand(id, db, formatter, prompt) {
|
|
|
160
219
|
process.exit(1);
|
|
161
220
|
}
|
|
162
221
|
if (!await prompt.confirm(`Delete memory ${id}?`)) return;
|
|
163
|
-
repo
|
|
222
|
+
await deleteMemory(id, repo, createActivityLogger(db));
|
|
164
223
|
process.stdout.write(`${chalk.green("✓")} Deleted memory: ${chalk.dim(id)}\n`);
|
|
165
224
|
}
|
|
166
225
|
//#endregion
|
|
@@ -370,7 +429,7 @@ async function buildText() {
|
|
|
370
429
|
try {
|
|
371
430
|
const builder = new SessionContextBuilder(createMemoryRepository(db, createProjectRepository(db)));
|
|
372
431
|
const synthRepo = createSynthesisRepository(db);
|
|
373
|
-
const globalRow = synthRepo.getSynthesis(
|
|
432
|
+
const globalRow = synthRepo.getSynthesis(GLOBAL_SCOPE_HASH);
|
|
374
433
|
const projectRow = synthRepo.getSynthesis(resolved.hash);
|
|
375
434
|
const synthesis = pickBestSynthesis(globalRow?.inFlightSince === null ? globalRow.content : void 0, projectRow?.inFlightSince === null ? projectRow.content : void 0);
|
|
376
435
|
return formatContext(builder.getSessionContext(resolved.hash, synthesis));
|
|
@@ -532,7 +591,8 @@ function synthesizeShowCommand(opts, formatter) {
|
|
|
532
591
|
try {
|
|
533
592
|
const scope = opts.scope ?? "global";
|
|
534
593
|
let resolvedScope = scope;
|
|
535
|
-
if (scope
|
|
594
|
+
if (scope === "global") resolvedScope = GLOBAL_SCOPE_HASH;
|
|
595
|
+
else if (!/^[0-9a-f]{16}$/.test(scope)) {
|
|
536
596
|
const project = createProjectRepository(db).getByName(scope);
|
|
537
597
|
if (project !== void 0) resolvedScope = project.scopeHash;
|
|
538
598
|
}
|
|
@@ -569,7 +629,7 @@ function synthesizeStatusCommand(formatter) {
|
|
|
569
629
|
}
|
|
570
630
|
process.stdout.write("\n");
|
|
571
631
|
for (const s of syntheses) {
|
|
572
|
-
const displayScope = (s.scope !==
|
|
632
|
+
const displayScope = (s.scope !== GLOBAL_SCOPE_HASH ? projectRepo.getByHash(s.scope) : void 0)?.name ?? (s.scope === GLOBAL_SCOPE_HASH ? "global" : s.scope);
|
|
573
633
|
const inFlight = s.inFlightSince !== null ? " [in-flight]" : "";
|
|
574
634
|
const synthesized = new Date(s.synthesizedAt).toLocaleString();
|
|
575
635
|
const expires = new Date(s.expiresAt).toLocaleString();
|
|
@@ -1876,6 +1936,19 @@ synthesizeCmd.command("status").description("show all scopes with synthesis stat
|
|
|
1876
1936
|
process.exit(2);
|
|
1877
1937
|
}
|
|
1878
1938
|
});
|
|
1939
|
+
program.command("activity").description("list activity events for the current project (or --global for global memories)").option("--type <event_type>", "filter by event type (memory.created|updated|deleted|flagged|queried)").option("--since <date>", "return events after this ISO date/time").option("--memory-id <id>", "filter by memory id").option("--limit <n>", "maximum number of results (default 50)").option("--global", "show activity for global (sentinel) project").option("--scope <hash>", "show activity for a specific scope hash (advanced)").action(async (cmdOptions) => {
|
|
1940
|
+
const globalOpts = program.opts();
|
|
1941
|
+
const formatter = Formatter.create(globalOpts.json === true);
|
|
1942
|
+
try {
|
|
1943
|
+
await activityCommand({
|
|
1944
|
+
...cmdOptions,
|
|
1945
|
+
json: globalOpts.json
|
|
1946
|
+
}, formatter);
|
|
1947
|
+
} catch (err) {
|
|
1948
|
+
formatter.error(err instanceof Error ? err.message : String(err));
|
|
1949
|
+
process.exit(2);
|
|
1950
|
+
}
|
|
1951
|
+
});
|
|
1879
1952
|
program.on("command:*", () => {
|
|
1880
1953
|
program.outputHelp();
|
|
1881
1954
|
process.exit(1);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@membank/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"commander": "^14.0.3",
|
|
22
22
|
"ora": "^9.4.0",
|
|
23
23
|
"zod": "^4.4.3",
|
|
24
|
-
"@membank/
|
|
25
|
-
"@membank/
|
|
24
|
+
"@membank/core": "0.12.0",
|
|
25
|
+
"@membank/mcp": "0.14.2"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@types/node": "^25.6.0",
|