@hiveai/cli 0.3.0 → 0.3.3

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/README.md CHANGED
@@ -22,28 +22,30 @@ This installs the `haive` command globally.
22
22
  ## Quick start
23
23
 
24
24
  ```bash
25
- # 1. Initialize hAIve in your project
25
+ # 1. Initialize hAIve in your project (autopilot ON by default)
26
26
  cd my-project
27
- haive init
27
+ haive init # autopilot: hooks + CI + code-map auto-configured
28
+ # haive init --manual # if you prefer to approve memories yourself
28
29
 
29
- # 2. Start the MCP server (in Claude Code / Cursor MCP config)
30
- haive mcp --root /absolute/path/to/my-project
30
+ # 2. Point your AI client at the MCP server
31
+ # Add to ~/.claude.json / ~/.cursor/mcp.json:
32
+ # { "mcpServers": { "haive": { "command": "haive-mcp", "args": ["--root", "/absolute/path"] } } }
31
33
 
32
- # 3. Add a team memory
34
+ # 3. Bootstrap the project context (run once in your AI client)
35
+ # → Use the bootstrap_project MCP prompt to analyze the codebase and fill .ai/project-context.md
36
+
37
+ # 4. Your AI client now calls get_briefing at every session start — zero config needed
38
+
39
+ # 5. Add a memory manually (or let the AI agent do it via mem_save)
33
40
  haive memory add \
34
- --type gotcha \
35
- --slug "open-in-view-false" \
36
- --scope team \
41
+ --type gotcha --slug "jpa-open-in-view" --scope team \
37
42
  --paths src/main/resources/application.properties \
38
43
  --body "spring.jpa.open-in-view=false is intentional — do not re-enable."
39
44
 
40
- # 4. Browse memories
41
- haive memory list --scope team
42
-
43
- # 5. Get a briefing before a task
44
- haive briefing --task "add a payment endpoint" --scope team
45
+ # 6. Browse and manage memories in the TUI dashboard
46
+ haive tui
45
47
 
46
- # 6. Sync after a git pull
48
+ # 7. Sync after a git pull (runs automatically via hooks in autopilot mode)
47
49
  haive sync
48
50
  ```
49
51
 
@@ -53,21 +55,35 @@ haive sync
53
55
 
54
56
  ### `haive init`
55
57
 
56
- Initialize the `.ai/` structure in a project and generate bridge files for your AI tools.
58
+ Initialize the `.ai/` structure in a project. **Autopilot mode is ON by default** zero manual steps required.
57
59
 
58
60
  ```bash
59
- haive init # Creates .ai/, CLAUDE.md, .cursorrules, copilot-instructions.md
60
- haive init --no-bridges # Skip bridge file generation
61
- haive init --with-ci # Also write .github/workflows/haive-sync.yml
61
+ haive init # Autopilot: validates memories automatically, installs hooks, builds code-map
62
+ haive init --manual # Manual mode: you approve every memory yourself
63
+ haive init --no-bridges # Skip bridge file generation (CLAUDE.md, .cursorrules, etc.)
62
64
  haive init --dir /other/path # Initialize in a specific directory
63
65
  ```
64
66
 
67
+ **Autopilot mode** (default):
68
+ - Memories are saved directly as `validated` (no approval cycle)
69
+ - Git hooks installed automatically (`haive sync` after every pull)
70
+ - CI workflow generated (`.github/workflows/haive-sync.yml`)
71
+ - Initial code-map built (`.ai/code-map.json`) for symbol lookup
72
+ - Session recaps saved automatically when the MCP server exits
73
+ - Configuration stored in `.ai/haive.config.json`
74
+
75
+ **Manual mode** (`--manual`):
76
+ - Memories start as `proposed` and require explicit approval (`haive memory approve`)
77
+ - No automatic hooks or CI — set up manually with `haive install-hooks` and `haive init --with-ci`
78
+ - Full control over when knowledge is shared with the team
79
+
65
80
  **What it creates:**
66
81
 
67
82
  ```
68
83
  your-project/
69
84
  ├── .ai/
70
85
  │ ├── project-context.md # Shared project overview (fill via bootstrap_project MCP prompt)
86
+ │ ├── haive.config.json # Autopilot settings
71
87
  │ ├── modules/ # Per-component context files
72
88
  │ └── memories/
73
89
  │ ├── personal/ # Private to one developer
@@ -252,14 +268,22 @@ Show memories relevant to specific files you're about to edit.
252
268
  haive memory for-files src/payments/PaymentService.java src/payments/PaymentController.java
253
269
  ```
254
270
 
255
- #### `haive memory stats` / `hot` / `pending`
271
+ #### `haive memory stats` / `hot` / `pending` / `digest`
256
272
 
257
273
  ```bash
258
274
  haive memory stats # Usage stats and confidence levels for all memories
259
275
  haive memory hot # Most-read unvalidated memories (good promotion candidates)
260
276
  haive memory pending # Proposed memories awaiting review
277
+
278
+ # Generate a Markdown review digest for bulk approval/rejection:
279
+ haive memory digest # Last 7 days, team scope (prints to stdout)
280
+ haive memory digest --days 14 # Last 14 days
281
+ haive memory digest --scope all # All scopes
282
+ haive memory digest --out digest.md # Write to file
261
283
  ```
262
284
 
285
+ The digest groups memories by type, shows confidence level (⬜ unverified / 🟡 low / 🟢 trusted / ⭐ authoritative), anchor, read count, and action checkboxes for easy bulk review.
286
+
263
287
  ---
264
288
 
265
289
  ### `haive briefing`
@@ -267,12 +291,20 @@ haive memory pending # Proposed memories awaiting review
267
291
  Print the full project briefing — project context + relevant memories — in one shot. Use before starting a task.
268
292
 
269
293
  ```bash
270
- haive briefing # Full briefing, team scope
271
- haive briefing --task "add a Stripe payment" # Filter by task relevance
294
+ haive briefing # Full briefing, team scope
295
+ haive briefing --task "add a Stripe payment" # Filter by task relevance
272
296
  haive briefing --files src/payments/PaymentService.java # Filter by files
273
- haive briefing --scope all # Include personal memories
274
- haive briefing --include-stale # Include stale memories
275
- haive briefing --max-memories 15 # Show more memories
297
+ haive briefing --symbols PaymentService,TenantFilter # Look up symbol locations in code-map
298
+ haive briefing --scope all # Include personal memories
299
+ haive briefing --include-stale # Include stale memories
300
+ haive briefing --max-memories 15 # Show more memories
301
+ ```
302
+
303
+ **`--symbols` (requires `haive index code`):** look up where specific symbols are defined across your entire codebase — no grep needed. Returns file, line number, kind (class/interface/function/enum), and JSDoc description for each match.
304
+
305
+ ```
306
+ PaymentProvider src/payments/PaymentProvider.java:12 [interface] — Abstract payment provider
307
+ PaymentProvider src/frontend/payment.types.ts:4 [enum] — Mobile payment provider enum
276
308
  ```
277
309
 
278
310
  ---
@@ -337,13 +369,51 @@ The code map lets AI agents find where a function lives without grepping — dra
337
369
 
338
370
  ### `haive tui`
339
371
 
340
- Interactive terminal dashboard to browse, filter, and manage memories.
372
+ Interactive terminal dashboard with 3 screens — browse, filter, and manage memories without leaving the terminal.
341
373
 
342
374
  ```bash
343
- haive tui # Open the TUI (q to quit, arrow keys to navigate)
375
+ haive tui # Open the TUI
344
376
  haive tui --dir /path/to/project
345
377
  ```
346
378
 
379
+ **Screens (switch with `1` `2` `3`):**
380
+
381
+ | Screen | Key | What it shows |
382
+ |---|---|---|
383
+ | Memories | `1` | Full list + preview panel, filter by status (Tab), actions |
384
+ | Health | `2` | Stale memories, pending review, anchorless memories |
385
+ | Stats | `3` | Top-read memories, decaying (>90d unused), totals by status |
386
+
387
+ **Actions (in Memories screen):**
388
+
389
+ | Key | Action |
390
+ |---|---|
391
+ | `↑` `↓` | Navigate |
392
+ | `Tab` | Cycle filter (all / draft / proposed / validated / stale / rejected) |
393
+ | `a` | Approve (→ validated) |
394
+ | `r` | Reject |
395
+ | `p` | Propose (→ proposed) |
396
+ | `d` | Delete |
397
+ | `q` | Quit |
398
+
399
+ ---
400
+
401
+ ### `haive session end`
402
+
403
+ Save a structured end-of-session recap. Surfaced automatically at the start of the next session via `get_briefing`.
404
+
405
+ ```bash
406
+ haive session end \
407
+ --goal "Add Stripe payment integration" \
408
+ --accomplished "Implemented PaymentService, added tests, deployed to staging" \
409
+ --discoveries "The webhook signature must use the raw request body, not parsed JSON" \
410
+ --files "src/payments/PaymentService.ts,src/payments/webhook.ts" \
411
+ --next "Add retry logic for failed webhooks" \
412
+ --scope team
413
+ ```
414
+
415
+ One recap is kept per scope (topic-upsert: `revision_count` increments on each call).
416
+
347
417
  ---
348
418
 
349
419
  ## Memory lifecycle
@@ -5,6 +5,7 @@ import { useState, useEffect, useCallback } from "react";
5
5
  import { Box, Text, useInput, useApp } from "ink";
6
6
  import { existsSync } from "fs";
7
7
  import { writeFile, unlink } from "fs/promises";
8
+ import path from "path";
8
9
  import {
9
10
  getUsage,
10
11
  isDecaying,
@@ -83,13 +84,37 @@ function Dashboard({ root }) {
83
84
  serializeMemory({ frontmatter: { ...fm, status: newStatus }, body: selected.memory.body }),
84
85
  "utf8"
85
86
  );
86
- const label = newStatus === "validated" ? "\u2713 Approved" : newStatus === "rejected" ? "\u2717 Rejected" : "\u2191 Promoted";
87
- const color = newStatus === "validated" ? "green" : newStatus === "rejected" ? "red" : "yellow";
87
+ const label = newStatus === "validated" ? "\u2713 Approved" : "\u2717 Rejected";
88
+ const color = newStatus === "validated" ? "green" : "red";
88
89
  flash_(`${label}: ${fm.id.slice(0, 40)}`, color);
89
90
  const prev = cursor;
90
91
  await reload();
91
92
  setCursor(Math.min(prev, Math.max(0, filtered.length - 2)));
92
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]);
93
118
  const doDelete = useCallback(async () => {
94
119
  if (!selected) return;
95
120
  const fm = selected.memory.frontmatter;
@@ -125,7 +150,7 @@ function Dashboard({ root }) {
125
150
  }
126
151
  if (input === "a") void doStatusChange("validated");
127
152
  if (input === "r") void doStatusChange("rejected");
128
- if (input === "p") void doStatusChange("proposed");
153
+ if (input === "p") void doPromote();
129
154
  if (input === "d") void doDelete();
130
155
  }
131
156
  });
@@ -225,7 +250,7 @@ function Dashboard({ root }) {
225
250
  ] })
226
251
  ] }),
227
252
  /* @__PURE__ */ jsx(FlashBar, {}),
228
- /* @__PURE__ */ jsx(Box, { paddingX: 1, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2191\u2193 navigate [tab] filter [a] approve [r] reject [p] propose [d] delete" }) })
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" }) })
229
254
  ] });
230
255
  }
231
256
  if (screen === "health") {
@@ -333,4 +358,4 @@ function Dashboard({ root }) {
333
358
  export {
334
359
  Dashboard
335
360
  };
336
- //# sourceMappingURL=Dashboard-HVELRRC7.js.map
361
+ //# sourceMappingURL=Dashboard-Y2AIWFZK.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 \"@hiveai/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 `haive 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\">hAIve</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 `haive memory verify --update` to recheck anchors | `haive 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":[]}