@membank/cli 0.16.1 → 0.17.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 +202 -168
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -4,17 +4,180 @@ import { ACTIVITY_EVENT_TYPE_VALUES, ActivityEventTypeSchema, DatabaseManager, E
|
|
|
4
4
|
import { runExtraction, runSynthesis, startServer } from "@membank/mcp";
|
|
5
5
|
import chalk from "chalk";
|
|
6
6
|
import { Command } from "commander";
|
|
7
|
+
import Table from "cli-table3";
|
|
7
8
|
import ora from "ora";
|
|
8
9
|
import { z } from "zod";
|
|
9
10
|
import { existsSync, mkdirSync, mkdtempSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
10
11
|
import { homedir, tmpdir } from "node:os";
|
|
11
12
|
import { dirname, join } from "node:path";
|
|
12
13
|
import { diffLines } from "@membank/core/client";
|
|
13
|
-
import Table from "cli-table3";
|
|
14
14
|
import { execFile } from "node:child_process";
|
|
15
15
|
import { promisify } from "node:util";
|
|
16
16
|
import { createInterface } from "node:readline";
|
|
17
|
+
//#region src/formatter.ts
|
|
18
|
+
const TYPE_COLORS = {
|
|
19
|
+
correction: chalk.yellow,
|
|
20
|
+
preference: chalk.cyan,
|
|
21
|
+
decision: chalk.blue,
|
|
22
|
+
learning: chalk.green,
|
|
23
|
+
fact: chalk.dim
|
|
24
|
+
};
|
|
25
|
+
function colorType(type) {
|
|
26
|
+
return TYPE_COLORS[type](type);
|
|
27
|
+
}
|
|
28
|
+
function statsRow(label, value, warn) {
|
|
29
|
+
if (warn) process.stdout.write(` ${chalk.yellow("⚠")} ${label.padEnd(12)} ${value}\n`);
|
|
30
|
+
else process.stdout.write(` ${" ".concat(label).padEnd(14)} ${value}\n`);
|
|
31
|
+
}
|
|
32
|
+
function truncate$2(str, max) {
|
|
33
|
+
return str.length > max ? `${str.slice(0, max - 1)}…` : str;
|
|
34
|
+
}
|
|
35
|
+
var Formatter = class Formatter {
|
|
36
|
+
#isJson;
|
|
37
|
+
constructor(isJson) {
|
|
38
|
+
this.#isJson = isJson;
|
|
39
|
+
}
|
|
40
|
+
static create(forceJson = false) {
|
|
41
|
+
return new Formatter(forceJson || !process.stdout.isTTY);
|
|
42
|
+
}
|
|
43
|
+
get isJson() {
|
|
44
|
+
return this.#isJson;
|
|
45
|
+
}
|
|
46
|
+
outputMemory(memory) {
|
|
47
|
+
if (this.#isJson) {
|
|
48
|
+
process.stdout.write(`${JSON.stringify(memory)}\n`);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const tags = memory.tags.length > 0 ? memory.tags.join(", ") : "(none)";
|
|
52
|
+
process.stdout.write("\n");
|
|
53
|
+
process.stdout.write(` ${colorType(memory.type)} ${chalk.dim(memory.id)}\n`);
|
|
54
|
+
process.stdout.write(` ${memory.content}\n`);
|
|
55
|
+
const scope = memory.projects.length > 0 ? memory.projects.map((p) => p.name).join(", ") : "global";
|
|
56
|
+
process.stdout.write(` ${chalk.dim("Tags:")} ${tags} ${chalk.dim("Project:")} ${scope}\n`);
|
|
57
|
+
process.stdout.write(`\n ${chalk.dim(`Hint: pin with membank pin ${memory.id}`)}\n\n`);
|
|
58
|
+
}
|
|
59
|
+
outputMemories(memories) {
|
|
60
|
+
if (this.#isJson) {
|
|
61
|
+
process.stdout.write(`${JSON.stringify(memories)}\n`);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
if (memories.length === 0) {
|
|
65
|
+
process.stdout.write(`${chalk.dim("No memories found.")}\n`);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const table = new Table({
|
|
69
|
+
head: [
|
|
70
|
+
"Type",
|
|
71
|
+
"ID",
|
|
72
|
+
"Content",
|
|
73
|
+
"Pinned"
|
|
74
|
+
].map((h) => chalk.bold(h)),
|
|
75
|
+
style: {
|
|
76
|
+
head: [],
|
|
77
|
+
border: []
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
for (const m of memories) {
|
|
81
|
+
const tags = m.tags.length > 0 ? m.tags.join(", ") : "(none)";
|
|
82
|
+
const mScope = m.projects.length > 0 ? m.projects.map((p) => p.name).join(", ") : "global";
|
|
83
|
+
const meta = `${truncate$2(m.content, 45)}\n${chalk.dim(`${tags} · ${mScope}`)}`;
|
|
84
|
+
table.push([
|
|
85
|
+
colorType(m.type),
|
|
86
|
+
chalk.dim(m.id),
|
|
87
|
+
meta,
|
|
88
|
+
m.pinned ? "📌" : ""
|
|
89
|
+
]);
|
|
90
|
+
}
|
|
91
|
+
process.stdout.write(`\n${table.toString()}\n\n`);
|
|
92
|
+
}
|
|
93
|
+
outputStats(stats) {
|
|
94
|
+
if (this.#isJson) {
|
|
95
|
+
process.stdout.write(`${JSON.stringify(stats)}\n`);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const types = [
|
|
99
|
+
"correction",
|
|
100
|
+
"preference",
|
|
101
|
+
"decision",
|
|
102
|
+
"learning",
|
|
103
|
+
"fact"
|
|
104
|
+
];
|
|
105
|
+
process.stdout.write("\n");
|
|
106
|
+
for (const type of types) process.stdout.write(` ${TYPE_COLORS[type](type.padEnd(14))} ${stats.byType[type]}\n`);
|
|
107
|
+
process.stdout.write(`\n ${chalk.dim("─".repeat(24))}\n`);
|
|
108
|
+
process.stdout.write(` ${"total".padEnd(14)} ${stats.total}\n`);
|
|
109
|
+
statsRow("needs_review", String(stats.needsReview), stats.needsReview > 0);
|
|
110
|
+
statsRow("pin_budget", `${stats.pinBudgetChars} / ${PIN_BUDGET_THRESHOLD} chars`, stats.pinBudgetChars > PIN_BUDGET_THRESHOLD);
|
|
111
|
+
process.stdout.write("\n");
|
|
112
|
+
}
|
|
113
|
+
outputQueryResults(results) {
|
|
114
|
+
if (this.#isJson) {
|
|
115
|
+
process.stdout.write(`${JSON.stringify(results)}\n`);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
if (results.length === 0) {
|
|
119
|
+
process.stdout.write(`${chalk.dim("No memories found.")}\n`);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
const table = new Table({
|
|
123
|
+
head: [
|
|
124
|
+
"Type",
|
|
125
|
+
"ID",
|
|
126
|
+
"Content",
|
|
127
|
+
"Score"
|
|
128
|
+
].map((h) => chalk.bold(h)),
|
|
129
|
+
style: {
|
|
130
|
+
head: [],
|
|
131
|
+
border: []
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
for (const r of results) {
|
|
135
|
+
const scoreStr = r.score.toFixed(4);
|
|
136
|
+
const score = r.score >= .85 ? chalk.bold(scoreStr) : r.score < .75 ? chalk.dim(scoreStr) : scoreStr;
|
|
137
|
+
const tags = r.tags.length > 0 ? r.tags.join(", ") : "(none)";
|
|
138
|
+
const rScope = r.projects.length > 0 ? r.projects.map((p) => p.name).join(", ") : "global";
|
|
139
|
+
const meta = `${truncate$2(r.content, 45)}\n${chalk.dim(`${tags} · ${rScope}`)}`;
|
|
140
|
+
table.push([
|
|
141
|
+
colorType(r.type),
|
|
142
|
+
chalk.dim(r.id),
|
|
143
|
+
meta,
|
|
144
|
+
score
|
|
145
|
+
]);
|
|
146
|
+
}
|
|
147
|
+
process.stdout.write(`\n${table.toString()}\n\n`);
|
|
148
|
+
}
|
|
149
|
+
outputReview(memories) {
|
|
150
|
+
if (this.#isJson) {
|
|
151
|
+
process.stdout.write(`${JSON.stringify(memories)}\n`);
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
if (memories.length === 0) {
|
|
155
|
+
process.stdout.write(`${chalk.dim("No memories flagged for review.")}\n`);
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
for (const m of memories) {
|
|
159
|
+
process.stdout.write("\n");
|
|
160
|
+
process.stdout.write(` ${colorType(m.type)} ${chalk.dim(m.id)}\n`);
|
|
161
|
+
process.stdout.write(` ${truncate$2(m.content, 80)}\n`);
|
|
162
|
+
for (const event of m.reviewEvents) this.#outputReviewEvent(event);
|
|
163
|
+
}
|
|
164
|
+
process.stdout.write("\n");
|
|
165
|
+
}
|
|
166
|
+
#outputReviewEvent(event) {
|
|
167
|
+
const pct = `${Math.round(event.similarity * 100)}%`;
|
|
168
|
+
const conflictRef = event.conflictingMemoryId ? chalk.dim(event.conflictingMemoryId) : chalk.dim("(deleted)");
|
|
169
|
+
const ts = new Date(event.createdAt).toLocaleString();
|
|
170
|
+
process.stdout.write(` ${chalk.yellow("⚠")} ${pct} similarity conflict: ${conflictRef} ${chalk.dim(ts)}\n`);
|
|
171
|
+
if (event.conflictContentSnapshot) process.stdout.write(` ${chalk.dim("snapshot:")} ${truncate$2(event.conflictContentSnapshot, 60)}\n`);
|
|
172
|
+
}
|
|
173
|
+
error(msg) {
|
|
174
|
+
if (this.#isJson) process.stderr.write(`${JSON.stringify({ error: msg })}\n`);
|
|
175
|
+
else process.stderr.write(`${chalk.red("Error:")} ${msg}\n`);
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
//#endregion
|
|
17
179
|
//#region src/commands/activity.ts
|
|
180
|
+
const SNIPPET_LENGTH = 120;
|
|
18
181
|
const EVENT_COLORS = {
|
|
19
182
|
"memory.created": chalk.green,
|
|
20
183
|
"memory.updated": chalk.cyan,
|
|
@@ -22,8 +185,41 @@ const EVENT_COLORS = {
|
|
|
22
185
|
"memory.flagged": chalk.yellow,
|
|
23
186
|
"memory.queried": chalk.dim
|
|
24
187
|
};
|
|
188
|
+
function formatEventDetail(event) {
|
|
189
|
+
const p = event.payload;
|
|
190
|
+
const getString = (key) => typeof p[key] === "string" ? p[key] : void 0;
|
|
191
|
+
const getNumber = (key) => typeof p[key] === "number" ? p[key] : void 0;
|
|
192
|
+
switch (event.eventType) {
|
|
193
|
+
case "memory.created":
|
|
194
|
+
case "memory.updated": {
|
|
195
|
+
const snippet = getString("contentSnapshot");
|
|
196
|
+
if (snippet === void 0) return null;
|
|
197
|
+
return chalk.dim(` ${truncate$2(snippet, SNIPPET_LENGTH).replace(/\n/g, " ↵ ")}`);
|
|
198
|
+
}
|
|
199
|
+
case "memory.deleted": {
|
|
200
|
+
const snippet = getString("contentSnapshot");
|
|
201
|
+
if (snippet === void 0) return null;
|
|
202
|
+
return chalk.dim(` (deleted) ${truncate$2(snippet, SNIPPET_LENGTH).replace(/\n/g, " ↵ ")}`);
|
|
203
|
+
}
|
|
204
|
+
case "memory.queried": {
|
|
205
|
+
const query = getString("query");
|
|
206
|
+
if (query === void 0) return null;
|
|
207
|
+
return chalk.dim(` "${truncate$2(query, SNIPPET_LENGTH)}"`);
|
|
208
|
+
}
|
|
209
|
+
case "memory.flagged": {
|
|
210
|
+
const sim = getNumber("similarity");
|
|
211
|
+
const conflictId = getString("conflictingMemoryId");
|
|
212
|
+
if (sim === void 0) return null;
|
|
213
|
+
const pct = `${Math.round(sim * 100)}% similar`;
|
|
214
|
+
const conflict = conflictId !== void 0 ? ` · conflict: ${conflictId.slice(0, 8)}` : "";
|
|
215
|
+
return chalk.dim(` ${pct}${conflict}`);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
25
219
|
function formatEvent(event) {
|
|
26
|
-
|
|
220
|
+
const header = ` ${(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)}]`) : ""}`;
|
|
221
|
+
const detail = formatEventDetail(event);
|
|
222
|
+
return detail !== null ? `${header}\n${detail}` : header;
|
|
27
223
|
}
|
|
28
224
|
async function activityCommand(options, formatter) {
|
|
29
225
|
const db = DatabaseManager.open();
|
|
@@ -499,7 +695,7 @@ function memoryDiffCommand(id, v1, v2, db, formatter) {
|
|
|
499
695
|
}
|
|
500
696
|
//#endregion
|
|
501
697
|
//#region src/commands/memory/history.ts
|
|
502
|
-
function truncate$
|
|
698
|
+
function truncate$1(str, max) {
|
|
503
699
|
return str.length > max ? `${str.slice(0, max - 1)}…` : str;
|
|
504
700
|
}
|
|
505
701
|
function memoryHistoryCommand(id, db, formatter) {
|
|
@@ -523,7 +719,7 @@ function memoryHistoryCommand(id, db, formatter) {
|
|
|
523
719
|
for (const v of versions) table.push([
|
|
524
720
|
String(v.version),
|
|
525
721
|
v.createdAt,
|
|
526
|
-
truncate$
|
|
722
|
+
truncate$1(v.content.replace(/\n/g, " "), 60)
|
|
527
723
|
]);
|
|
528
724
|
process.stdout.write(`${table.toString()}\n`);
|
|
529
725
|
}
|
|
@@ -711,7 +907,7 @@ function synthesizeDiffCommand(v1, v2, opts, formatter) {
|
|
|
711
907
|
}
|
|
712
908
|
//#endregion
|
|
713
909
|
//#region src/commands/synthesize/history.ts
|
|
714
|
-
function truncate
|
|
910
|
+
function truncate(str, max) {
|
|
715
911
|
return str.length > max ? `${str.slice(0, max - 1)}…` : str;
|
|
716
912
|
}
|
|
717
913
|
function synthesizeHistoryCommand(opts, formatter) {
|
|
@@ -739,7 +935,7 @@ function synthesizeHistoryCommand(opts, formatter) {
|
|
|
739
935
|
for (const v of versions) table.push([
|
|
740
936
|
String(v.version),
|
|
741
937
|
new Date(v.synthesizedAt).toLocaleString(),
|
|
742
|
-
truncate
|
|
938
|
+
truncate(v.content.replace(/\n/g, " "), 60)
|
|
743
939
|
]);
|
|
744
940
|
process.stdout.write(`${table.toString()}\n`);
|
|
745
941
|
} finally {
|
|
@@ -858,168 +1054,6 @@ function unpinCommand(id, db) {
|
|
|
858
1054
|
}
|
|
859
1055
|
}
|
|
860
1056
|
//#endregion
|
|
861
|
-
//#region src/formatter.ts
|
|
862
|
-
const TYPE_COLORS = {
|
|
863
|
-
correction: chalk.yellow,
|
|
864
|
-
preference: chalk.cyan,
|
|
865
|
-
decision: chalk.blue,
|
|
866
|
-
learning: chalk.green,
|
|
867
|
-
fact: chalk.dim
|
|
868
|
-
};
|
|
869
|
-
function colorType(type) {
|
|
870
|
-
return TYPE_COLORS[type](type);
|
|
871
|
-
}
|
|
872
|
-
function statsRow(label, value, warn) {
|
|
873
|
-
if (warn) process.stdout.write(` ${chalk.yellow("⚠")} ${label.padEnd(12)} ${value}\n`);
|
|
874
|
-
else process.stdout.write(` ${" ".concat(label).padEnd(14)} ${value}\n`);
|
|
875
|
-
}
|
|
876
|
-
function truncate(str, max) {
|
|
877
|
-
return str.length > max ? `${str.slice(0, max - 1)}…` : str;
|
|
878
|
-
}
|
|
879
|
-
var Formatter = class Formatter {
|
|
880
|
-
#isJson;
|
|
881
|
-
constructor(isJson) {
|
|
882
|
-
this.#isJson = isJson;
|
|
883
|
-
}
|
|
884
|
-
static create(forceJson = false) {
|
|
885
|
-
return new Formatter(forceJson || !process.stdout.isTTY);
|
|
886
|
-
}
|
|
887
|
-
get isJson() {
|
|
888
|
-
return this.#isJson;
|
|
889
|
-
}
|
|
890
|
-
outputMemory(memory) {
|
|
891
|
-
if (this.#isJson) {
|
|
892
|
-
process.stdout.write(`${JSON.stringify(memory)}\n`);
|
|
893
|
-
return;
|
|
894
|
-
}
|
|
895
|
-
const tags = memory.tags.length > 0 ? memory.tags.join(", ") : "(none)";
|
|
896
|
-
process.stdout.write("\n");
|
|
897
|
-
process.stdout.write(` ${colorType(memory.type)} ${chalk.dim(memory.id)}\n`);
|
|
898
|
-
process.stdout.write(` ${memory.content}\n`);
|
|
899
|
-
const scope = memory.projects.length > 0 ? memory.projects.map((p) => p.name).join(", ") : "global";
|
|
900
|
-
process.stdout.write(` ${chalk.dim("Tags:")} ${tags} ${chalk.dim("Project:")} ${scope}\n`);
|
|
901
|
-
process.stdout.write(`\n ${chalk.dim(`Hint: pin with membank pin ${memory.id}`)}\n\n`);
|
|
902
|
-
}
|
|
903
|
-
outputMemories(memories) {
|
|
904
|
-
if (this.#isJson) {
|
|
905
|
-
process.stdout.write(`${JSON.stringify(memories)}\n`);
|
|
906
|
-
return;
|
|
907
|
-
}
|
|
908
|
-
if (memories.length === 0) {
|
|
909
|
-
process.stdout.write(`${chalk.dim("No memories found.")}\n`);
|
|
910
|
-
return;
|
|
911
|
-
}
|
|
912
|
-
const table = new Table({
|
|
913
|
-
head: [
|
|
914
|
-
"Type",
|
|
915
|
-
"ID",
|
|
916
|
-
"Content",
|
|
917
|
-
"Pinned"
|
|
918
|
-
].map((h) => chalk.bold(h)),
|
|
919
|
-
style: {
|
|
920
|
-
head: [],
|
|
921
|
-
border: []
|
|
922
|
-
}
|
|
923
|
-
});
|
|
924
|
-
for (const m of memories) {
|
|
925
|
-
const tags = m.tags.length > 0 ? m.tags.join(", ") : "(none)";
|
|
926
|
-
const mScope = m.projects.length > 0 ? m.projects.map((p) => p.name).join(", ") : "global";
|
|
927
|
-
const meta = `${truncate(m.content, 45)}\n${chalk.dim(`${tags} · ${mScope}`)}`;
|
|
928
|
-
table.push([
|
|
929
|
-
colorType(m.type),
|
|
930
|
-
chalk.dim(m.id),
|
|
931
|
-
meta,
|
|
932
|
-
m.pinned ? "📌" : ""
|
|
933
|
-
]);
|
|
934
|
-
}
|
|
935
|
-
process.stdout.write(`\n${table.toString()}\n\n`);
|
|
936
|
-
}
|
|
937
|
-
outputStats(stats) {
|
|
938
|
-
if (this.#isJson) {
|
|
939
|
-
process.stdout.write(`${JSON.stringify(stats)}\n`);
|
|
940
|
-
return;
|
|
941
|
-
}
|
|
942
|
-
const types = [
|
|
943
|
-
"correction",
|
|
944
|
-
"preference",
|
|
945
|
-
"decision",
|
|
946
|
-
"learning",
|
|
947
|
-
"fact"
|
|
948
|
-
];
|
|
949
|
-
process.stdout.write("\n");
|
|
950
|
-
for (const type of types) process.stdout.write(` ${TYPE_COLORS[type](type.padEnd(14))} ${stats.byType[type]}\n`);
|
|
951
|
-
process.stdout.write(`\n ${chalk.dim("─".repeat(24))}\n`);
|
|
952
|
-
process.stdout.write(` ${"total".padEnd(14)} ${stats.total}\n`);
|
|
953
|
-
statsRow("needs_review", String(stats.needsReview), stats.needsReview > 0);
|
|
954
|
-
statsRow("pin_budget", `${stats.pinBudgetChars} / ${PIN_BUDGET_THRESHOLD} chars`, stats.pinBudgetChars > PIN_BUDGET_THRESHOLD);
|
|
955
|
-
process.stdout.write("\n");
|
|
956
|
-
}
|
|
957
|
-
outputQueryResults(results) {
|
|
958
|
-
if (this.#isJson) {
|
|
959
|
-
process.stdout.write(`${JSON.stringify(results)}\n`);
|
|
960
|
-
return;
|
|
961
|
-
}
|
|
962
|
-
if (results.length === 0) {
|
|
963
|
-
process.stdout.write(`${chalk.dim("No memories found.")}\n`);
|
|
964
|
-
return;
|
|
965
|
-
}
|
|
966
|
-
const table = new Table({
|
|
967
|
-
head: [
|
|
968
|
-
"Type",
|
|
969
|
-
"ID",
|
|
970
|
-
"Content",
|
|
971
|
-
"Score"
|
|
972
|
-
].map((h) => chalk.bold(h)),
|
|
973
|
-
style: {
|
|
974
|
-
head: [],
|
|
975
|
-
border: []
|
|
976
|
-
}
|
|
977
|
-
});
|
|
978
|
-
for (const r of results) {
|
|
979
|
-
const scoreStr = r.score.toFixed(4);
|
|
980
|
-
const score = r.score >= .85 ? chalk.bold(scoreStr) : r.score < .75 ? chalk.dim(scoreStr) : scoreStr;
|
|
981
|
-
const tags = r.tags.length > 0 ? r.tags.join(", ") : "(none)";
|
|
982
|
-
const rScope = r.projects.length > 0 ? r.projects.map((p) => p.name).join(", ") : "global";
|
|
983
|
-
const meta = `${truncate(r.content, 45)}\n${chalk.dim(`${tags} · ${rScope}`)}`;
|
|
984
|
-
table.push([
|
|
985
|
-
colorType(r.type),
|
|
986
|
-
chalk.dim(r.id),
|
|
987
|
-
meta,
|
|
988
|
-
score
|
|
989
|
-
]);
|
|
990
|
-
}
|
|
991
|
-
process.stdout.write(`\n${table.toString()}\n\n`);
|
|
992
|
-
}
|
|
993
|
-
outputReview(memories) {
|
|
994
|
-
if (this.#isJson) {
|
|
995
|
-
process.stdout.write(`${JSON.stringify(memories)}\n`);
|
|
996
|
-
return;
|
|
997
|
-
}
|
|
998
|
-
if (memories.length === 0) {
|
|
999
|
-
process.stdout.write(`${chalk.dim("No memories flagged for review.")}\n`);
|
|
1000
|
-
return;
|
|
1001
|
-
}
|
|
1002
|
-
for (const m of memories) {
|
|
1003
|
-
process.stdout.write("\n");
|
|
1004
|
-
process.stdout.write(` ${colorType(m.type)} ${chalk.dim(m.id)}\n`);
|
|
1005
|
-
process.stdout.write(` ${truncate(m.content, 80)}\n`);
|
|
1006
|
-
for (const event of m.reviewEvents) this.#outputReviewEvent(event);
|
|
1007
|
-
}
|
|
1008
|
-
process.stdout.write("\n");
|
|
1009
|
-
}
|
|
1010
|
-
#outputReviewEvent(event) {
|
|
1011
|
-
const pct = `${Math.round(event.similarity * 100)}%`;
|
|
1012
|
-
const conflictRef = event.conflictingMemoryId ? chalk.dim(event.conflictingMemoryId) : chalk.dim("(deleted)");
|
|
1013
|
-
const ts = new Date(event.createdAt).toLocaleString();
|
|
1014
|
-
process.stdout.write(` ${chalk.yellow("⚠")} ${pct} similarity conflict: ${conflictRef} ${chalk.dim(ts)}\n`);
|
|
1015
|
-
if (event.conflictContentSnapshot) process.stdout.write(` ${chalk.dim("snapshot:")} ${truncate(event.conflictContentSnapshot, 60)}\n`);
|
|
1016
|
-
}
|
|
1017
|
-
error(msg) {
|
|
1018
|
-
if (this.#isJson) process.stderr.write(`${JSON.stringify({ error: msg })}\n`);
|
|
1019
|
-
else process.stderr.write(`${chalk.red("Error:")} ${msg}\n`);
|
|
1020
|
-
}
|
|
1021
|
-
};
|
|
1022
|
-
//#endregion
|
|
1023
1057
|
//#region src/prompt-helper.ts
|
|
1024
1058
|
var PromptHelper = class {
|
|
1025
1059
|
autoConfirm;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@membank/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.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.
|
|
25
|
-
"@membank/mcp": "0.16.
|
|
24
|
+
"@membank/core": "0.15.0",
|
|
25
|
+
"@membank/mcp": "0.16.2"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@types/node": "^25.6.0",
|