@membank/cli 0.15.0 → 0.16.1
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 +309 -25
- 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 { 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";
|
|
3
|
+
import { ACTIVITY_EVENT_TYPE_VALUES, ActivityEventTypeSchema, DatabaseManager, EmbeddingService, GLOBAL_PROJECT_NAME, 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, revertMemory, revertSynthesis, 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";
|
|
@@ -9,6 +9,7 @@ import { z } from "zod";
|
|
|
9
9
|
import { existsSync, mkdirSync, mkdtempSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
10
10
|
import { homedir, tmpdir } from "node:os";
|
|
11
11
|
import { dirname, join } from "node:path";
|
|
12
|
+
import { diffLines } from "@membank/core/client";
|
|
12
13
|
import Table from "cli-table3";
|
|
13
14
|
import { execFile } from "node:child_process";
|
|
14
15
|
import { promisify } from "node:util";
|
|
@@ -43,8 +44,8 @@ async function activityCommand(options, formatter) {
|
|
|
43
44
|
}
|
|
44
45
|
const events = listEvents({
|
|
45
46
|
scope,
|
|
46
|
-
type: validatedType,
|
|
47
|
-
since: options.since,
|
|
47
|
+
...validatedType !== void 0 && { type: validatedType },
|
|
48
|
+
...options.since !== void 0 && { since: options.since },
|
|
48
49
|
limit: options.limit !== void 0 ? parseInt(options.limit, 10) : 50
|
|
49
50
|
}, activityRepo);
|
|
50
51
|
if (formatter.isJson) {
|
|
@@ -464,8 +465,8 @@ async function listCommand(options, formatter) {
|
|
|
464
465
|
const db = DatabaseManager.open();
|
|
465
466
|
try {
|
|
466
467
|
const memories = createMemoryRepository(db, createProjectRepository(db)).list({
|
|
467
|
-
|
|
468
|
-
pinned: options.pinned
|
|
468
|
+
...options.type !== void 0 && { type: MemoryTypeSchema$1.parse(options.type) },
|
|
469
|
+
...options.pinned !== void 0 && { pinned: options.pinned }
|
|
469
470
|
});
|
|
470
471
|
formatter.outputMemories(memories);
|
|
471
472
|
} finally {
|
|
@@ -473,6 +474,102 @@ async function listCommand(options, formatter) {
|
|
|
473
474
|
}
|
|
474
475
|
}
|
|
475
476
|
//#endregion
|
|
477
|
+
//#region src/commands/memory/diff.ts
|
|
478
|
+
function memoryDiffCommand(id, v1, v2, db, formatter) {
|
|
479
|
+
const repo = createMemoryRepository(db, createProjectRepository(db));
|
|
480
|
+
const version1 = repo.getVersion(id, v1);
|
|
481
|
+
if (version1 === void 0) {
|
|
482
|
+
formatter.error(`Version ${v1} not found for memory: ${id}`);
|
|
483
|
+
process.exit(1);
|
|
484
|
+
}
|
|
485
|
+
const version2 = repo.getVersion(id, v2);
|
|
486
|
+
if (version2 === void 0) {
|
|
487
|
+
formatter.error(`Version ${v2} not found for memory: ${id}`);
|
|
488
|
+
process.exit(1);
|
|
489
|
+
}
|
|
490
|
+
const diff = diffLines(version1.content, version2.content);
|
|
491
|
+
if (formatter.isJson) {
|
|
492
|
+
process.stdout.write(`${JSON.stringify(diff)}\n`);
|
|
493
|
+
return;
|
|
494
|
+
}
|
|
495
|
+
process.stdout.write(`--- version ${v1}\n+++ version ${v2}\n`);
|
|
496
|
+
for (const entry of diff) if (entry.kind === "added") process.stdout.write(chalk.green(`+ ${entry.line}\n`));
|
|
497
|
+
else if (entry.kind === "removed") process.stdout.write(chalk.red(`- ${entry.line}\n`));
|
|
498
|
+
else process.stdout.write(` ${entry.line}\n`);
|
|
499
|
+
}
|
|
500
|
+
//#endregion
|
|
501
|
+
//#region src/commands/memory/history.ts
|
|
502
|
+
function truncate$2(str, max) {
|
|
503
|
+
return str.length > max ? `${str.slice(0, max - 1)}…` : str;
|
|
504
|
+
}
|
|
505
|
+
function memoryHistoryCommand(id, db, formatter) {
|
|
506
|
+
const versions = createMemoryRepository(db, createProjectRepository(db)).listVersions(id);
|
|
507
|
+
if (versions.length === 0) {
|
|
508
|
+
formatter.error(`No version history found for memory: ${id}`);
|
|
509
|
+
process.exit(1);
|
|
510
|
+
}
|
|
511
|
+
if (formatter.isJson) {
|
|
512
|
+
process.stdout.write(`${JSON.stringify(versions)}\n`);
|
|
513
|
+
return;
|
|
514
|
+
}
|
|
515
|
+
const table = new Table({
|
|
516
|
+
head: [
|
|
517
|
+
chalk.bold("version"),
|
|
518
|
+
chalk.bold("created_at"),
|
|
519
|
+
chalk.bold("preview")
|
|
520
|
+
],
|
|
521
|
+
style: { head: [] }
|
|
522
|
+
});
|
|
523
|
+
for (const v of versions) table.push([
|
|
524
|
+
String(v.version),
|
|
525
|
+
v.createdAt,
|
|
526
|
+
truncate$2(v.content.replace(/\n/g, " "), 60)
|
|
527
|
+
]);
|
|
528
|
+
process.stdout.write(`${table.toString()}\n`);
|
|
529
|
+
}
|
|
530
|
+
//#endregion
|
|
531
|
+
//#region src/commands/memory/revert.ts
|
|
532
|
+
async function memoryRevertCommand(id, version, db, formatter, prompt) {
|
|
533
|
+
const repo = createMemoryRepository(db, createProjectRepository(db));
|
|
534
|
+
if (repo.findById(id) === void 0) {
|
|
535
|
+
formatter.error(`Memory not found: ${id}`);
|
|
536
|
+
process.exit(1);
|
|
537
|
+
}
|
|
538
|
+
if (repo.getVersion(id, version) === void 0) {
|
|
539
|
+
formatter.error(`Version ${version} not found for memory: ${id}`);
|
|
540
|
+
process.exit(1);
|
|
541
|
+
}
|
|
542
|
+
if (!await prompt.confirm(`Revert memory ${id} to version ${version}?`)) return;
|
|
543
|
+
await revertMemory(id, version, {
|
|
544
|
+
repo,
|
|
545
|
+
embedder: new EmbeddingService(),
|
|
546
|
+
activityLogger: createActivityLogger(db)
|
|
547
|
+
});
|
|
548
|
+
process.stdout.write(`${chalk.green("✓")} Reverted memory ${chalk.dim(id)} to version ${version}\n`);
|
|
549
|
+
}
|
|
550
|
+
//#endregion
|
|
551
|
+
//#region src/commands/memory/show.ts
|
|
552
|
+
function memoryShowCommand(id, db, formatter, opts) {
|
|
553
|
+
const repo = createMemoryRepository(db, createProjectRepository(db));
|
|
554
|
+
if (opts.version !== void 0) {
|
|
555
|
+
const v = repo.getVersion(id, opts.version);
|
|
556
|
+
if (v === void 0) {
|
|
557
|
+
formatter.error(`Version ${opts.version} not found for memory: ${id}`);
|
|
558
|
+
process.exit(1);
|
|
559
|
+
}
|
|
560
|
+
if (formatter.isJson) process.stdout.write(`${JSON.stringify(v)}\n`);
|
|
561
|
+
else process.stdout.write(`${v.content}\n`);
|
|
562
|
+
return;
|
|
563
|
+
}
|
|
564
|
+
const memory = repo.findById(id);
|
|
565
|
+
if (memory === void 0) {
|
|
566
|
+
formatter.error(`Memory not found: ${id}`);
|
|
567
|
+
process.exit(1);
|
|
568
|
+
}
|
|
569
|
+
if (formatter.isJson) process.stdout.write(`${JSON.stringify(memory)}\n`);
|
|
570
|
+
else process.stdout.write(`${memory.content}\n`);
|
|
571
|
+
}
|
|
572
|
+
//#endregion
|
|
476
573
|
//#region src/commands/migrate.ts
|
|
477
574
|
async function migrateCommand(mode, name, formatter) {
|
|
478
575
|
if (mode === "list") {
|
|
@@ -574,9 +671,85 @@ async function statsCommand(formatter) {
|
|
|
574
671
|
}
|
|
575
672
|
}
|
|
576
673
|
//#endregion
|
|
577
|
-
//#region src/commands/synthesize.ts
|
|
674
|
+
//#region src/commands/synthesize/resolve-scope.ts
|
|
675
|
+
function resolveScope(scope, db) {
|
|
676
|
+
if (scope === GLOBAL_PROJECT_NAME) return GLOBAL_SCOPE_HASH;
|
|
677
|
+
if (/^[0-9a-f]{16}$/.test(scope)) return scope;
|
|
678
|
+
const project = createProjectRepository(db).getByName(scope);
|
|
679
|
+
return project !== void 0 ? project.scopeHash : scope;
|
|
680
|
+
}
|
|
681
|
+
//#endregion
|
|
682
|
+
//#region src/commands/synthesize/diff.ts
|
|
683
|
+
function synthesizeDiffCommand(v1, v2, opts, formatter) {
|
|
684
|
+
const db = DatabaseManager.open();
|
|
685
|
+
try {
|
|
686
|
+
const scope = opts.scope ?? GLOBAL_PROJECT_NAME;
|
|
687
|
+
const resolvedScope = resolveScope(scope, db);
|
|
688
|
+
const repo = createSynthesisRepository(db);
|
|
689
|
+
const version1 = repo.getVersion(resolvedScope, v1);
|
|
690
|
+
if (version1 === void 0) {
|
|
691
|
+
formatter.error(`Version ${v1} not found for scope: ${scope}`);
|
|
692
|
+
process.exit(1);
|
|
693
|
+
}
|
|
694
|
+
const version2 = repo.getVersion(resolvedScope, v2);
|
|
695
|
+
if (version2 === void 0) {
|
|
696
|
+
formatter.error(`Version ${v2} not found for scope: ${scope}`);
|
|
697
|
+
process.exit(1);
|
|
698
|
+
}
|
|
699
|
+
const diff = diffLines(version1.content, version2.content);
|
|
700
|
+
if (formatter.isJson) {
|
|
701
|
+
process.stdout.write(`${JSON.stringify(diff)}\n`);
|
|
702
|
+
return;
|
|
703
|
+
}
|
|
704
|
+
process.stdout.write(`--- version ${v1}\n+++ version ${v2}\n`);
|
|
705
|
+
for (const entry of diff) if (entry.kind === "added") process.stdout.write(chalk.green(`+ ${entry.line}\n`));
|
|
706
|
+
else if (entry.kind === "removed") process.stdout.write(chalk.red(`- ${entry.line}\n`));
|
|
707
|
+
else process.stdout.write(` ${entry.line}\n`);
|
|
708
|
+
} finally {
|
|
709
|
+
db.close();
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
//#endregion
|
|
713
|
+
//#region src/commands/synthesize/history.ts
|
|
714
|
+
function truncate$1(str, max) {
|
|
715
|
+
return str.length > max ? `${str.slice(0, max - 1)}…` : str;
|
|
716
|
+
}
|
|
717
|
+
function synthesizeHistoryCommand(opts, formatter) {
|
|
718
|
+
const db = DatabaseManager.open();
|
|
719
|
+
try {
|
|
720
|
+
const scope = opts.scope ?? GLOBAL_PROJECT_NAME;
|
|
721
|
+
const resolvedScope = resolveScope(scope, db);
|
|
722
|
+
const versions = createSynthesisRepository(db).listVersions(resolvedScope);
|
|
723
|
+
if (versions.length === 0) {
|
|
724
|
+
formatter.error(`No version history found for scope: ${scope}`);
|
|
725
|
+
process.exit(1);
|
|
726
|
+
}
|
|
727
|
+
if (formatter.isJson) {
|
|
728
|
+
process.stdout.write(`${JSON.stringify(versions)}\n`);
|
|
729
|
+
return;
|
|
730
|
+
}
|
|
731
|
+
const table = new Table({
|
|
732
|
+
head: [
|
|
733
|
+
chalk.bold("version"),
|
|
734
|
+
chalk.bold("synthesized_at"),
|
|
735
|
+
chalk.bold("preview")
|
|
736
|
+
],
|
|
737
|
+
style: { head: [] }
|
|
738
|
+
});
|
|
739
|
+
for (const v of versions) table.push([
|
|
740
|
+
String(v.version),
|
|
741
|
+
new Date(v.synthesizedAt).toLocaleString(),
|
|
742
|
+
truncate$1(v.content.replace(/\n/g, " "), 60)
|
|
743
|
+
]);
|
|
744
|
+
process.stdout.write(`${table.toString()}\n`);
|
|
745
|
+
} finally {
|
|
746
|
+
db.close();
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
//#endregion
|
|
750
|
+
//#region src/commands/synthesize/index.ts
|
|
578
751
|
async function synthesizeRunCommand(opts, formatter) {
|
|
579
|
-
const scope = opts.scope ??
|
|
752
|
+
const scope = opts.scope ?? GLOBAL_PROJECT_NAME;
|
|
580
753
|
if (!formatter.isJson) process.stdout.write(`Running synthesis for scope: ${scope}\n`);
|
|
581
754
|
const content = await runSynthesis(scope);
|
|
582
755
|
if (formatter.isJson) process.stdout.write(`${JSON.stringify({
|
|
@@ -588,14 +761,26 @@ async function synthesizeRunCommand(opts, formatter) {
|
|
|
588
761
|
function synthesizeShowCommand(opts, formatter) {
|
|
589
762
|
const db = DatabaseManager.open();
|
|
590
763
|
try {
|
|
591
|
-
const scope = opts.scope ??
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
const
|
|
596
|
-
if (
|
|
764
|
+
const scope = opts.scope ?? GLOBAL_PROJECT_NAME;
|
|
765
|
+
const resolvedScope = resolveScope(scope, db);
|
|
766
|
+
const repo = createSynthesisRepository(db);
|
|
767
|
+
if (opts.version !== void 0) {
|
|
768
|
+
const version = repo.getVersion(resolvedScope, opts.version);
|
|
769
|
+
if (version === void 0) {
|
|
770
|
+
if (formatter.isJson) process.stdout.write(`${JSON.stringify(null)}\n`);
|
|
771
|
+
else process.stdout.write(`Version ${opts.version} not found for scope: ${scope}\n`);
|
|
772
|
+
return;
|
|
773
|
+
}
|
|
774
|
+
if (formatter.isJson) process.stdout.write(`${JSON.stringify(version)}\n`);
|
|
775
|
+
else {
|
|
776
|
+
process.stdout.write(`\nScope: ${resolvedScope} (version ${version.version})\n`);
|
|
777
|
+
process.stdout.write(`Synthesized: ${new Date(version.synthesizedAt).toLocaleString()}\n`);
|
|
778
|
+
process.stdout.write(`Archived: ${new Date(version.createdAt).toLocaleString()}\n`);
|
|
779
|
+
process.stdout.write(`\n${version.content}\n\n`);
|
|
780
|
+
}
|
|
781
|
+
return;
|
|
597
782
|
}
|
|
598
|
-
const synthesis =
|
|
783
|
+
const synthesis = repo.getSynthesis(resolvedScope);
|
|
599
784
|
if (synthesis === void 0) {
|
|
600
785
|
if (formatter.isJson) process.stdout.write(`${JSON.stringify(null)}\n`);
|
|
601
786
|
else process.stdout.write(`No synthesis found for scope: ${scope}\n`);
|
|
@@ -628,7 +813,7 @@ function synthesizeStatusCommand(formatter) {
|
|
|
628
813
|
}
|
|
629
814
|
process.stdout.write("\n");
|
|
630
815
|
for (const s of syntheses) {
|
|
631
|
-
const displayScope = (s.scope !== GLOBAL_SCOPE_HASH ? projectRepo.getByHash(s.scope) : void 0)?.name ?? (s.scope === GLOBAL_SCOPE_HASH ?
|
|
816
|
+
const displayScope = (s.scope !== GLOBAL_SCOPE_HASH ? projectRepo.getByHash(s.scope) : void 0)?.name ?? (s.scope === GLOBAL_SCOPE_HASH ? GLOBAL_PROJECT_NAME : s.scope);
|
|
632
817
|
const inFlight = s.inFlightSince !== null ? " [in-flight]" : "";
|
|
633
818
|
const synthesized = new Date(s.synthesizedAt).toLocaleString();
|
|
634
819
|
const expires = new Date(s.expiresAt).toLocaleString();
|
|
@@ -642,6 +827,25 @@ function synthesizeStatusCommand(formatter) {
|
|
|
642
827
|
}
|
|
643
828
|
}
|
|
644
829
|
//#endregion
|
|
830
|
+
//#region src/commands/synthesize/revert.ts
|
|
831
|
+
async function synthesizeRevertCommand(version, opts, formatter, prompt) {
|
|
832
|
+
const db = DatabaseManager.open();
|
|
833
|
+
try {
|
|
834
|
+
const scope = opts.scope ?? GLOBAL_PROJECT_NAME;
|
|
835
|
+
const resolvedScope = resolveScope(scope, db);
|
|
836
|
+
const repo = createSynthesisRepository(db);
|
|
837
|
+
if (repo.getVersion(resolvedScope, version) === void 0) {
|
|
838
|
+
formatter.error(`Version ${version} not found for scope: ${scope}`);
|
|
839
|
+
process.exit(1);
|
|
840
|
+
}
|
|
841
|
+
if (!await prompt.confirm(`Revert synthesis for scope "${scope}" to version ${version}?`)) return;
|
|
842
|
+
revertSynthesis(resolvedScope, version, repo);
|
|
843
|
+
process.stdout.write(`${chalk.green("✓")} Reverted synthesis for scope ${chalk.dim(scope)} to version ${version}\n`);
|
|
844
|
+
} finally {
|
|
845
|
+
db.close();
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
//#endregion
|
|
645
849
|
//#region src/commands/unpin.ts
|
|
646
850
|
function unpinCommand(id, db) {
|
|
647
851
|
const ownDb = db === void 0;
|
|
@@ -1741,9 +1945,9 @@ program.command("inject").description("output session context for harness inject
|
|
|
1741
1945
|
program.command("extract").description("(internal) run session-end memory extraction; reads the harness's SessionEnd hook payload from stdin").option("--harness <name>", "harness whose session-end hook payload is on stdin (only claude-code is supported today)", "claude-code").option("--session <id>", "session id (otherwise read from stdin)").option("--transcript <path>", "transcript JSONL path (otherwise read from stdin)").action(async (cmdOptions) => {
|
|
1742
1946
|
try {
|
|
1743
1947
|
await extractCommand({
|
|
1744
|
-
harness: cmdOptions.harness,
|
|
1745
|
-
sessionId: cmdOptions.session,
|
|
1746
|
-
transcript: cmdOptions.transcript
|
|
1948
|
+
...cmdOptions.harness !== void 0 && { harness: cmdOptions.harness },
|
|
1949
|
+
...cmdOptions.session !== void 0 && { sessionId: cmdOptions.session },
|
|
1950
|
+
...cmdOptions.transcript !== void 0 && { transcript: cmdOptions.transcript }
|
|
1747
1951
|
});
|
|
1748
1952
|
} catch (err) {
|
|
1749
1953
|
process.stderr.write(`${err instanceof Error ? err.message : String(err)}\n`);
|
|
@@ -1825,16 +2029,16 @@ setupCmd.action(async (cmdOptions) => {
|
|
|
1825
2029
|
writer,
|
|
1826
2030
|
hookWriter,
|
|
1827
2031
|
prompter: (question) => promptHelper.confirm(question),
|
|
1828
|
-
harnessSelector,
|
|
2032
|
+
...harnessSelector !== void 0 && { harnessSelector },
|
|
1829
2033
|
modelDownloader: new ModelDownloader(),
|
|
1830
|
-
|
|
2034
|
+
...!formatter.isJson && { out: decoratedOut },
|
|
1831
2035
|
synthesisOptIn: true
|
|
1832
2036
|
});
|
|
1833
2037
|
try {
|
|
1834
2038
|
const results = await orchestrator.run({
|
|
1835
2039
|
yes: autoYes,
|
|
1836
|
-
dryRun: cmdOptions.dryRun,
|
|
1837
|
-
harness: cmdOptions.harness,
|
|
2040
|
+
...cmdOptions.dryRun !== void 0 && { dryRun: cmdOptions.dryRun },
|
|
2041
|
+
...cmdOptions.harness !== void 0 && { harness: cmdOptions.harness },
|
|
1838
2042
|
json: formatter.isJson
|
|
1839
2043
|
});
|
|
1840
2044
|
if (!formatter.isJson && !cmdOptions.dryRun && results.length > 0) {
|
|
@@ -1900,11 +2104,14 @@ synthesizeCmd.command("run").description("trigger a synthesis run for a scope").
|
|
|
1900
2104
|
process.exit(2);
|
|
1901
2105
|
}
|
|
1902
2106
|
});
|
|
1903
|
-
synthesizeCmd.command("show").description("display current synthesis for a scope").option("--scope <scope>", "scope to show (default: global)").action((cmdOptions) => {
|
|
2107
|
+
synthesizeCmd.command("show").description("display current synthesis for a scope, or a specific archived version").option("--scope <scope>", "scope to show (default: global)").option("--version <n>", "show this archived version number instead of the active synthesis").action((cmdOptions) => {
|
|
1904
2108
|
const globalOpts = program.opts();
|
|
1905
2109
|
const formatter = Formatter.create(globalOpts.json === true);
|
|
1906
2110
|
try {
|
|
1907
|
-
synthesizeShowCommand(
|
|
2111
|
+
synthesizeShowCommand({
|
|
2112
|
+
...cmdOptions.scope !== void 0 && { scope: cmdOptions.scope },
|
|
2113
|
+
...cmdOptions.version !== void 0 && { version: Number(cmdOptions.version) }
|
|
2114
|
+
}, formatter);
|
|
1908
2115
|
} catch (err) {
|
|
1909
2116
|
formatter.error(err instanceof Error ? err.message : String(err));
|
|
1910
2117
|
process.exit(2);
|
|
@@ -1920,13 +2127,90 @@ synthesizeCmd.command("status").description("show all scopes with synthesis stat
|
|
|
1920
2127
|
process.exit(2);
|
|
1921
2128
|
}
|
|
1922
2129
|
});
|
|
2130
|
+
synthesizeCmd.command("history").description("list archived synthesis versions for a scope").option("--scope <scope>", "scope to list history for (default: global)").action((cmdOptions) => {
|
|
2131
|
+
const globalOpts = program.opts();
|
|
2132
|
+
const formatter = Formatter.create(globalOpts.json === true);
|
|
2133
|
+
try {
|
|
2134
|
+
synthesizeHistoryCommand(cmdOptions, formatter);
|
|
2135
|
+
} catch (err) {
|
|
2136
|
+
formatter.error(err instanceof Error ? err.message : String(err));
|
|
2137
|
+
process.exit(2);
|
|
2138
|
+
}
|
|
2139
|
+
});
|
|
2140
|
+
synthesizeCmd.command("diff <v1> <v2>").description("show a line diff between two archived synthesis versions").option("--scope <scope>", "scope to diff (default: global)").action((v1, v2, cmdOptions) => {
|
|
2141
|
+
const globalOpts = program.opts();
|
|
2142
|
+
const formatter = Formatter.create(globalOpts.json === true);
|
|
2143
|
+
try {
|
|
2144
|
+
synthesizeDiffCommand(Number(v1), Number(v2), cmdOptions, formatter);
|
|
2145
|
+
} catch (err) {
|
|
2146
|
+
formatter.error(err instanceof Error ? err.message : String(err));
|
|
2147
|
+
process.exit(2);
|
|
2148
|
+
}
|
|
2149
|
+
});
|
|
2150
|
+
synthesizeCmd.command("revert <version>").description("revert the active synthesis to a previous archived version (records a new version)").option("--scope <scope>", "scope to revert (default: global)").action(async (version, cmdOptions) => {
|
|
2151
|
+
const globalOpts = program.opts();
|
|
2152
|
+
const formatter = Formatter.create(globalOpts.json === true);
|
|
2153
|
+
const prompt = new PromptHelper(globalOpts.yes === true);
|
|
2154
|
+
try {
|
|
2155
|
+
await synthesizeRevertCommand(Number(version), cmdOptions, formatter, prompt);
|
|
2156
|
+
} catch (err) {
|
|
2157
|
+
formatter.error(err instanceof Error ? err.message : String(err));
|
|
2158
|
+
process.exit(2);
|
|
2159
|
+
}
|
|
2160
|
+
});
|
|
2161
|
+
const memoryCmd = program.command("memory").description("view and manage memory version history");
|
|
2162
|
+
memoryCmd.command("history <id>").description("list version history for a memory").action((id) => {
|
|
2163
|
+
const globalOpts = program.opts();
|
|
2164
|
+
const formatter = Formatter.create(globalOpts.json === true);
|
|
2165
|
+
const db = DatabaseManager.open();
|
|
2166
|
+
try {
|
|
2167
|
+
memoryHistoryCommand(id, db, formatter);
|
|
2168
|
+
} catch (err) {
|
|
2169
|
+
formatter.error(err instanceof Error ? err.message : String(err));
|
|
2170
|
+
process.exit(2);
|
|
2171
|
+
}
|
|
2172
|
+
});
|
|
2173
|
+
memoryCmd.command("show <id>").description("show content of a memory, optionally at a specific version").option("--version <n>", "show this version number instead of current content").action((id, cmdOptions) => {
|
|
2174
|
+
const globalOpts = program.opts();
|
|
2175
|
+
const formatter = Formatter.create(globalOpts.json === true);
|
|
2176
|
+
const db = DatabaseManager.open();
|
|
2177
|
+
try {
|
|
2178
|
+
memoryShowCommand(id, db, formatter, { ...cmdOptions.version !== void 0 && { version: Number(cmdOptions.version) } });
|
|
2179
|
+
} catch (err) {
|
|
2180
|
+
formatter.error(err instanceof Error ? err.message : String(err));
|
|
2181
|
+
process.exit(2);
|
|
2182
|
+
}
|
|
2183
|
+
});
|
|
2184
|
+
memoryCmd.command("diff <id> <v1> <v2>").description("show a line diff between two versions of a memory").action((id, v1, v2) => {
|
|
2185
|
+
const globalOpts = program.opts();
|
|
2186
|
+
const formatter = Formatter.create(globalOpts.json === true);
|
|
2187
|
+
const db = DatabaseManager.open();
|
|
2188
|
+
try {
|
|
2189
|
+
memoryDiffCommand(id, Number(v1), Number(v2), db, formatter);
|
|
2190
|
+
} catch (err) {
|
|
2191
|
+
formatter.error(err instanceof Error ? err.message : String(err));
|
|
2192
|
+
process.exit(2);
|
|
2193
|
+
}
|
|
2194
|
+
});
|
|
2195
|
+
memoryCmd.command("revert <id> <version>").description("revert a memory to a previous version (records the revert as a new version)").action(async (id, version) => {
|
|
2196
|
+
const globalOpts = program.opts();
|
|
2197
|
+
const formatter = Formatter.create(globalOpts.json === true);
|
|
2198
|
+
const db = DatabaseManager.open();
|
|
2199
|
+
const prompt = new PromptHelper(globalOpts.yes === true);
|
|
2200
|
+
try {
|
|
2201
|
+
await memoryRevertCommand(id, Number(version), db, formatter, prompt);
|
|
2202
|
+
} catch (err) {
|
|
2203
|
+
formatter.error(err instanceof Error ? err.message : String(err));
|
|
2204
|
+
process.exit(2);
|
|
2205
|
+
}
|
|
2206
|
+
});
|
|
1923
2207
|
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) => {
|
|
1924
2208
|
const globalOpts = program.opts();
|
|
1925
2209
|
const formatter = Formatter.create(globalOpts.json === true);
|
|
1926
2210
|
try {
|
|
1927
2211
|
await activityCommand({
|
|
1928
2212
|
...cmdOptions,
|
|
1929
|
-
json: globalOpts.json
|
|
2213
|
+
...globalOpts.json !== void 0 && { json: globalOpts.json }
|
|
1930
2214
|
}, formatter);
|
|
1931
2215
|
} catch (err) {
|
|
1932
2216
|
formatter.error(err instanceof Error ? err.message : String(err));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@membank/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.1",
|
|
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.
|
|
25
|
-
"@membank/mcp": "0.
|
|
24
|
+
"@membank/core": "0.14.1",
|
|
25
|
+
"@membank/mcp": "0.16.1"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@types/node": "^25.6.0",
|