pi-mega-compact 0.13.4 → 0.13.6

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.
Files changed (217) hide show
  1. package/README.md +11 -8
  2. package/dist/extensions/dashboard-server/api-contracts/endpoints/registry.js +50 -0
  3. package/dist/extensions/dashboard-server/api-contracts/rag-metrics.js +1 -0
  4. package/dist/extensions/dashboard-server/api-contracts/rag-settings.js +3 -3
  5. package/dist/extensions/dashboard-server/api-contracts/wiki.js +1 -0
  6. package/dist/extensions/dashboard-server/routes-rag-metrics.js +60 -0
  7. package/dist/extensions/dashboard-server/routes-rag-settings-helpers.js +167 -0
  8. package/dist/extensions/dashboard-server/routes-rag-settings.js +136 -77
  9. package/dist/extensions/dashboard-server/routes-wiki-helpers.js +97 -0
  10. package/dist/extensions/dashboard-server/routes-wiki.js +330 -0
  11. package/dist/extensions/dashboard-server/routes.js +2 -0
  12. package/dist/extensions/dashboard-server/server.js +17 -3
  13. package/dist/extensions/mega-events/context-handler/afterCompact.js +35 -2
  14. package/dist/extensions/mega-pipeline/recall.js +31 -0
  15. package/dist/extensions/mega-turn-store.js +2 -1
  16. package/dist/src/config/turns.js +10 -0
  17. package/dist/src/config.js +2 -0
  18. package/dist/src/recall/async.js +10 -1
  19. package/dist/src/recall/format.js +10 -1
  20. package/dist/src/recall/hydeTelemetry.js +22 -0
  21. package/dist/src/recall/sync.js +28 -2
  22. package/dist/src/store/turns/hydeStore.js +32 -0
  23. package/dist/src/store/turns/index.js +1 -0
  24. package/dist/src/store/turns/schema.js +102 -1
  25. package/dist/src/store/turns/sqlite-store/rows.js +23 -0
  26. package/dist/src/store/turns/sqlite-store/write.js +7 -3
  27. package/dist/src/topics/durability.js +187 -0
  28. package/dist/src/topics/index.js +2 -1
  29. package/dist/src/topics/store.js +28 -9
  30. package/dist/src/wiki/curation-helpers.js +71 -0
  31. package/dist/src/wiki/curation.js +147 -0
  32. package/dist/src/wiki/incremental.js +126 -0
  33. package/dist/src/wiki/index.js +5 -0
  34. package/extensions/dashboard-client/dist/assets/AreaChart-KAmp_6bL.js +70 -0
  35. package/extensions/dashboard-client/dist/assets/{SessionsTab-C30AwyoF.js.map → AreaChart-KAmp_6bL.js.map} +1 -1
  36. package/extensions/dashboard-client/dist/assets/CacheTab-Bk-gm-R0.js +2 -0
  37. package/extensions/dashboard-client/dist/assets/CacheTab-Bk-gm-R0.js.map +1 -0
  38. package/extensions/dashboard-client/dist/assets/EventsTab-Cyylo0of.js +2 -0
  39. package/extensions/dashboard-client/dist/assets/EventsTab-Cyylo0of.js.map +1 -0
  40. package/extensions/dashboard-client/dist/assets/HealthTab-D-IzmV29.js +2 -0
  41. package/extensions/dashboard-client/dist/assets/HealthTab-D-IzmV29.js.map +1 -0
  42. package/extensions/dashboard-client/dist/assets/MaintenanceTab-CrlkCFVj.js +2 -0
  43. package/extensions/dashboard-client/dist/assets/MaintenanceTab-CrlkCFVj.js.map +1 -0
  44. package/extensions/dashboard-client/dist/assets/MemoryMapTab-DHUdZ7RR.js +2 -0
  45. package/extensions/dashboard-client/dist/assets/MemoryMapTab-DHUdZ7RR.js.map +1 -0
  46. package/extensions/dashboard-client/dist/assets/MetricsTab-B7I4HWVg.js +2 -0
  47. package/extensions/dashboard-client/dist/assets/MetricsTab-B7I4HWVg.js.map +1 -0
  48. package/extensions/dashboard-client/dist/assets/OverviewTab-K6j4ZI7u.js +2 -0
  49. package/extensions/dashboard-client/dist/assets/OverviewTab-K6j4ZI7u.js.map +1 -0
  50. package/extensions/dashboard-client/dist/assets/ReposTab-BSRWhn56.js +2 -0
  51. package/extensions/dashboard-client/dist/assets/ReposTab-BSRWhn56.js.map +1 -0
  52. package/extensions/dashboard-client/dist/assets/SessionsTab-BXdizHN1.js +2 -0
  53. package/extensions/dashboard-client/dist/assets/SessionsTab-BXdizHN1.js.map +1 -0
  54. package/extensions/dashboard-client/dist/assets/SetupTab-CAgyfqY3.js +2 -0
  55. package/extensions/dashboard-client/dist/assets/SetupTab-CAgyfqY3.js.map +1 -0
  56. package/extensions/dashboard-client/dist/assets/TimeSavedCard-DwgCzPD9.js +2 -0
  57. package/extensions/dashboard-client/dist/assets/TimeSavedCard-DwgCzPD9.js.map +1 -0
  58. package/extensions/dashboard-client/dist/assets/TurnsTab-CVKcStBp.js +5 -0
  59. package/extensions/dashboard-client/dist/assets/TurnsTab-CVKcStBp.js.map +1 -0
  60. package/extensions/dashboard-client/dist/assets/WikiTab-BNohxTbs.js +2 -0
  61. package/extensions/dashboard-client/dist/assets/WikiTab-BNohxTbs.js.map +1 -0
  62. package/extensions/dashboard-client/dist/assets/button-B4A-_dCA.js +2 -0
  63. package/extensions/dashboard-client/dist/assets/button-B4A-_dCA.js.map +1 -0
  64. package/extensions/dashboard-client/dist/assets/card-Cjn7Ifoe.js +2 -0
  65. package/extensions/dashboard-client/dist/assets/card-Cjn7Ifoe.js.map +1 -0
  66. package/extensions/dashboard-client/dist/assets/index-CQjCLvv7.js +137 -0
  67. package/extensions/dashboard-client/dist/assets/index-CQjCLvv7.js.map +1 -0
  68. package/extensions/dashboard-client/dist/assets/index-CUA6EDRF.css +1 -0
  69. package/extensions/dashboard-client/dist/assets/switch-CcdXX0Zm.js +2 -0
  70. package/extensions/dashboard-client/dist/assets/switch-CcdXX0Zm.js.map +1 -0
  71. package/extensions/dashboard-client/dist/assets/toggle-KdBnFLu3.js +2 -0
  72. package/extensions/dashboard-client/dist/assets/toggle-KdBnFLu3.js.map +1 -0
  73. package/extensions/dashboard-client/dist/assets/{useSSE-p1pOI_-P.js → useSSE-B6t44vzc.js} +2 -2
  74. package/extensions/dashboard-client/dist/assets/{useSSE-p1pOI_-P.js.map → useSSE-B6t44vzc.js.map} +1 -1
  75. package/extensions/dashboard-client/dist/index.html +2 -2
  76. package/extensions/dashboard-client/package-lock.json +1995 -191
  77. package/extensions/dashboard-client/package.json +12 -1
  78. package/extensions/dashboard-client/postcss.config.js +6 -0
  79. package/extensions/dashboard-client/src/App.tsx +127 -88
  80. package/extensions/dashboard-client/src/api/client.ts +109 -10
  81. package/extensions/dashboard-client/src/components/ActiveReposTable.tsx +15 -7
  82. package/extensions/dashboard-client/src/components/ActiveSessionsTable.tsx +67 -55
  83. package/extensions/dashboard-client/src/components/CacheHitRateTrendCard.tsx +17 -13
  84. package/extensions/dashboard-client/src/components/CacheHitsCard.tsx +35 -30
  85. package/extensions/dashboard-client/src/components/CacheStatusPerModel.tsx +33 -28
  86. package/extensions/dashboard-client/src/components/EventCategoryFilter.tsx +5 -6
  87. package/extensions/dashboard-client/src/components/EventStream.tsx +17 -13
  88. package/extensions/dashboard-client/src/components/HydeDetailPanel.tsx +173 -0
  89. package/extensions/dashboard-client/src/components/LegendCard.tsx +16 -9
  90. package/extensions/dashboard-client/src/components/PerfCards.tsx +28 -20
  91. package/extensions/dashboard-client/src/components/PerfChart.tsx +9 -6
  92. package/extensions/dashboard-client/src/components/ProviderCacheCard.tsx +15 -7
  93. package/extensions/dashboard-client/src/components/RagDashboard.tsx +253 -0
  94. package/extensions/dashboard-client/src/components/RepoAllSessionsCard.tsx +15 -10
  95. package/extensions/dashboard-client/src/components/RepoContextStack.tsx +24 -16
  96. package/extensions/dashboard-client/src/components/RepoDetailModal.tsx +52 -49
  97. package/extensions/dashboard-client/src/components/RepoTable.tsx +26 -17
  98. package/extensions/dashboard-client/src/components/SessionContextGauges.tsx +11 -14
  99. package/extensions/dashboard-client/src/components/SessionInfo.tsx +20 -15
  100. package/extensions/dashboard-client/src/components/SessionsMemoryChart.tsx +8 -5
  101. package/extensions/dashboard-client/src/components/SummaryTiles.tsx +26 -17
  102. package/extensions/dashboard-client/src/components/TabBar.tsx +1 -3
  103. package/extensions/dashboard-client/src/components/layout/AppShell.tsx +42 -0
  104. package/extensions/dashboard-client/src/components/layout/BottomBar.tsx +88 -0
  105. package/extensions/dashboard-client/src/components/layout/Sidebar.tsx +83 -0
  106. package/extensions/dashboard-client/src/components/ui/badge.tsx +30 -0
  107. package/extensions/dashboard-client/src/components/ui/button.tsx +44 -0
  108. package/extensions/dashboard-client/src/components/ui/card.tsx +32 -0
  109. package/extensions/dashboard-client/src/components/ui/select.tsx +64 -0
  110. package/extensions/dashboard-client/src/components/ui/switch.tsx +26 -0
  111. package/extensions/dashboard-client/src/components/ui/tabs.tsx +36 -0
  112. package/extensions/dashboard-client/src/components/ui/toggle.tsx +28 -0
  113. package/extensions/dashboard-client/src/components/ui/tooltip.tsx +27 -0
  114. package/extensions/dashboard-client/src/config.ts +10 -0
  115. package/extensions/dashboard-client/src/main.tsx +2 -2
  116. package/extensions/dashboard-client/src/memory-map-layout.ts +1 -2
  117. package/extensions/dashboard-client/src/styles/index.css +79 -0
  118. package/extensions/dashboard-client/src/tabs/CacheTab.tsx +33 -26
  119. package/extensions/dashboard-client/src/tabs/EventsTab.tsx +22 -7
  120. package/extensions/dashboard-client/src/tabs/HealthTab.tsx +77 -46
  121. package/extensions/dashboard-client/src/tabs/MaintenanceTab/ActionsCard.tsx +60 -50
  122. package/extensions/dashboard-client/src/tabs/MaintenanceTab/DbStatsCard.tsx +61 -35
  123. package/extensions/dashboard-client/src/tabs/MaintenanceTab/DebugBundleCard.tsx +34 -23
  124. package/extensions/dashboard-client/src/tabs/MaintenanceTab/HealthMitigationCard.tsx +62 -43
  125. package/extensions/dashboard-client/src/tabs/MaintenanceTab/SchemaHealthCard.tsx +53 -32
  126. package/extensions/dashboard-client/src/tabs/MaintenanceTab.tsx +2 -2
  127. package/extensions/dashboard-client/src/tabs/MemoryMapTab/MemoryMapView.tsx +29 -46
  128. package/extensions/dashboard-client/src/tabs/MemoryMapTab/RaptorTreeView.tsx +10 -34
  129. package/extensions/dashboard-client/src/tabs/MemoryMapTab.tsx +14 -34
  130. package/extensions/dashboard-client/src/tabs/MetricsTab.tsx +5 -2
  131. package/extensions/dashboard-client/src/tabs/OverviewTab.tsx +11 -5
  132. package/extensions/dashboard-client/src/tabs/ReposTab.tsx +5 -5
  133. package/extensions/dashboard-client/src/tabs/SessionsTab.tsx +47 -33
  134. package/extensions/dashboard-client/src/tabs/SetupTab/EmbedderSetup.tsx +6 -2
  135. package/extensions/dashboard-client/src/tabs/SetupTab/RagHealthCard.tsx +78 -0
  136. package/extensions/dashboard-client/src/tabs/SetupTab/SettingsPanel.tsx +198 -0
  137. package/extensions/dashboard-client/src/tabs/SetupTab/SettingsSection.tsx +50 -0
  138. package/extensions/dashboard-client/src/tabs/SetupTab.tsx +21 -59
  139. package/extensions/dashboard-client/src/tabs/TopicsTab.tsx +75 -40
  140. package/extensions/dashboard-client/src/tabs/TurnsTab.tsx +150 -112
  141. package/extensions/dashboard-client/src/tabs/WikiTab/TopicEvolutionGraph.tsx +274 -0
  142. package/extensions/dashboard-client/src/tabs/WikiTab/TopicEvolutionView.tsx +71 -0
  143. package/extensions/dashboard-client/src/tabs/WikiTab/TopicTimeline.tsx +103 -0
  144. package/extensions/dashboard-client/src/tabs/WikiTab/WikiPage.tsx +213 -0
  145. package/extensions/dashboard-client/src/tabs/WikiTab/WikiPageControls.tsx +188 -0
  146. package/extensions/dashboard-client/src/tabs/WikiTab.tsx +222 -0
  147. package/extensions/dashboard-client/src/tabs/registry.ts +57 -0
  148. package/extensions/dashboard-client/src/utils/cn.ts +7 -0
  149. package/extensions/dashboard-client/tailwind.config.js +46 -0
  150. package/extensions/dashboard-server/api-contracts/core.ts +59 -0
  151. package/extensions/dashboard-server/api-contracts/endpoints/registry.ts +79 -0
  152. package/extensions/dashboard-server/api-contracts/index.ts +48 -2
  153. package/extensions/dashboard-server/api-contracts/rag-metrics.ts +22 -0
  154. package/extensions/dashboard-server/api-contracts/rag-settings.ts +30 -20
  155. package/extensions/dashboard-server/api-contracts/wiki.ts +138 -0
  156. package/extensions/dashboard-server/routes-rag-metrics.ts +82 -0
  157. package/extensions/dashboard-server/routes-rag-settings-helpers.ts +314 -0
  158. package/extensions/dashboard-server/routes-rag-settings.ts +147 -97
  159. package/extensions/dashboard-server/routes-wiki-helpers.ts +126 -0
  160. package/extensions/dashboard-server/routes-wiki.ts +376 -0
  161. package/extensions/dashboard-server/routes.ts +2 -0
  162. package/extensions/dashboard-server/server.ts +18 -2
  163. package/extensions/mega-events/context-handler/afterCompact.ts +44 -1
  164. package/extensions/mega-pipeline/recall.ts +31 -0
  165. package/extensions/mega-turn-store.ts +13 -0
  166. package/package.json +1 -1
  167. package/src/config/turns.ts +17 -0
  168. package/src/config.ts +3 -0
  169. package/src/recall/async.ts +10 -1
  170. package/src/recall/format.ts +15 -2
  171. package/src/recall/hydeTelemetry.ts +44 -0
  172. package/src/recall/sync.ts +34 -2
  173. package/src/recall/types.ts +36 -0
  174. package/src/store/turns/hydeStore.ts +82 -0
  175. package/src/store/turns/index.ts +4 -0
  176. package/src/store/turns/schema.ts +126 -1
  177. package/src/store/turns/sqlite-store/rows.ts +25 -0
  178. package/src/store/turns/sqlite-store/write.ts +20 -2
  179. package/src/store/turns/types.ts +33 -0
  180. package/src/topics/durability.ts +231 -0
  181. package/src/topics/index.ts +7 -1
  182. package/src/topics/store.ts +35 -9
  183. package/src/wiki/curation-helpers.ts +140 -0
  184. package/src/wiki/curation.ts +217 -0
  185. package/src/wiki/incremental.ts +164 -0
  186. package/src/wiki/index.ts +13 -0
  187. package/extensions/dashboard-client/dist/assets/CacheTab-Cqnc7lMg.js +0 -2
  188. package/extensions/dashboard-client/dist/assets/CacheTab-Cqnc7lMg.js.map +0 -1
  189. package/extensions/dashboard-client/dist/assets/EventsTab-tYk3VFAp.js +0 -2
  190. package/extensions/dashboard-client/dist/assets/EventsTab-tYk3VFAp.js.map +0 -1
  191. package/extensions/dashboard-client/dist/assets/HealthTab-D2_kjgxw.js +0 -2
  192. package/extensions/dashboard-client/dist/assets/HealthTab-D2_kjgxw.js.map +0 -1
  193. package/extensions/dashboard-client/dist/assets/MaintenanceTab-Bc-uPYrz.js +0 -2
  194. package/extensions/dashboard-client/dist/assets/MaintenanceTab-Bc-uPYrz.js.map +0 -1
  195. package/extensions/dashboard-client/dist/assets/MemoryMapTab-D1V9g_NC.js +0 -2
  196. package/extensions/dashboard-client/dist/assets/MemoryMapTab-D1V9g_NC.js.map +0 -1
  197. package/extensions/dashboard-client/dist/assets/MetricsTab-DT_XfL96.js +0 -2
  198. package/extensions/dashboard-client/dist/assets/MetricsTab-DT_XfL96.js.map +0 -1
  199. package/extensions/dashboard-client/dist/assets/OverviewTab-BY6KZCme.js +0 -2
  200. package/extensions/dashboard-client/dist/assets/OverviewTab-BY6KZCme.js.map +0 -1
  201. package/extensions/dashboard-client/dist/assets/ReposTab-CeS-tpDM.js +0 -2
  202. package/extensions/dashboard-client/dist/assets/ReposTab-CeS-tpDM.js.map +0 -1
  203. package/extensions/dashboard-client/dist/assets/SessionsTab-C30AwyoF.js +0 -70
  204. package/extensions/dashboard-client/dist/assets/SetupTab-BJUHOVK2.js +0 -2
  205. package/extensions/dashboard-client/dist/assets/SetupTab-BJUHOVK2.js.map +0 -1
  206. package/extensions/dashboard-client/dist/assets/TimeSavedCard-p55K1tFP.js +0 -2
  207. package/extensions/dashboard-client/dist/assets/TimeSavedCard-p55K1tFP.js.map +0 -1
  208. package/extensions/dashboard-client/dist/assets/TopicsTab-D8FqyAbK.js +0 -2
  209. package/extensions/dashboard-client/dist/assets/TopicsTab-D8FqyAbK.js.map +0 -1
  210. package/extensions/dashboard-client/dist/assets/TurnsTab-ju-nXDys.js +0 -2
  211. package/extensions/dashboard-client/dist/assets/TurnsTab-ju-nXDys.js.map +0 -1
  212. package/extensions/dashboard-client/dist/assets/index-BEj1Zahy.js +0 -42
  213. package/extensions/dashboard-client/dist/assets/index-BEj1Zahy.js.map +0 -1
  214. package/extensions/dashboard-client/dist/assets/index-CUNn22iV.css +0 -1
  215. package/extensions/dashboard-client/src/styles/metrics-extra.css +0 -69
  216. package/extensions/dashboard-client/src/styles/turns.css +0 -142
  217. package/extensions/dashboard-client/src/tabs/SetupTab/RagSettingsCard.tsx +0 -160
@@ -0,0 +1,222 @@
1
+ /**
2
+ * dashboard-client/src/tabs/WikiTab.tsx — Wiki Revival (W3): wiki landing list.
3
+ *
4
+ * Replaces TopicsTab in the App registry (TopicsTab.tsx kept, unused). Renders
5
+ * the wiki index: each auto-categorized topic with its resolved label (edited
6
+ * badge when user-renamed), member count, curation badges (label/merge/split),
7
+ * and a click-to-open that pushes a client-side page state to WikiPage.
8
+ *
9
+ * Styling is Tailwind + shadcn (Card, Badge, Button) — no legacy CSS classes.
10
+ */
11
+
12
+ import type React from "react";
13
+ import { useCallback, useMemo, useState } from "react";
14
+ import { useApi } from "../hooks/useApi";
15
+ import { fetchWikiIndex } from "../api/client";
16
+ import type { WikiIndexEntry, WikiIndexResponse } from "@contracts";
17
+ import { Badge } from "../components/ui/badge";
18
+ import { Button } from "../components/ui/button";
19
+ import { Toggle } from "../components/ui/toggle";
20
+ import WikiPage from "./WikiTab/WikiPage";
21
+ import TopicEvolutionView from "./WikiTab/TopicEvolutionView";
22
+
23
+ type WikiView = "list" | "evolution";
24
+
25
+ const KIND_BADGES: Record<string, "default" | "accent" | "warning"> = {
26
+ label: "accent",
27
+ merge: "warning",
28
+ split: "default",
29
+ };
30
+
31
+ function fmtTs(ms: number | null): string {
32
+ if (!ms) return "—";
33
+ return new Date(ms).toLocaleString();
34
+ }
35
+
36
+ function ViewToggle({
37
+ view,
38
+ onChange,
39
+ }: {
40
+ view: WikiView;
41
+ onChange: (v: WikiView) => void;
42
+ }): React.ReactElement {
43
+ return (
44
+ <div className="flex gap-1">
45
+ <Toggle pressed={view === "list"} onClick={() => onChange("list")}>
46
+ Topics
47
+ </Toggle>
48
+ <Toggle
49
+ pressed={view === "evolution"}
50
+ onClick={() => onChange("evolution")}
51
+ >
52
+ Evolution
53
+ </Toggle>
54
+ </div>
55
+ );
56
+ }
57
+
58
+ interface RowProps {
59
+ entry: WikiIndexEntry;
60
+ onOpen: (id: string) => void;
61
+ }
62
+
63
+ function TopicRow({ entry, onOpen }: RowProps): React.ReactElement {
64
+ return (
65
+ <tr className="border-b border-border/60 last:border-0 hover:bg-bg-elevated/40">
66
+ <td className="py-2 pr-3">
67
+ <div className="flex items-center gap-2">
68
+ <span className="font-medium text-foreground">{entry.label}</span>
69
+ {entry.edited && <Badge variant="outline">edited</Badge>}
70
+ </div>
71
+ </td>
72
+ <td className="py-2 pr-3 text-sm text-muted-foreground">
73
+ {entry.memoryCount}
74
+ </td>
75
+ <td className="py-2 pr-3">
76
+ <div className="flex flex-wrap gap-1">
77
+ {entry.overrideKinds.map((k) => (
78
+ <Badge key={k} variant={KIND_BADGES[k] ?? "default"}>
79
+ {k}
80
+ </Badge>
81
+ ))}
82
+ </div>
83
+ </td>
84
+ <td className="py-2 pr-3 text-xs text-muted-foreground">
85
+ {fmtTs(entry.lastUpdated)}
86
+ </td>
87
+ <td className="py-2 text-right">
88
+ <Button
89
+ variant="outline"
90
+ size="sm"
91
+ onClick={() => onOpen(entry.id)}
92
+ >
93
+ Open
94
+ </Button>
95
+ </td>
96
+ </tr>
97
+ );
98
+ }
99
+
100
+ export default function WikiTab(): React.ReactElement {
101
+ const { data, loading, error } = useApi<WikiIndexResponse>(
102
+ useCallback(() => fetchWikiIndex(), []),
103
+ { pollInterval: 30_000 },
104
+ );
105
+ const [view, setView] = useState<WikiView>("list");
106
+ const [query, setQuery] = useState("");
107
+ const [openId, setOpenId] = useState<string | null>(null);
108
+
109
+ const filtered = useMemo(() => {
110
+ if (!data) return [];
111
+ const q = query.trim().toLowerCase();
112
+ if (!q) return data.topics;
113
+ return data.topics.filter((t) =>
114
+ t.label.toLowerCase().includes(q),
115
+ );
116
+ }, [data, query]);
117
+
118
+ if (openId) {
119
+ return <WikiPage topicId={openId} onBack={() => setOpenId(null)} />;
120
+ }
121
+
122
+ if (view === "evolution") {
123
+ return (
124
+ <div className="flex flex-col gap-3">
125
+ <ViewToggle view={view} onChange={setView} />
126
+ <TopicEvolutionView />
127
+ </div>
128
+ );
129
+ }
130
+
131
+ if (error && !data) {
132
+ return (
133
+ <div className="rounded-lg border border-border bg-bg-card p-6 text-sm text-danger">
134
+ Error loading wiki: {error.message}
135
+ </div>
136
+ );
137
+ }
138
+ if (loading && !data) {
139
+ return (
140
+ <div className="rounded-lg border border-border bg-bg-card p-6 text-sm text-muted-foreground">
141
+ Loading wiki…
142
+ </div>
143
+ );
144
+ }
145
+ if (!data) {
146
+ return (
147
+ <div className="rounded-lg border border-border bg-bg-card p-6 text-sm text-muted-foreground">
148
+ No wiki data available.
149
+ </div>
150
+ );
151
+ }
152
+ if (data.totalTopics === 0) {
153
+ return (
154
+ <div className="rounded-lg border border-border bg-bg-card p-6 text-sm text-muted-foreground">
155
+ <h3 className="mb-2 font-heading text-base text-foreground">Wiki</h3>
156
+ <p>
157
+ No topics yet. Topics are auto-generated after every Nth compaction
158
+ from real memory embeddings (k-means + TF-IDF).
159
+ </p>
160
+ <p className="mt-2">Check back after a few more compaction cycles.</p>
161
+ </div>
162
+ );
163
+ }
164
+
165
+ return (
166
+ <div className="flex flex-col gap-4">
167
+ <div className="flex flex-wrap items-end justify-between gap-2">
168
+ <div className="flex items-center gap-3">
169
+ <ViewToggle view={view} onChange={setView} />
170
+ <div>
171
+ <h2 className="font-heading text-lg font-semibold">Wiki</h2>
172
+ <p className="text-sm text-muted-foreground">
173
+ {data.totalTopics} topic{data.totalTopics !== 1 ? "s" : ""} ·{" "}
174
+ {data.totalMemories} assigned memori
175
+ {data.totalMemories !== 1 ? "es" : "y"}
176
+ {data.lastRebuildAt != null && (
177
+ <> · last rebuild {fmtTs(data.lastRebuildAt)}</>
178
+ )}
179
+ </p>
180
+ </div>
181
+ </div>
182
+ <input
183
+ type="search"
184
+ placeholder="Filter topics by label…"
185
+ aria-label="Filter topics by label"
186
+ value={query}
187
+ onChange={(e) => setQuery(e.target.value)}
188
+ className="w-64 rounded-md border border-border bg-bg-elevated/50 px-3 py-2 text-sm outline-none transition-colors focus:border-primary"
189
+ />
190
+ </div>
191
+
192
+ <div className="overflow-x-auto rounded-lg border border-border bg-bg-card">
193
+ <table className="w-full table-fixed text-sm">
194
+ <thead>
195
+ <tr className="border-b border-border text-left text-xs uppercase text-muted-foreground">
196
+ <th className="w-1/3 px-4 py-2 font-medium">Label</th>
197
+ <th className="w-16 py-2 font-medium">Memories</th>
198
+ <th className="w-40 py-2 font-medium">Badges</th>
199
+ <th className="w-40 py-2 font-medium">Last updated</th>
200
+ <th className="w-20 py-2" />
201
+ </tr>
202
+ </thead>
203
+ <tbody>
204
+ {filtered.map((t) => (
205
+ <TopicRow key={t.id} entry={t} onOpen={setOpenId} />
206
+ ))}
207
+ {filtered.length === 0 && (
208
+ <tr>
209
+ <td
210
+ colSpan={5}
211
+ className="px-4 py-6 text-center text-muted-foreground"
212
+ >
213
+ No topics match "{query}".
214
+ </td>
215
+ </tr>
216
+ )}
217
+ </tbody>
218
+ </table>
219
+ </div>
220
+ </div>
221
+ );
222
+ }
@@ -0,0 +1,57 @@
1
+ import type { LucideIcon } from "lucide-react";
2
+ import {
3
+ LayoutGrid,
4
+ Database,
5
+ MessagesSquare,
6
+ GitBranch,
7
+ HeartPulse,
8
+ FolderGit2,
9
+ ScrollText,
10
+ Settings,
11
+ BarChart3,
12
+ BookOpen,
13
+ Wrench,
14
+ Network,
15
+ } from "lucide-react";
16
+
17
+ export type TabId =
18
+ | "overview"
19
+ | "repos"
20
+ | "events"
21
+ | "setup"
22
+ | "metrics"
23
+ | "cache"
24
+ | "sessions"
25
+ | "wiki"
26
+ | "turns"
27
+ | "maintenance"
28
+ | "memory-map"
29
+ | "health";
30
+
31
+ export interface TabDef {
32
+ id: TabId;
33
+ label: string;
34
+ icon: LucideIcon;
35
+ }
36
+
37
+ export const PRIMARY_TABS: TabDef[] = [
38
+ { id: "overview", label: "Overview", icon: LayoutGrid },
39
+ { id: "cache", label: "Cache", icon: Database },
40
+ { id: "sessions", label: "Sessions", icon: MessagesSquare },
41
+ { id: "turns", label: "Turns", icon: GitBranch },
42
+ { id: "health", label: "Health", icon: HeartPulse },
43
+ ];
44
+
45
+ export const ADVANCED_TABS: TabDef[] = [
46
+ { id: "repos", label: "Repos", icon: FolderGit2 },
47
+ { id: "events", label: "Events", icon: ScrollText },
48
+ { id: "setup", label: "Setup", icon: Settings },
49
+ { id: "metrics", label: "Metrics", icon: BarChart3 },
50
+ { id: "wiki", label: "Wiki", icon: BookOpen },
51
+ { id: "maintenance", label: "Maintenance", icon: Wrench },
52
+ { id: "memory-map", label: "Memory Map", icon: Network },
53
+ ];
54
+
55
+ export const ADVANCED_TAB_IDS: ReadonlySet<TabId> = new Set(
56
+ ADVANCED_TABS.map((t) => t.id),
57
+ );
@@ -0,0 +1,7 @@
1
+ import { clsx, type ClassValue } from "clsx";
2
+ import { twMerge } from "tailwind-merge";
3
+
4
+ /** Combine className inputs then de-duplicate/merge conflicting Tailwind classes. */
5
+ export function cn(...inputs: ClassValue[]): string {
6
+ return twMerge(clsx(inputs));
7
+ }
@@ -0,0 +1,46 @@
1
+ /** @type {import('tailwindcss').Config} */
2
+ export default {
3
+ darkMode: ["class"],
4
+ content: ["./index.html", "./src/**/*.{ts,tsx}"],
5
+ theme: {
6
+ container: {
7
+ center: true,
8
+ padding: "1.5rem",
9
+ screens: { "2xl": "1600px" },
10
+ },
11
+ extend: {
12
+ colors: {
13
+ background: "hsl(var(--bg))",
14
+ "bg-card": "hsl(var(--bg-card))",
15
+ "bg-elevated": "hsl(var(--bg-elevated))",
16
+ border: "hsl(var(--border))",
17
+ foreground: "hsl(var(--foreground))",
18
+ muted: { DEFAULT: "hsl(var(--muted))", foreground: "hsl(var(--foreground))" },
19
+ primary: {
20
+ DEFAULT: "hsl(var(--primary))",
21
+ foreground: "hsl(222 47% 5%)",
22
+ glow: "hsl(var(--primary-glow))",
23
+ },
24
+ success: "hsl(var(--success))",
25
+ warning: "hsl(var(--warning))",
26
+ danger: "hsl(var(--danger))",
27
+ accent: { DEFAULT: "hsl(var(--accent))", foreground: "hsl(222 47% 5%)" },
28
+ },
29
+ borderRadius: {
30
+ lg: "var(--radius)",
31
+ md: "calc(var(--radius) - 2px)",
32
+ sm: "calc(var(--radius) - 4px)",
33
+ },
34
+ fontFamily: {
35
+ sans: ['Inter', 'ui-sans-serif', 'system-ui', 'sans-serif'],
36
+ mono: ['"JetBrains Mono"', 'ui-monospace', 'monospace'],
37
+ heading: ['"JetBrains Mono"', 'ui-monospace', 'monospace'],
38
+ },
39
+ boxShadow: {
40
+ glow: "0 0 20px -4px hsl(var(--primary-glow) / 0.5)",
41
+ panel: "0 8px 30px -12px hsl(var(--bg) / 0.6)",
42
+ },
43
+ },
44
+ },
45
+ plugins: [],
46
+ };
@@ -205,6 +205,65 @@ export interface SseRecallInject {
205
205
  tokens: number;
206
206
  }
207
207
 
208
+ /**
209
+ * SSE event emitted on a recall pass when HyDE was considered (H1). Streamed
210
+ * via `GET /api/events`. Mirrors the metrics carried up from the recall core's
211
+ * `HydeInvocationInfo`.
212
+ */
213
+ export interface SseHydeExecuted {
214
+ /** Discriminator. Always `'hyde_executed'`. */
215
+ type: 'hyde_executed';
216
+ /** ISO 8601 timestamp of the event. */
217
+ ts: string;
218
+ /** Session identifier the recall ran in. */
219
+ sessionId: string;
220
+ /** True when HyDE ran (hypothetical doc generated + embedded + searched). */
221
+ ran: boolean;
222
+ /** True when HyDE was considered but explicitly skipped. */
223
+ skipped: boolean;
224
+ /** Human-readable reason: "ran" | "disabled" | "no-llm" | "generation-failed". */
225
+ reason: string;
226
+ /** The hypothetical answer document the LLM produced (truncated). */
227
+ hypotheticalDoc: string;
228
+ /** ms spent generating + embedding the hypothetical doc (0 when skipped). */
229
+ generationMs: number;
230
+ /** Hit count from the raw-query search before fusion. */
231
+ rawHitCount: number;
232
+ /** Hit count from the hypothetical-doc search before fusion. */
233
+ hydeHitCount: number;
234
+ /** Hit count of the RRF-fused result actually injected. */
235
+ fusedHitCount: number;
236
+ /** Lift = fusedHitCount / max(1, rawHitCount). */
237
+ lift: number;
238
+ }
239
+
240
+ /**
241
+ * SSE event emitted per recall pass with the recall-quality metrics (H1).
242
+ * Streamed via `GET /api/events`.
243
+ */
244
+ export interface SseRecallMetrics {
245
+ /** Discriminator. Always `'recall_metrics'`. */
246
+ type: 'recall_metrics';
247
+ /** ISO 8601 timestamp of the event. */
248
+ ts: string;
249
+ /** Session identifier the recall ran in. */
250
+ sessionId: string;
251
+ /** Number of hits injected for the turn. */
252
+ hitCount: number;
253
+ /** Weighted composite recall-quality score (0–1). */
254
+ score: number;
255
+ /** Whether the recall quality passed its thresholds. */
256
+ pass: boolean;
257
+ /** Relevance breakdown (0–1). */
258
+ relevance: number;
259
+ /** Coverage breakdown (0–1). */
260
+ coverage: number;
261
+ /** Diversity breakdown (0–1). */
262
+ diversity: number;
263
+ /** Specificity breakdown (0–1). */
264
+ specificity: number;
265
+ }
266
+
208
267
  /**
209
268
  * SSE event emitted when anchor messages are updated.
210
269
  *
@@ -24,6 +24,7 @@ import type {
24
24
  RagSettingsRequest,
25
25
  RagSettingsResponsePost,
26
26
  } from "../rag-settings.js";
27
+ import type { RagMetricsResponse } from "../rag-metrics.js";
27
28
  import type {
28
29
  TurnsResponse,
29
30
  ConversationTurnsResponse,
@@ -42,6 +43,16 @@ import type {
42
43
  SchemaHealthResponse,
43
44
  } from "../maintenance.js";
44
45
  import type { CacheStripesResponse } from "../cache-stripes.js";
46
+ import type {
47
+ WikiIndexResponse,
48
+ WikiPageResponse,
49
+ TopicEvolutionResponse,
50
+ TopicTimelineResponse,
51
+ RenameTopicRequest,
52
+ MergeTopicsRequest,
53
+ SplitTopicRequest,
54
+ CurationResult,
55
+ } from "../wiki.js";
45
56
  import type {
46
57
  GameScoreRow,
47
58
  GameScoresQuery,
@@ -262,6 +273,64 @@ export const ENDPOINTS = {
262
273
  description: "Member memories assigned to a wiki topic (drill-down).",
263
274
  } as const satisfies EndpointDef<"GET", undefined, TopicMemoriesResponse>,
264
275
 
276
+ // ─── Wiki Revival (W2) ───────────────────────────────────────────
277
+
278
+ /** GET /api/wiki/index — wiki landing page with resolved labels. */
279
+ wikiIndex: {
280
+ method: "GET",
281
+ path: "/api/wiki/index",
282
+ description:
283
+ "Wiki index: auto-categorized topics with resolved (override-aware) labels.",
284
+ } as const satisfies EndpointDef<"GET", undefined, WikiIndexResponse>,
285
+
286
+ /** GET /api/wiki/topic/:topicId — single topic page + provenance. */
287
+ wikiTopic: {
288
+ method: "GET",
289
+ path: "/api/wiki/topic/:topicId",
290
+ description:
291
+ "Single wiki topic page: summary, key memories, and memory provenance.",
292
+ } as const satisfies EndpointDef<"GET", undefined, WikiPageResponse>,
293
+
294
+ /** PUT /api/wiki/topic/:topicId/label — rename a topic (user curation). */
295
+ renameTopic: {
296
+ method: "PUT",
297
+ path: "/api/wiki/topic/:topicId/label",
298
+ description:
299
+ "Rename a wiki topic (persists a label override; emits wiki_topic_renamed).",
300
+ } as const satisfies EndpointDef<"PUT", RenameTopicRequest, CurationResult>,
301
+
302
+ /** POST /api/wiki/merge — merge one topic into another. */
303
+ mergeTopics: {
304
+ method: "POST",
305
+ path: "/api/wiki/merge",
306
+ description:
307
+ "Merge source topic into target (reassigns memories; emits wiki_topics_merged).",
308
+ } as const satisfies EndpointDef<"POST", MergeTopicsRequest, CurationResult>,
309
+
310
+ /** POST /api/wiki/topic/:topicId/split — split listed memories into a new topic. */
311
+ splitTopic: {
312
+ method: "POST",
313
+ path: "/api/wiki/topic/:topicId/split",
314
+ description:
315
+ "Split listed member memories into a new topic (emits wiki_topic_split).",
316
+ } as const satisfies EndpointDef<"POST", SplitTopicRequest, CurationResult>,
317
+
318
+ /** GET /api/wiki/topic/:topicId/timeline — per-topic time buckets. */
319
+ topicTimeline: {
320
+ method: "GET",
321
+ path: "/api/wiki/topic/:topicId/timeline",
322
+ description:
323
+ "Per-topic memory-assignment timeline buckets for charts.",
324
+ } as const satisfies EndpointDef<"GET", undefined, TopicTimelineResponse>,
325
+
326
+ /** GET /api/wiki/evolution — node/edge D3 evolution graph. */
327
+ topicEvolution: {
328
+ method: "GET",
329
+ path: "/api/wiki/evolution",
330
+ description:
331
+ "Topic evolution nodes + edges + time buckets from topic_evolution.",
332
+ } as const satisfies EndpointDef<"GET", undefined, TopicEvolutionResponse>,
333
+
265
334
  // ─── S49B Maintenance Tab ─────────────────────────────────────────
266
335
 
267
336
  /** GET /api/maintenance — DB stats (table row counts + storage). */
@@ -380,4 +449,14 @@ export const ENDPOINTS = {
380
449
  description:
381
450
  "Update RAG feature flag states by writing _DISABLED env vars to .mega-compact.env.",
382
451
  } as const satisfies EndpointDef<"POST", RagSettingsRequest, RagSettingsResponsePost>,
452
+
453
+ // ─── RAG Metrics (Sprint H2) ──────────────────────────────────────
454
+
455
+ /** GET /api/rag-metrics — HyDE + recall-quality telemetry aggregates. */
456
+ ragMetrics: {
457
+ method: "GET",
458
+ path: "/api/rag-metrics",
459
+ description:
460
+ "HyDE invocation + recall-quality telemetry: flags, totals, recent turns, and daily series.",
461
+ } as const satisfies EndpointDef<"GET", undefined, RagMetricsResponse>,
383
462
  } as const;
@@ -20,6 +20,8 @@ export type {
20
20
  SsePressureLifted,
21
21
  SseCheckpointPersisted,
22
22
  SseRecallInject,
23
+ SseHydeExecuted,
24
+ SseRecallMetrics,
23
25
  SseAnchorsUpdated,
24
26
  SseConfigUpdated,
25
27
  SseConfigPreset,
@@ -98,6 +100,8 @@ import type {
98
100
  SsePressureLifted,
99
101
  SseCheckpointPersisted,
100
102
  SseRecallInject,
103
+ SseHydeExecuted,
104
+ SseRecallMetrics,
101
105
  SseAnchorsUpdated,
102
106
  SseConfigUpdated,
103
107
  SseConfigPreset,
@@ -107,6 +111,13 @@ import type {
107
111
  SseSessionSample,
108
112
  } from "./core.js";
109
113
 
114
+ import type {
115
+ SseWikiRebuilt,
116
+ SseWikiTopicRenamed,
117
+ SseWikiTopicsMerged,
118
+ SseWikiTopicSplit,
119
+ } from "./wiki.js";
120
+
110
121
  // Endpoints registry (Sprint A1)
111
122
  export type {
112
123
  VersionResponse,
@@ -124,6 +135,7 @@ export type {
124
135
  PerfPercentile,
125
136
  PerfAverage,
126
137
  PerfLatest,
138
+ CacheHitSample,
127
139
  PerfCacheHit,
128
140
  PerfDiag,
129
141
  PerfQuery,
@@ -169,12 +181,18 @@ export type SseEvent =
169
181
  | SseCrewPresenceChanged
170
182
  | SseCrewTurnChanged
171
183
  | SseCrewBanditChosen
184
+ | SseHydeExecuted
185
+ | SseRecallMetrics
172
186
  | SseGameRitualStart
173
187
  | SseGameRitualStage
174
188
  | SseGameRitualEnd
175
189
  | SseGameModeChanged
176
190
  | SseGameRender
177
- | SseSessionSample;
191
+ | SseSessionSample
192
+ | SseWikiRebuilt
193
+ | SseWikiTopicRenamed
194
+ | SseWikiTopicsMerged
195
+ | SseWikiTopicSplit;
178
196
 
179
197
  // S49B — maintenance tab API
180
198
  export type {
@@ -233,10 +251,38 @@ export type {
233
251
  CacheStripesResponse,
234
252
  } from "./cache-stripes.js";
235
253
 
236
- // RAG Settings — feature flag toggles (B6)
254
+ // RAG Settings — comprehensive adjustable settings (B6)
237
255
  export type {
256
+ SettingState,
257
+ SettingsResponse,
258
+ SettingsUpdateRequest,
259
+ SettingsResponsePost,
238
260
  RagFlagState,
239
261
  RagSettingsResponse,
240
262
  RagSettingsRequest,
241
263
  RagSettingsResponsePost,
242
264
  } from "./rag-settings.js";
265
+
266
+ // RAG metrics — HyDE + recall-quality aggregations (H1/H2)
267
+ export type { RagMetricsResponse } from "./rag-metrics.js";
268
+
269
+ // W2 — wiki revival: curation + provenance
270
+ export type {
271
+ WikiIndexEntry,
272
+ WikiIndexResponse,
273
+ MemoryProvenance,
274
+ WikiPageResponse,
275
+ RenameTopicRequest,
276
+ MergeTopicsRequest,
277
+ SplitTopicRequest,
278
+ TopicTimelineResponse,
279
+ TopicEvolutionResponse,
280
+ TopicEvolutionNode,
281
+ TopicEvolutionEdge,
282
+ SseWikiRebuilt,
283
+ SseWikiTopicRenamed,
284
+ SseWikiTopicsMerged,
285
+ SseWikiTopicSplit,
286
+ WikiSseEvent,
287
+ } from "./wiki.js";
288
+ export type { CurationResult, OverrideKind, WikiCurationStore } from "../../../src/wiki/curation.js";
@@ -0,0 +1,22 @@
1
+ /**
2
+ * api-contracts/rag-metrics.ts — GET /api/rag-metrics response + HyDE/recall SSE
3
+ * event contracts (H1/H2).
4
+ */
5
+ import type { TurnTelemetryRow, DailyTelemetry } from "../../../src/store/turns/hydeStore.js";
6
+
7
+ export interface RagMetricsResponse {
8
+ flags: {
9
+ hydeEnabled: boolean;
10
+ recallMetricsEnabled: boolean;
11
+ };
12
+ totals: {
13
+ telemetryTurns: number;
14
+ hydeRanTurns: number;
15
+ avgLift: number;
16
+ avgScore: number | null;
17
+ avgGenerationMs: number;
18
+ recentPassRate: number;
19
+ };
20
+ recent: TurnTelemetryRow[];
21
+ daily: DailyTelemetry[];
22
+ }