@membank/cli 0.13.0 → 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.
Files changed (2) hide show
  1. package/dist/index.mjs +79 -6
  2. 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.delete(id);
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("global");
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 !== "global" && !/^[0-9a-f]{16}$/.test(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 !== "global" ? projectRepo.getByHash(s.scope) : void 0)?.name ?? 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.13.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/core": "0.11.0",
25
- "@membank/mcp": "0.14.0"
24
+ "@membank/core": "0.12.0",
25
+ "@membank/mcp": "0.14.2"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@types/node": "^25.6.0",