@hivelore/cli 0.30.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.
@@ -0,0 +1,361 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/tui/Dashboard.tsx
4
+ import { useState, useEffect, useCallback } from "react";
5
+ import { Box, Text, useInput, useApp } from "ink";
6
+ import { existsSync } from "fs";
7
+ import { writeFile, unlink } from "fs/promises";
8
+ import path from "path";
9
+ import {
10
+ getUsage,
11
+ isDecaying,
12
+ loadMemoriesFromDir,
13
+ loadUsageIndex,
14
+ resolveHaivePaths,
15
+ serializeMemory
16
+ } from "@hivelore/core";
17
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
18
+ var FILTERS = ["all", "draft", "proposed", "validated", "stale", "rejected"];
19
+ var LIST_H = 14;
20
+ function statusColor(status) {
21
+ if (status === "validated") return "green";
22
+ if (status === "proposed" || status === "stale") return "yellow";
23
+ if (status === "rejected") return "red";
24
+ return void 0;
25
+ }
26
+ function Dashboard({ root }) {
27
+ const { exit } = useApp();
28
+ const paths = resolveHaivePaths(root);
29
+ const [screen, setScreen] = useState("memories");
30
+ const [memories, setMemories] = useState([]);
31
+ const [usage, setUsage] = useState({ version: 1, updated_at: "", by_id: {} });
32
+ const [loading, setLoading] = useState(true);
33
+ const [filterIdx, setFilterIdx] = useState(0);
34
+ const [cursor, setCursor] = useState(0);
35
+ const [flash, setFlash] = useState(null);
36
+ const filter = FILTERS[filterIdx] ?? "all";
37
+ const reload = useCallback(async () => {
38
+ setLoading(true);
39
+ const [mems, u] = await Promise.all([
40
+ existsSync(paths.memoriesDir) ? loadMemoriesFromDir(paths.memoriesDir) : Promise.resolve([]),
41
+ loadUsageIndex(paths)
42
+ ]);
43
+ setMemories(mems);
44
+ setUsage(u);
45
+ setLoading(false);
46
+ }, [paths.memoriesDir]);
47
+ useEffect(() => {
48
+ void reload();
49
+ }, [reload]);
50
+ const nonRecap = memories.filter((m) => m.memory.frontmatter.type !== "session_recap");
51
+ const filtered = nonRecap.filter((m) => {
52
+ const s = m.memory.frontmatter.status;
53
+ if (filter === "all") return s !== "rejected";
54
+ return s === filter;
55
+ });
56
+ const staleMemories = nonRecap.filter((m) => m.memory.frontmatter.status === "stale");
57
+ const anchorless = nonRecap.filter(
58
+ (m) => m.memory.frontmatter.anchor.paths.length === 0 && m.memory.frontmatter.anchor.symbols.length === 0 && m.memory.frontmatter.status !== "rejected"
59
+ );
60
+ const pending = nonRecap.filter((m) => m.memory.frontmatter.status === "proposed");
61
+ const topRead = [...nonRecap].map((m) => ({ m, u: getUsage(usage, m.memory.frontmatter.id) })).filter(({ u }) => u.read_count > 0).sort((a, b) => b.u.read_count - a.u.read_count).slice(0, 5);
62
+ const decaying = nonRecap.filter(({ memory: mem }) => {
63
+ const u = getUsage(usage, mem.frontmatter.id);
64
+ return isDecaying(u, mem.frontmatter.created_at);
65
+ });
66
+ const selected = filtered[cursor];
67
+ const counts = nonRecap.reduce((acc, m) => {
68
+ acc[m.memory.frontmatter.status] = (acc[m.memory.frontmatter.status] ?? 0) + 1;
69
+ return acc;
70
+ }, {});
71
+ const flash_ = (text, color = "green") => {
72
+ setFlash({ text, color });
73
+ setTimeout(() => setFlash(null), 2500);
74
+ };
75
+ const doStatusChange = useCallback(async (newStatus) => {
76
+ if (!selected) return;
77
+ const fm = selected.memory.frontmatter;
78
+ if (fm.status === newStatus) {
79
+ flash_(`Already ${newStatus}`, "yellow");
80
+ return;
81
+ }
82
+ await writeFile(
83
+ selected.filePath,
84
+ serializeMemory({ frontmatter: { ...fm, status: newStatus }, body: selected.memory.body }),
85
+ "utf8"
86
+ );
87
+ const label = newStatus === "validated" ? "\u2713 Approved" : "\u2717 Rejected";
88
+ const color = newStatus === "validated" ? "green" : "red";
89
+ flash_(`${label}: ${fm.id.slice(0, 40)}`, color);
90
+ const prev = cursor;
91
+ await reload();
92
+ setCursor(Math.min(prev, Math.max(0, filtered.length - 2)));
93
+ }, [selected, cursor, filtered.length, reload]);
94
+ const doPromote = useCallback(async () => {
95
+ if (!selected) return;
96
+ const fm = selected.memory.frontmatter;
97
+ if (fm.scope === "team") {
98
+ flash_("Already team scope", "yellow");
99
+ return;
100
+ }
101
+ const teamDir = path.join(path.dirname(path.dirname(selected.filePath)), "team");
102
+ const newFilePath = path.join(teamDir, path.basename(selected.filePath));
103
+ const { mkdir } = await import("fs/promises");
104
+ await mkdir(teamDir, { recursive: true });
105
+ await writeFile(
106
+ newFilePath,
107
+ serializeMemory({
108
+ frontmatter: { ...fm, scope: "team", status: "proposed" },
109
+ body: selected.memory.body
110
+ }),
111
+ "utf8"
112
+ );
113
+ await unlink(selected.filePath);
114
+ flash_(`\u2191 Promoted to team: ${fm.id.slice(0, 36)}`, "yellow");
115
+ await reload();
116
+ setCursor((c) => Math.max(0, c - 1));
117
+ }, [selected, reload]);
118
+ const doDelete = useCallback(async () => {
119
+ if (!selected) return;
120
+ const fm = selected.memory.frontmatter;
121
+ await unlink(selected.filePath);
122
+ flash_(`\u{1F5D1} Deleted: ${fm.id.slice(0, 40)}`, "red");
123
+ await reload();
124
+ setCursor((c) => Math.max(0, c - 1));
125
+ }, [selected, reload]);
126
+ useInput((input, key) => {
127
+ if (input === "q") {
128
+ exit();
129
+ return;
130
+ }
131
+ if (input === "1") {
132
+ setScreen("memories");
133
+ setCursor(0);
134
+ return;
135
+ }
136
+ if (input === "2") {
137
+ setScreen("health");
138
+ return;
139
+ }
140
+ if (input === "3") {
141
+ setScreen("stats");
142
+ return;
143
+ }
144
+ if (screen === "memories") {
145
+ if (key.upArrow) setCursor((c) => Math.max(0, c - 1));
146
+ if (key.downArrow) setCursor((c) => Math.min(filtered.length - 1, c + 1));
147
+ if (key.tab) {
148
+ setFilterIdx((i) => (i + 1) % FILTERS.length);
149
+ setCursor(0);
150
+ }
151
+ if (input === "a") void doStatusChange("validated");
152
+ if (input === "r") void doStatusChange("rejected");
153
+ if (input === "p") void doPromote();
154
+ if (input === "d") void doDelete();
155
+ }
156
+ });
157
+ if (loading) return /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Loading memories\u2026" });
158
+ if (!existsSync(paths.memoriesDir)) {
159
+ return /* @__PURE__ */ jsx(Text, { color: "red", children: "No .ai/memories found \u2014 run `hivelore init` first." });
160
+ }
161
+ const v = counts["validated"] ?? 0;
162
+ const p = counts["proposed"] ?? 0;
163
+ const d = counts["draft"] ?? 0;
164
+ const st = counts["stale"] ?? 0;
165
+ const rej = counts["rejected"] ?? 0;
166
+ const Header = () => /* @__PURE__ */ jsxs(Box, { borderStyle: "round", paddingX: 1, gap: 2, children: [
167
+ /* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "Hivelore" }),
168
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: root.length > 40 ? "\u2026" + root.slice(-38) : root }),
169
+ /* @__PURE__ */ jsx(Text, { children: " " }),
170
+ /* @__PURE__ */ jsxs(Text, { color: "green", children: [
171
+ "\u2713 ",
172
+ v
173
+ ] }),
174
+ /* @__PURE__ */ jsxs(Text, { color: p > 0 ? "yellow" : void 0, children: [
175
+ " ~ ",
176
+ p
177
+ ] }),
178
+ /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
179
+ " \xB7 ",
180
+ d
181
+ ] }),
182
+ st > 0 && /* @__PURE__ */ jsxs(Text, { color: "yellow", children: [
183
+ " \u26A0 ",
184
+ st
185
+ ] }),
186
+ rej > 0 && /* @__PURE__ */ jsxs(Text, { color: "red", children: [
187
+ " \u2717 ",
188
+ rej
189
+ ] })
190
+ ] });
191
+ const ScreenTabs = () => /* @__PURE__ */ jsxs(Box, { paddingX: 1, gap: 3, marginBottom: 0, children: [
192
+ ["memories", "health", "stats"].map((s, i) => /* @__PURE__ */ jsxs(Text, { color: screen === s ? "cyan" : void 0, bold: screen === s, children: [
193
+ "[",
194
+ i + 1,
195
+ "] ",
196
+ screen === s ? `[${s}]` : s
197
+ ] }, s)),
198
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: " [q] quit" })
199
+ ] });
200
+ const FlashBar = () => flash ? /* @__PURE__ */ jsx(Box, { paddingX: 1, children: /* @__PURE__ */ jsx(Text, { color: flash.color, children: flash.text }) }) : null;
201
+ if (screen === "memories") {
202
+ const half = Math.floor(LIST_H / 2);
203
+ const start = Math.max(0, Math.min(cursor - half, Math.max(0, filtered.length - LIST_H)));
204
+ const visible = filtered.slice(start, start + LIST_H);
205
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
206
+ /* @__PURE__ */ jsx(Header, {}),
207
+ /* @__PURE__ */ jsx(ScreenTabs, {}),
208
+ /* @__PURE__ */ jsxs(Box, { paddingX: 1, gap: 2, marginBottom: 0, children: [
209
+ FILTERS.map((f) => /* @__PURE__ */ jsx(Text, { color: filter === f ? "cyan" : void 0, bold: filter === f, children: filter === f ? `[${f}]` : f }, f)),
210
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: " [tab] cycle" })
211
+ ] }),
212
+ /* @__PURE__ */ jsxs(Box, { children: [
213
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "column", width: 64, borderStyle: "single", paddingX: 1, children: [
214
+ /* @__PURE__ */ jsx(Text, { bold: true, dimColor: true, children: `MEMORIES ${filtered.length}/${nonRecap.length}` }),
215
+ filtered.length === 0 ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: " (no memories in this filter)" }) : visible.map((m, vi) => {
216
+ const absIdx = start + vi;
217
+ const fm = m.memory.frontmatter;
218
+ const sel = absIdx === cursor;
219
+ const idShort = fm.id.length > 43 ? fm.id.slice(0, 40) + "\u2026" : fm.id;
220
+ return /* @__PURE__ */ jsxs(Box, { children: [
221
+ /* @__PURE__ */ jsxs(Text, { color: sel ? "cyan" : void 0, bold: sel, children: [
222
+ sel ? "\u25B6 " : " ",
223
+ idShort.padEnd(43)
224
+ ] }),
225
+ /* @__PURE__ */ jsx(Text, { color: statusColor(fm.status), children: fm.status.slice(0, 9) })
226
+ ] }, fm.id);
227
+ })
228
+ ] }),
229
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "column", width: 40, borderStyle: "single", paddingX: 1, children: [
230
+ /* @__PURE__ */ jsx(Text, { bold: true, dimColor: true, children: "PREVIEW" }),
231
+ selected ? /* @__PURE__ */ jsxs(Fragment, { children: [
232
+ /* @__PURE__ */ jsx(Text, { bold: true, children: selected.memory.frontmatter.id.slice(0, 36) }),
233
+ /* @__PURE__ */ jsxs(Text, { color: "cyan", children: [
234
+ selected.memory.frontmatter.scope,
235
+ "/",
236
+ selected.memory.frontmatter.type,
237
+ selected.memory.frontmatter.module ? ` [${selected.memory.frontmatter.module}]` : ""
238
+ ] }),
239
+ /* @__PURE__ */ jsxs(Text, { color: statusColor(selected.memory.frontmatter.status), children: [
240
+ selected.memory.frontmatter.status,
241
+ selected.memory.frontmatter.revision_count ? ` (rev ${selected.memory.frontmatter.revision_count})` : ""
242
+ ] }),
243
+ /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
244
+ "tags: ",
245
+ selected.memory.frontmatter.tags.slice(0, 5).join(", ") || "(none)"
246
+ ] }),
247
+ /* @__PURE__ */ jsx(Text, { children: " " }),
248
+ selected.memory.body.split("\n").slice(0, LIST_H - 4).map((line, i) => /* @__PURE__ */ jsx(Text, { wrap: "truncate-end", children: line || " " }, i))
249
+ ] }) : /* @__PURE__ */ jsx(Text, { dimColor: true, children: "select a memory" })
250
+ ] })
251
+ ] }),
252
+ /* @__PURE__ */ jsx(FlashBar, {}),
253
+ /* @__PURE__ */ jsx(Box, { paddingX: 1, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2191\u2193 navigate [tab] filter [a] approve [r] reject [p] promote personal\u2192team [d] delete" }) })
254
+ ] });
255
+ }
256
+ if (screen === "health") {
257
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
258
+ /* @__PURE__ */ jsx(Header, {}),
259
+ /* @__PURE__ */ jsx(ScreenTabs, {}),
260
+ /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
261
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "column", width: 40, borderStyle: "single", paddingX: 1, children: [
262
+ /* @__PURE__ */ jsxs(Text, { bold: true, color: staleMemories.length > 0 ? "yellow" : "green", children: [
263
+ "\u26A0 STALE (",
264
+ staleMemories.length,
265
+ ")"
266
+ ] }),
267
+ staleMemories.length === 0 ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: " All memories are fresh" }) : staleMemories.slice(0, LIST_H).map((m) => /* @__PURE__ */ jsx(Text, { wrap: "truncate-end", color: "yellow", children: m.memory.frontmatter.id.slice(0, 36) }, m.memory.frontmatter.id)),
268
+ staleMemories.length > LIST_H && /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
269
+ " \u2026 +",
270
+ staleMemories.length - LIST_H,
271
+ " more"
272
+ ] })
273
+ ] }),
274
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
275
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "column", width: 44, borderStyle: "single", paddingX: 1, children: [
276
+ /* @__PURE__ */ jsxs(Text, { bold: true, color: pending.length > 0 ? "yellow" : "green", children: [
277
+ "~ PENDING REVIEW (",
278
+ pending.length,
279
+ ")"
280
+ ] }),
281
+ pending.length === 0 ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: " No memories pending review" }) : pending.slice(0, 6).map((m) => /* @__PURE__ */ jsx(Text, { wrap: "truncate-end", children: m.memory.frontmatter.id.slice(0, 40) }, m.memory.frontmatter.id))
282
+ ] }),
283
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "column", width: 44, borderStyle: "single", paddingX: 1, children: [
284
+ /* @__PURE__ */ jsxs(Text, { bold: true, dimColor: true, children: [
285
+ "\u2298 ANCHORLESS (",
286
+ anchorless.length,
287
+ ")"
288
+ ] }),
289
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: " No paths/symbols \u2014 staleness undetectable" }),
290
+ anchorless.slice(0, 5).map((m) => /* @__PURE__ */ jsx(Text, { wrap: "truncate-end", dimColor: true, children: m.memory.frontmatter.id.slice(0, 40) }, m.memory.frontmatter.id)),
291
+ anchorless.length > 5 && /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
292
+ " \u2026 +",
293
+ anchorless.length - 5,
294
+ " more"
295
+ ] })
296
+ ] })
297
+ ] })
298
+ ] }),
299
+ /* @__PURE__ */ jsx(Box, { paddingX: 1, marginTop: 1, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Run `hivelore memory verify --update` to recheck anchors | `hivelore memory update <id> --paths <files>` to add anchors" }) }),
300
+ /* @__PURE__ */ jsx(FlashBar, {})
301
+ ] });
302
+ }
303
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
304
+ /* @__PURE__ */ jsx(Header, {}),
305
+ /* @__PURE__ */ jsx(ScreenTabs, {}),
306
+ /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
307
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "column", width: 44, borderStyle: "single", paddingX: 1, children: [
308
+ /* @__PURE__ */ jsx(Text, { bold: true, dimColor: true, children: "\u{1F4D6} TOP READ MEMORIES" }),
309
+ topRead.length === 0 ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: " No read data yet (use `get_briefing`)" }) : topRead.map(({ m, u }) => /* @__PURE__ */ jsxs(Box, { children: [
310
+ /* @__PURE__ */ jsx(Text, { wrap: "truncate-end", children: m.memory.frontmatter.id.slice(0, 32).padEnd(32) }),
311
+ /* @__PURE__ */ jsxs(Text, { color: "cyan", children: [
312
+ " \xD7",
313
+ u.read_count
314
+ ] })
315
+ ] }, m.memory.frontmatter.id))
316
+ ] }),
317
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
318
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "column", width: 44, borderStyle: "single", paddingX: 1, children: [
319
+ /* @__PURE__ */ jsxs(Text, { bold: true, color: decaying.length > 0 ? "yellow" : "green", children: [
320
+ "\u23F3 DECAYING (not read in 90d) (",
321
+ decaying.length,
322
+ ")"
323
+ ] }),
324
+ decaying.length === 0 ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: " All memories are actively used" }) : decaying.slice(0, 5).map((m) => /* @__PURE__ */ jsx(Text, { wrap: "truncate-end", color: "yellow", children: m.memory.frontmatter.id.slice(0, 40) }, m.memory.frontmatter.id))
325
+ ] }),
326
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "column", width: 44, borderStyle: "single", paddingX: 1, children: [
327
+ /* @__PURE__ */ jsx(Text, { bold: true, dimColor: true, children: "\u{1F4CA} MEMORY TOTALS" }),
328
+ /* @__PURE__ */ jsxs(Text, { children: [
329
+ " Validated: ",
330
+ /* @__PURE__ */ jsx(Text, { color: "green", children: v })
331
+ ] }),
332
+ /* @__PURE__ */ jsxs(Text, { children: [
333
+ " Proposed: ",
334
+ /* @__PURE__ */ jsx(Text, { color: "yellow", children: p })
335
+ ] }),
336
+ /* @__PURE__ */ jsxs(Text, { children: [
337
+ " Draft: ",
338
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: d })
339
+ ] }),
340
+ /* @__PURE__ */ jsxs(Text, { children: [
341
+ " Stale: ",
342
+ /* @__PURE__ */ jsx(Text, { color: "yellow", children: st })
343
+ ] }),
344
+ /* @__PURE__ */ jsxs(Text, { children: [
345
+ " Rejected: ",
346
+ /* @__PURE__ */ jsx(Text, { color: "red", children: rej })
347
+ ] }),
348
+ /* @__PURE__ */ jsxs(Text, { children: [
349
+ " Total: ",
350
+ /* @__PURE__ */ jsx(Text, { bold: true, children: nonRecap.length })
351
+ ] })
352
+ ] })
353
+ ] })
354
+ ] }),
355
+ /* @__PURE__ */ jsx(FlashBar, {})
356
+ ] });
357
+ }
358
+ export {
359
+ Dashboard
360
+ };
361
+ //# sourceMappingURL=Dashboard-3WMW72XE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tui/Dashboard.tsx"],"sourcesContent":["import { useState, useEffect, useCallback } from \"react\";\nimport { Box, Text, useInput, useApp } from \"ink\";\nimport { existsSync } from \"node:fs\";\nimport { writeFile, unlink } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport {\n getUsage,\n isDecaying,\n loadMemoriesFromDir,\n loadUsageIndex,\n resolveHaivePaths,\n serializeMemory,\n type LoadedMemory,\n type UsageIndex,\n} from \"@hivelore/core\";\n\ntype Screen = \"memories\" | \"health\" | \"stats\";\ntype FilterStatus = \"all\" | \"draft\" | \"proposed\" | \"validated\" | \"stale\" | \"rejected\";\nconst FILTERS: FilterStatus[] = [\"all\", \"draft\", \"proposed\", \"validated\", \"stale\", \"rejected\"];\nconst LIST_H = 14;\n\nfunction statusColor(status: string): \"green\" | \"yellow\" | \"red\" | undefined {\n if (status === \"validated\") return \"green\";\n if (status === \"proposed\" || status === \"stale\") return \"yellow\";\n if (status === \"rejected\") return \"red\";\n return undefined;\n}\n\ninterface Props { root: string; }\n\nexport function Dashboard({ root }: Props) {\n const { exit } = useApp();\n const paths = resolveHaivePaths(root);\n\n const [screen, setScreen] = useState<Screen>(\"memories\");\n const [memories, setMemories] = useState<LoadedMemory[]>([]);\n const [usage, setUsage] = useState<UsageIndex>({ version: 1, updated_at: \"\", by_id: {} });\n const [loading, setLoading] = useState(true);\n const [filterIdx, setFilterIdx] = useState(0);\n const [cursor, setCursor] = useState(0);\n const [flash, setFlash] = useState<{ text: string; color: \"green\" | \"red\" | \"yellow\" } | null>(null);\n\n const filter: FilterStatus = FILTERS[filterIdx] ?? \"all\";\n\n const reload = useCallback(async () => {\n setLoading(true);\n const [mems, u] = await Promise.all([\n existsSync(paths.memoriesDir) ? loadMemoriesFromDir(paths.memoriesDir) : Promise.resolve([]),\n loadUsageIndex(paths),\n ]);\n setMemories(mems);\n setUsage(u);\n setLoading(false);\n }, [paths.memoriesDir]);\n\n useEffect(() => { void reload(); }, [reload]);\n\n // ── Derived data ──────────────────────────────────────────────────────\n const nonRecap = memories.filter((m) => m.memory.frontmatter.type !== \"session_recap\");\n\n const filtered = nonRecap.filter((m) => {\n const s = m.memory.frontmatter.status;\n if (filter === \"all\") return s !== \"rejected\";\n return s === filter;\n });\n\n const staleMemories = nonRecap.filter((m) => m.memory.frontmatter.status === \"stale\");\n const anchorless = nonRecap.filter(\n (m) =>\n m.memory.frontmatter.anchor.paths.length === 0 &&\n m.memory.frontmatter.anchor.symbols.length === 0 &&\n m.memory.frontmatter.status !== \"rejected\",\n );\n const pending = nonRecap.filter((m) => m.memory.frontmatter.status === \"proposed\");\n\n // Top-5 by read_count\n const topRead = [...nonRecap]\n .map((m) => ({ m, u: getUsage(usage, m.memory.frontmatter.id) }))\n .filter(({ u }) => u.read_count > 0)\n .sort((a, b) => b.u.read_count - a.u.read_count)\n .slice(0, 5);\n\n // Decaying memories\n const decaying = nonRecap.filter(({ memory: mem }) => {\n const u = getUsage(usage, mem.frontmatter.id);\n return isDecaying(u, mem.frontmatter.created_at);\n });\n\n const selected = filtered[cursor];\n\n const counts = nonRecap.reduce<Record<string, number>>((acc, m) => {\n acc[m.memory.frontmatter.status] = (acc[m.memory.frontmatter.status] ?? 0) + 1;\n return acc;\n }, {});\n\n const flash_ = (text: string, color: \"green\" | \"red\" | \"yellow\" = \"green\") => {\n setFlash({ text, color });\n setTimeout(() => setFlash(null), 2500);\n };\n\n // ── Actions ───────────────────────────────────────────────────────────\n const doStatusChange = useCallback(async (newStatus: \"validated\" | \"rejected\") => {\n if (!selected) return;\n const fm = selected.memory.frontmatter;\n if (fm.status === newStatus) { flash_(`Already ${newStatus}`, \"yellow\"); return; }\n await writeFile(\n selected.filePath,\n serializeMemory({ frontmatter: { ...fm, status: newStatus }, body: selected.memory.body }),\n \"utf8\",\n );\n const label = newStatus === \"validated\" ? \"✓ Approved\" : \"✗ Rejected\";\n const color = newStatus === \"validated\" ? \"green\" : \"red\";\n flash_(`${label}: ${fm.id.slice(0, 40)}`, color);\n const prev = cursor;\n await reload();\n setCursor(Math.min(prev, Math.max(0, filtered.length - 2)));\n }, [selected, cursor, filtered.length, reload]);\n\n // Promote = move personal → team (scope change) + set status proposed\n const doPromote = useCallback(async () => {\n if (!selected) return;\n const fm = selected.memory.frontmatter;\n if (fm.scope === \"team\") { flash_(\"Already team scope\", \"yellow\"); return; }\n const teamDir = path.join(path.dirname(path.dirname(selected.filePath)), \"team\");\n const newFilePath = path.join(teamDir, path.basename(selected.filePath));\n const { mkdir } = await import(\"node:fs/promises\");\n await mkdir(teamDir, { recursive: true });\n await writeFile(\n newFilePath,\n serializeMemory({\n frontmatter: { ...fm, scope: \"team\" as const, status: \"proposed\" as const },\n body: selected.memory.body,\n }),\n \"utf8\",\n );\n await unlink(selected.filePath);\n flash_(`↑ Promoted to team: ${fm.id.slice(0, 36)}`, \"yellow\");\n await reload();\n setCursor((c) => Math.max(0, c - 1));\n }, [selected, reload]);\n\n const doDelete = useCallback(async () => {\n if (!selected) return;\n const fm = selected.memory.frontmatter;\n await unlink(selected.filePath);\n flash_(`🗑 Deleted: ${fm.id.slice(0, 40)}`, \"red\");\n await reload();\n setCursor((c) => Math.max(0, c - 1));\n }, [selected, reload]);\n\n useInput((input, key) => {\n if (input === \"q\") { exit(); return; }\n if (input === \"1\") { setScreen(\"memories\"); setCursor(0); return; }\n if (input === \"2\") { setScreen(\"health\"); return; }\n if (input === \"3\") { setScreen(\"stats\"); return; }\n\n if (screen === \"memories\") {\n if (key.upArrow) setCursor((c) => Math.max(0, c - 1));\n if (key.downArrow) setCursor((c) => Math.min(filtered.length - 1, c + 1));\n if (key.tab) { setFilterIdx((i) => (i + 1) % FILTERS.length); setCursor(0); }\n if (input === \"a\") void doStatusChange(\"validated\");\n if (input === \"r\") void doStatusChange(\"rejected\");\n if (input === \"p\") void doPromote();\n if (input === \"d\") void doDelete();\n }\n });\n\n if (loading) return <Text dimColor>Loading memories…</Text>;\n if (!existsSync(paths.memoriesDir)) {\n return <Text color=\"red\">No .ai/memories found — run `hivelore init` first.</Text>;\n }\n\n // ── Header (shared) ───────────────────────────────────────────────────\n const v = counts[\"validated\"] ?? 0;\n const p = counts[\"proposed\"] ?? 0;\n const d = counts[\"draft\"] ?? 0;\n const st = counts[\"stale\"] ?? 0;\n const rej = counts[\"rejected\"] ?? 0;\n\n const Header = () => (\n <Box borderStyle=\"round\" paddingX={1} gap={2}>\n <Text bold color=\"cyan\">Hivelore</Text>\n <Text dimColor>{root.length > 40 ? \"…\" + root.slice(-38) : root}</Text>\n <Text> </Text>\n <Text color=\"green\">✓ {v}</Text>\n <Text color={p > 0 ? \"yellow\" : undefined}> ~ {p}</Text>\n <Text dimColor> · {d}</Text>\n {st > 0 && <Text color=\"yellow\"> ⚠ {st}</Text>}\n {rej > 0 && <Text color=\"red\"> ✗ {rej}</Text>}\n </Box>\n );\n\n const ScreenTabs = () => (\n <Box paddingX={1} gap={3} marginBottom={0}>\n {([\"memories\", \"health\", \"stats\"] as Screen[]).map((s, i) => (\n <Text key={s} color={screen === s ? \"cyan\" : undefined} bold={screen === s}>\n [{i + 1}] {screen === s ? `[${s}]` : s}\n </Text>\n ))}\n <Text dimColor> [q] quit</Text>\n </Box>\n );\n\n const FlashBar = () => flash\n ? <Box paddingX={1}><Text color={flash.color}>{flash.text}</Text></Box>\n : null;\n\n // ── Screen: Memories ─────────────────────────────────────────────────\n if (screen === \"memories\") {\n const half = Math.floor(LIST_H / 2);\n const start = Math.max(0, Math.min(cursor - half, Math.max(0, filtered.length - LIST_H)));\n const visible = filtered.slice(start, start + LIST_H);\n\n return (\n <Box flexDirection=\"column\">\n <Header />\n <ScreenTabs />\n\n {/* Filter bar */}\n <Box paddingX={1} gap={2} marginBottom={0}>\n {FILTERS.map((f) => (\n <Text key={f} color={filter === f ? \"cyan\" : undefined} bold={filter === f}>\n {filter === f ? `[${f}]` : f}\n </Text>\n ))}\n <Text dimColor> [tab] cycle</Text>\n </Box>\n\n {/* List + Preview */}\n <Box>\n <Box flexDirection=\"column\" width={64} borderStyle=\"single\" paddingX={1}>\n <Text bold dimColor>{`MEMORIES ${filtered.length}/${nonRecap.length}`}</Text>\n {filtered.length === 0 ? (\n <Text dimColor> (no memories in this filter)</Text>\n ) : (\n visible.map((m, vi) => {\n const absIdx = start + vi;\n const fm = m.memory.frontmatter;\n const sel = absIdx === cursor;\n const idShort = fm.id.length > 43 ? fm.id.slice(0, 40) + \"…\" : fm.id;\n return (\n <Box key={fm.id}>\n <Text color={sel ? \"cyan\" : undefined} bold={sel}>\n {sel ? \"▶ \" : \" \"}\n {idShort.padEnd(43)}\n </Text>\n <Text color={statusColor(fm.status)}>{fm.status.slice(0, 9)}</Text>\n </Box>\n );\n })\n )}\n </Box>\n\n {/* Preview */}\n <Box flexDirection=\"column\" width={40} borderStyle=\"single\" paddingX={1}>\n <Text bold dimColor>PREVIEW</Text>\n {selected ? (\n <>\n <Text bold>{selected.memory.frontmatter.id.slice(0, 36)}</Text>\n <Text color=\"cyan\">\n {selected.memory.frontmatter.scope}/{selected.memory.frontmatter.type}\n {selected.memory.frontmatter.module ? ` [${selected.memory.frontmatter.module}]` : \"\"}\n </Text>\n <Text color={statusColor(selected.memory.frontmatter.status)}>\n {selected.memory.frontmatter.status}\n {selected.memory.frontmatter.revision_count ? ` (rev ${selected.memory.frontmatter.revision_count})` : \"\"}\n </Text>\n <Text dimColor>tags: {selected.memory.frontmatter.tags.slice(0, 5).join(\", \") || \"(none)\"}</Text>\n <Text> </Text>\n {selected.memory.body\n .split(\"\\n\")\n .slice(0, LIST_H - 4)\n .map((line, i) => (\n <Text key={i} wrap=\"truncate-end\">{line || \" \"}</Text>\n ))}\n </>\n ) : (\n <Text dimColor>select a memory</Text>\n )}\n </Box>\n </Box>\n\n <FlashBar />\n <Box paddingX={1}>\n <Text dimColor>↑↓ navigate [tab] filter [a] approve [r] reject [p] promote personal→team [d] delete</Text>\n </Box>\n </Box>\n );\n }\n\n // ── Screen: Health ────────────────────────────────────────────────────\n if (screen === \"health\") {\n return (\n <Box flexDirection=\"column\">\n <Header />\n <ScreenTabs />\n <Box gap={2}>\n\n {/* Stale memories */}\n <Box flexDirection=\"column\" width={40} borderStyle=\"single\" paddingX={1}>\n <Text bold color={staleMemories.length > 0 ? \"yellow\" : \"green\"}>\n ⚠ STALE ({staleMemories.length})\n </Text>\n {staleMemories.length === 0\n ? <Text dimColor> All memories are fresh</Text>\n : staleMemories.slice(0, LIST_H).map((m) => (\n <Text key={m.memory.frontmatter.id} wrap=\"truncate-end\" color=\"yellow\">\n {m.memory.frontmatter.id.slice(0, 36)}\n </Text>\n ))\n }\n {staleMemories.length > LIST_H && (\n <Text dimColor> … +{staleMemories.length - LIST_H} more</Text>\n )}\n </Box>\n\n <Box flexDirection=\"column\" gap={1}>\n {/* Pending review */}\n <Box flexDirection=\"column\" width={44} borderStyle=\"single\" paddingX={1}>\n <Text bold color={pending.length > 0 ? \"yellow\" : \"green\"}>\n ~ PENDING REVIEW ({pending.length})\n </Text>\n {pending.length === 0\n ? <Text dimColor> No memories pending review</Text>\n : pending.slice(0, 6).map((m) => (\n <Text key={m.memory.frontmatter.id} wrap=\"truncate-end\">\n {m.memory.frontmatter.id.slice(0, 40)}\n </Text>\n ))\n }\n </Box>\n\n {/* Anchorless */}\n <Box flexDirection=\"column\" width={44} borderStyle=\"single\" paddingX={1}>\n <Text bold dimColor>⊘ ANCHORLESS ({anchorless.length})</Text>\n <Text dimColor> No paths/symbols — staleness undetectable</Text>\n {anchorless.slice(0, 5).map((m) => (\n <Text key={m.memory.frontmatter.id} wrap=\"truncate-end\" dimColor>\n {m.memory.frontmatter.id.slice(0, 40)}\n </Text>\n ))}\n {anchorless.length > 5 && (\n <Text dimColor> … +{anchorless.length - 5} more</Text>\n )}\n </Box>\n </Box>\n </Box>\n\n <Box paddingX={1} marginTop={1}>\n <Text dimColor>\n Run `hivelore memory verify --update` to recheck anchors | `hivelore memory update &lt;id&gt; --paths &lt;files&gt;` to add anchors\n </Text>\n </Box>\n <FlashBar />\n </Box>\n );\n }\n\n // ── Screen: Stats ─────────────────────────────────────────────────────\n return (\n <Box flexDirection=\"column\">\n <Header />\n <ScreenTabs />\n <Box gap={2}>\n\n {/* Top read */}\n <Box flexDirection=\"column\" width={44} borderStyle=\"single\" paddingX={1}>\n <Text bold dimColor>📖 TOP READ MEMORIES</Text>\n {topRead.length === 0\n ? <Text dimColor> No read data yet (use `get_briefing`)</Text>\n : topRead.map(({ m, u }) => (\n <Box key={m.memory.frontmatter.id}>\n <Text wrap=\"truncate-end\">\n {m.memory.frontmatter.id.slice(0, 32).padEnd(32)}\n </Text>\n <Text color=\"cyan\"> ×{u.read_count}</Text>\n </Box>\n ))\n }\n </Box>\n\n <Box flexDirection=\"column\" gap={1}>\n {/* Decaying */}\n <Box flexDirection=\"column\" width={44} borderStyle=\"single\" paddingX={1}>\n <Text bold color={decaying.length > 0 ? \"yellow\" : \"green\"}>\n ⏳ DECAYING (not read in 90d) ({decaying.length})\n </Text>\n {decaying.length === 0\n ? <Text dimColor> All memories are actively used</Text>\n : decaying.slice(0, 5).map((m) => (\n <Text key={m.memory.frontmatter.id} wrap=\"truncate-end\" color=\"yellow\">\n {m.memory.frontmatter.id.slice(0, 40)}\n </Text>\n ))\n }\n </Box>\n\n {/* Memory totals */}\n <Box flexDirection=\"column\" width={44} borderStyle=\"single\" paddingX={1}>\n <Text bold dimColor>📊 MEMORY TOTALS</Text>\n <Text> Validated: <Text color=\"green\">{v}</Text></Text>\n <Text> Proposed: <Text color=\"yellow\">{p}</Text></Text>\n <Text> Draft: <Text dimColor>{d}</Text></Text>\n <Text> Stale: <Text color=\"yellow\">{st}</Text></Text>\n <Text> Rejected: <Text color=\"red\">{rej}</Text></Text>\n <Text> Total: <Text bold>{nonRecap.length}</Text></Text>\n </Box>\n </Box>\n </Box>\n <FlashBar />\n </Box>\n );\n}\n"],"mappings":"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","names":[]}