@hiveai/cli 0.2.3 → 0.2.5
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/Dashboard-SRPCHP7Z.js +194 -0
- package/dist/Dashboard-SRPCHP7Z.js.map +1 -0
- package/dist/index.js +107 -61
- package/dist/index.js.map +1 -1
- package/package.json +7 -2
|
@@ -0,0 +1,194 @@
|
|
|
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 } from "fs/promises";
|
|
8
|
+
import {
|
|
9
|
+
loadMemoriesFromDir,
|
|
10
|
+
resolveHaivePaths,
|
|
11
|
+
serializeMemory
|
|
12
|
+
} from "@hiveai/core";
|
|
13
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
14
|
+
var FILTERS = ["all", "draft", "proposed", "validated", "stale", "rejected"];
|
|
15
|
+
var LIST_H = 12;
|
|
16
|
+
function statusColor(status) {
|
|
17
|
+
if (status === "validated") return "green";
|
|
18
|
+
if (status === "proposed" || status === "stale") return "yellow";
|
|
19
|
+
if (status === "rejected") return "red";
|
|
20
|
+
return void 0;
|
|
21
|
+
}
|
|
22
|
+
function Dashboard({ root }) {
|
|
23
|
+
const { exit } = useApp();
|
|
24
|
+
const paths = resolveHaivePaths(root);
|
|
25
|
+
const [memories, setMemories] = useState([]);
|
|
26
|
+
const [loading, setLoading] = useState(true);
|
|
27
|
+
const [filterIdx, setFilterIdx] = useState(0);
|
|
28
|
+
const [cursor, setCursor] = useState(0);
|
|
29
|
+
const [flash, setFlash] = useState(null);
|
|
30
|
+
const filter = FILTERS[filterIdx] ?? "all";
|
|
31
|
+
const reload = useCallback(async () => {
|
|
32
|
+
if (!existsSync(paths.memoriesDir)) {
|
|
33
|
+
setLoading(false);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
setMemories(await loadMemoriesFromDir(paths.memoriesDir));
|
|
37
|
+
setLoading(false);
|
|
38
|
+
}, [paths.memoriesDir]);
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
void reload();
|
|
41
|
+
}, [reload]);
|
|
42
|
+
const filtered = memories.filter((m) => {
|
|
43
|
+
const s2 = m.memory.frontmatter.status;
|
|
44
|
+
if (filter === "all") return s2 !== "rejected";
|
|
45
|
+
return s2 === filter;
|
|
46
|
+
});
|
|
47
|
+
const selected = filtered[cursor];
|
|
48
|
+
const counts = memories.reduce((acc, m) => {
|
|
49
|
+
const s2 = m.memory.frontmatter.status;
|
|
50
|
+
acc[s2] = (acc[s2] ?? 0) + 1;
|
|
51
|
+
return acc;
|
|
52
|
+
}, {});
|
|
53
|
+
const flash_ = (text, color = "green") => {
|
|
54
|
+
setFlash({ text, color });
|
|
55
|
+
setTimeout(() => setFlash(null), 2e3);
|
|
56
|
+
};
|
|
57
|
+
const doApprove = useCallback(async () => {
|
|
58
|
+
if (!selected) return;
|
|
59
|
+
const fm = selected.memory.frontmatter;
|
|
60
|
+
if (fm.status === "validated") {
|
|
61
|
+
flash_("Already validated");
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
await writeFile(
|
|
65
|
+
selected.filePath,
|
|
66
|
+
serializeMemory({ frontmatter: { ...fm, status: "validated" }, body: selected.memory.body }),
|
|
67
|
+
"utf8"
|
|
68
|
+
);
|
|
69
|
+
flash_(`\u2713 Approved ${fm.id.slice(0, 32)}\u2026`);
|
|
70
|
+
const prev = cursor;
|
|
71
|
+
await reload();
|
|
72
|
+
setCursor(prev);
|
|
73
|
+
}, [selected, cursor, reload]);
|
|
74
|
+
const doReject = useCallback(async () => {
|
|
75
|
+
if (!selected) return;
|
|
76
|
+
const fm = selected.memory.frontmatter;
|
|
77
|
+
if (fm.status === "rejected") {
|
|
78
|
+
flash_("Already rejected", "red");
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
await writeFile(
|
|
82
|
+
selected.filePath,
|
|
83
|
+
serializeMemory({ frontmatter: { ...fm, status: "rejected" }, body: selected.memory.body }),
|
|
84
|
+
"utf8"
|
|
85
|
+
);
|
|
86
|
+
flash_(`\u2717 Rejected ${fm.id.slice(0, 32)}\u2026`, "red");
|
|
87
|
+
await reload();
|
|
88
|
+
setCursor((c) => Math.min(c, Math.max(0, filtered.length - 2)));
|
|
89
|
+
}, [selected, filtered.length, reload]);
|
|
90
|
+
useInput((input, key) => {
|
|
91
|
+
if (input === "q") {
|
|
92
|
+
exit();
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
if (key.upArrow) setCursor((c) => Math.max(0, c - 1));
|
|
96
|
+
if (key.downArrow) setCursor((c) => Math.min(filtered.length - 1, c + 1));
|
|
97
|
+
if (key.tab) {
|
|
98
|
+
setFilterIdx((i) => (i + 1) % FILTERS.length);
|
|
99
|
+
setCursor(0);
|
|
100
|
+
}
|
|
101
|
+
if (input === "a") void doApprove();
|
|
102
|
+
if (input === "r") void doReject();
|
|
103
|
+
});
|
|
104
|
+
if (loading) {
|
|
105
|
+
return /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Loading memories\u2026" });
|
|
106
|
+
}
|
|
107
|
+
if (!existsSync(paths.memoriesDir)) {
|
|
108
|
+
return /* @__PURE__ */ jsx(Text, { color: "red", children: "No .ai/memories found \u2014 run `haive init` first." });
|
|
109
|
+
}
|
|
110
|
+
const half = Math.floor(LIST_H / 2);
|
|
111
|
+
const start = Math.max(0, Math.min(cursor - half, Math.max(0, filtered.length - LIST_H)));
|
|
112
|
+
const visible = filtered.slice(start, start + LIST_H);
|
|
113
|
+
const v = counts["validated"] ?? 0;
|
|
114
|
+
const p = counts["proposed"] ?? 0;
|
|
115
|
+
const d = counts["draft"] ?? 0;
|
|
116
|
+
const s = counts["stale"] ?? 0;
|
|
117
|
+
const rej = counts["rejected"] ?? 0;
|
|
118
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
119
|
+
/* @__PURE__ */ jsxs(Box, { borderStyle: "round", paddingX: 1, gap: 2, children: [
|
|
120
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "hAIve" }),
|
|
121
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: root }),
|
|
122
|
+
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
123
|
+
/* @__PURE__ */ jsxs(Text, { color: "green", children: [
|
|
124
|
+
"\u2713 ",
|
|
125
|
+
v
|
|
126
|
+
] }),
|
|
127
|
+
/* @__PURE__ */ jsx(Text, { children: " \xB7 " }),
|
|
128
|
+
/* @__PURE__ */ jsxs(Text, { color: p > 0 ? "yellow" : void 0, children: [
|
|
129
|
+
"~ ",
|
|
130
|
+
p
|
|
131
|
+
] }),
|
|
132
|
+
/* @__PURE__ */ jsx(Text, { children: " \xB7 " }),
|
|
133
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
134
|
+
"\xB7 ",
|
|
135
|
+
d
|
|
136
|
+
] }),
|
|
137
|
+
s > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
138
|
+
/* @__PURE__ */ jsx(Text, { children: " \xB7 " }),
|
|
139
|
+
/* @__PURE__ */ jsxs(Text, { color: "yellow", children: [
|
|
140
|
+
"\u26A0 ",
|
|
141
|
+
s
|
|
142
|
+
] })
|
|
143
|
+
] }),
|
|
144
|
+
rej > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
145
|
+
/* @__PURE__ */ jsx(Text, { children: " \xB7 " }),
|
|
146
|
+
/* @__PURE__ */ jsxs(Text, { color: "red", children: [
|
|
147
|
+
"\u2717 ",
|
|
148
|
+
rej
|
|
149
|
+
] })
|
|
150
|
+
] })
|
|
151
|
+
] }),
|
|
152
|
+
/* @__PURE__ */ jsxs(Box, { paddingX: 1, gap: 2, children: [
|
|
153
|
+
FILTERS.map((f) => /* @__PURE__ */ jsx(Text, { color: filter === f ? "cyan" : void 0, bold: filter === f, children: filter === f ? `[${f}]` : f }, f)),
|
|
154
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " tab\u2192cycle" })
|
|
155
|
+
] }),
|
|
156
|
+
/* @__PURE__ */ jsxs(Box, { children: [
|
|
157
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", width: 64, borderStyle: "single", paddingX: 1, children: [
|
|
158
|
+
/* @__PURE__ */ jsx(Text, { bold: true, dimColor: true, children: `MEMORIES ${filtered.length}/${memories.length}` }),
|
|
159
|
+
filtered.length === 0 ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: " (no memories)" }) : visible.map((m, vi) => {
|
|
160
|
+
const absIdx = start + vi;
|
|
161
|
+
const fm = m.memory.frontmatter;
|
|
162
|
+
const sel = absIdx === cursor;
|
|
163
|
+
const idShort = fm.id.length > 43 ? fm.id.slice(0, 40) + "\u2026" : fm.id;
|
|
164
|
+
return /* @__PURE__ */ jsxs(Box, { children: [
|
|
165
|
+
/* @__PURE__ */ jsxs(Text, { color: sel ? "cyan" : void 0, bold: sel, children: [
|
|
166
|
+
sel ? "\u25B6 " : " ",
|
|
167
|
+
idShort.padEnd(43)
|
|
168
|
+
] }),
|
|
169
|
+
/* @__PURE__ */ jsx(Text, { color: statusColor(fm.status), children: fm.status.slice(0, 9) })
|
|
170
|
+
] }, fm.id);
|
|
171
|
+
})
|
|
172
|
+
] }),
|
|
173
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", width: 36, borderStyle: "single", paddingX: 1, children: [
|
|
174
|
+
/* @__PURE__ */ jsx(Text, { bold: true, dimColor: true, children: "PREVIEW" }),
|
|
175
|
+
selected ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
176
|
+
/* @__PURE__ */ jsxs(Text, { color: "cyan", children: [
|
|
177
|
+
selected.memory.frontmatter.scope,
|
|
178
|
+
"/",
|
|
179
|
+
selected.memory.frontmatter.type
|
|
180
|
+
] }),
|
|
181
|
+
/* @__PURE__ */ jsx(Text, { color: statusColor(selected.memory.frontmatter.status), children: selected.memory.frontmatter.status }),
|
|
182
|
+
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
183
|
+
selected.memory.body.split("\n").slice(0, LIST_H - 1).map((line, i) => /* @__PURE__ */ jsx(Text, { wrap: "truncate-end", children: line || " " }, i))
|
|
184
|
+
] }) : /* @__PURE__ */ jsx(Text, { dimColor: true, children: "select a memory" })
|
|
185
|
+
] })
|
|
186
|
+
] }),
|
|
187
|
+
flash && /* @__PURE__ */ jsx(Box, { paddingX: 1, children: /* @__PURE__ */ jsx(Text, { color: flash.color, children: flash.text }) }),
|
|
188
|
+
/* @__PURE__ */ jsx(Box, { paddingX: 1, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2191\u2193 navigate [tab] filter [a] approve [r] reject [q] quit" }) })
|
|
189
|
+
] });
|
|
190
|
+
}
|
|
191
|
+
export {
|
|
192
|
+
Dashboard
|
|
193
|
+
};
|
|
194
|
+
//# sourceMappingURL=Dashboard-SRPCHP7Z.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 } from \"node:fs/promises\";\nimport {\n loadMemoriesFromDir,\n resolveHaivePaths,\n serializeMemory,\n type LoadedMemory,\n} from \"@hiveai/core\";\n\ntype FilterStatus = \"all\" | \"draft\" | \"proposed\" | \"validated\" | \"stale\" | \"rejected\";\nconst FILTERS: FilterStatus[] = [\"all\", \"draft\", \"proposed\", \"validated\", \"stale\", \"rejected\"];\nconst LIST_H = 12;\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 {\n root: string;\n}\n\nexport function Dashboard({ root }: Props) {\n const { exit } = useApp();\n const paths = resolveHaivePaths(root);\n\n const [memories, setMemories] = useState<LoadedMemory[]>([]);\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\" } | null>(null);\n\n const filter: FilterStatus = FILTERS[filterIdx] ?? \"all\";\n\n const reload = useCallback(async () => {\n if (!existsSync(paths.memoriesDir)) {\n setLoading(false);\n return;\n }\n setMemories(await loadMemoriesFromDir(paths.memoriesDir));\n setLoading(false);\n }, [paths.memoriesDir]);\n\n useEffect(() => {\n void reload();\n }, [reload]);\n\n const filtered = memories.filter((m) => {\n const s = m.memory.frontmatter.status;\n if (filter === \"all\") return s !== \"rejected\";\n return s === filter;\n });\n\n const selected = filtered[cursor];\n\n const counts = memories.reduce<Record<string, number>>((acc, m) => {\n const s = m.memory.frontmatter.status;\n acc[s] = (acc[s] ?? 0) + 1;\n return acc;\n }, {});\n\n const flash_ = (text: string, color: \"green\" | \"red\" = \"green\") => {\n setFlash({ text, color });\n setTimeout(() => setFlash(null), 2000);\n };\n\n const doApprove = useCallback(async () => {\n if (!selected) return;\n const fm = selected.memory.frontmatter;\n if (fm.status === \"validated\") { flash_(\"Already validated\"); return; }\n await writeFile(\n selected.filePath,\n serializeMemory({ frontmatter: { ...fm, status: \"validated\" as const }, body: selected.memory.body }),\n \"utf8\",\n );\n flash_(`✓ Approved ${fm.id.slice(0, 32)}…`);\n const prev = cursor;\n await reload();\n setCursor(prev);\n }, [selected, cursor, reload]);\n\n const doReject = useCallback(async () => {\n if (!selected) return;\n const fm = selected.memory.frontmatter;\n if (fm.status === \"rejected\") { flash_(\"Already rejected\", \"red\"); return; }\n await writeFile(\n selected.filePath,\n serializeMemory({ frontmatter: { ...fm, status: \"rejected\" as const }, body: selected.memory.body }),\n \"utf8\",\n );\n flash_(`✗ Rejected ${fm.id.slice(0, 32)}…`, \"red\");\n await reload();\n setCursor((c) => Math.min(c, Math.max(0, filtered.length - 2)));\n }, [selected, filtered.length, reload]);\n\n useInput((input, key) => {\n if (input === \"q\") { exit(); return; }\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) {\n setFilterIdx((i) => (i + 1) % FILTERS.length);\n setCursor(0);\n }\n if (input === \"a\") void doApprove();\n if (input === \"r\") void doReject();\n });\n\n if (loading) {\n return <Text dimColor>Loading memories…</Text>;\n }\n\n if (!existsSync(paths.memoriesDir)) {\n return <Text color=\"red\">No .ai/memories found — run `haive init` first.</Text>;\n }\n\n // Compute scrolling window\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 const v = counts[\"validated\"] ?? 0;\n const p = counts[\"proposed\"] ?? 0;\n const d = counts[\"draft\"] ?? 0;\n const s = counts[\"stale\"] ?? 0;\n const rej = counts[\"rejected\"] ?? 0;\n\n return (\n <Box flexDirection=\"column\">\n\n {/* ── Header ── */}\n <Box borderStyle=\"round\" paddingX={1} gap={2}>\n <Text bold color=\"cyan\">hAIve</Text>\n <Text dimColor>{root}</Text>\n <Text> </Text>\n <Text color=\"green\">✓ {v}</Text>\n <Text> · </Text>\n <Text color={p > 0 ? \"yellow\" : undefined}>~ {p}</Text>\n <Text> · </Text>\n <Text dimColor>· {d}</Text>\n {s > 0 && <><Text> · </Text><Text color=\"yellow\">⚠ {s}</Text></>}\n {rej > 0 && <><Text> · </Text><Text color=\"red\">✗ {rej}</Text></>}\n </Box>\n\n {/* ── Filter bar ── */}\n <Box paddingX={1} gap={2}>\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\n {/* List panel */}\n <Box flexDirection=\"column\" width={64} borderStyle=\"single\" paddingX={1}>\n <Text bold dimColor>{`MEMORIES ${filtered.length}/${memories.length}`}</Text>\n {filtered.length === 0 ? (\n <Text dimColor> (no memories)</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 panel */}\n <Box flexDirection=\"column\" width={36} borderStyle=\"single\" paddingX={1}>\n <Text bold dimColor>PREVIEW</Text>\n {selected ? (\n <>\n <Text color=\"cyan\">\n {selected.memory.frontmatter.scope}/{selected.memory.frontmatter.type}\n </Text>\n <Text color={statusColor(selected.memory.frontmatter.status)}>\n {selected.memory.frontmatter.status}\n </Text>\n <Text> </Text>\n {selected.memory.body\n .split(\"\\n\")\n .slice(0, LIST_H - 1)\n .map((line, i) => (\n <Text key={i} wrap=\"truncate-end\">\n {line || \" \"}\n </Text>\n ))}\n </>\n ) : (\n <Text dimColor>select a memory</Text>\n )}\n </Box>\n\n </Box>\n\n {/* ── Flash message ── */}\n {flash && (\n <Box paddingX={1}>\n <Text color={flash.color}>{flash.text}</Text>\n </Box>\n )}\n\n {/* ── Footer ── */}\n <Box paddingX={1}>\n <Text dimColor>\n ↑↓ navigate [tab] filter [a] approve [r] reject [q] quit\n </Text>\n </Box>\n\n </Box>\n );\n}\n"],"mappings":"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","names":["s"]}
|