pi-mega-compact 0.13.0 → 0.13.2

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 (212) hide show
  1. package/dist/extensions/dashboard-server/api-contracts/embedder-health.js +11 -0
  2. package/dist/extensions/dashboard-server/api-contracts/endpoints/registry.js +225 -0
  3. package/dist/extensions/dashboard-server/api-contracts/endpoints/types.js +1 -0
  4. package/dist/extensions/dashboard-server/api-contracts/endpoints.js +5 -224
  5. package/dist/extensions/dashboard-server/api-contracts/raptor.js +8 -0
  6. package/dist/extensions/dashboard-server/api-contracts.test/_helpers.js +32 -0
  7. package/dist/extensions/dashboard-server/routes-cache.test/_helpers.js +48 -0
  8. package/dist/extensions/dashboard-server/routes-embedder-health.js +67 -0
  9. package/dist/extensions/dashboard-server/routes-raptor.js +88 -0
  10. package/dist/extensions/dashboard-server/routes-setup.js +1 -1
  11. package/dist/extensions/dashboard-server/routes.js +2 -0
  12. package/dist/extensions/dashboard-server/server.js +5 -1
  13. package/dist/extensions/mega-cache-replay.test/_helpers.js +175 -0
  14. package/dist/extensions/mega-commands/dataCommands.js +151 -0
  15. package/dist/extensions/mega-commands/helpers.js +61 -0
  16. package/dist/extensions/mega-commands/historyCommands.js +97 -0
  17. package/dist/extensions/mega-commands/setupCommand.js +200 -0
  18. package/dist/extensions/mega-commands.js +14 -499
  19. package/dist/extensions/mega-compact-s38.test/_helpers.js +194 -0
  20. package/dist/extensions/mega-compact.js +12 -2
  21. package/dist/extensions/mega-compact.test/_helpers.js +225 -0
  22. package/dist/extensions/mega-events/agent-handlers/agentEndHandler.js +211 -0
  23. package/dist/extensions/mega-events/agent-handlers/turnEndHandler/cacheStripe.js +49 -0
  24. package/dist/extensions/mega-events/agent-handlers/turnEndHandler/contextHealth.js +33 -0
  25. package/dist/extensions/mega-events/agent-handlers/turnEndHandler/errorRetry.js +387 -0
  26. package/dist/extensions/mega-events/agent-handlers/turnEndHandler/event.js +7 -0
  27. package/dist/extensions/mega-events/agent-handlers/turnEndHandler/gameScoring.js +55 -0
  28. package/dist/extensions/mega-events/agent-handlers/turnEndHandler/lengthStop.js +12 -0
  29. package/dist/extensions/mega-events/agent-handlers/turnEndHandler/memoryReview.js +22 -0
  30. package/dist/extensions/mega-events/agent-handlers/turnEndHandler/recordTurnRow.js +38 -0
  31. package/dist/extensions/mega-events/agent-handlers/turnEndHandler.js +36 -0
  32. package/dist/extensions/mega-events/agent-handlers.js +4 -799
  33. package/dist/extensions/mega-events/context-handler/afterCompact.js +163 -0
  34. package/dist/extensions/mega-events/context-handler/messageText.js +12 -0
  35. package/dist/extensions/mega-events/context-handler/tailResult.js +46 -0
  36. package/dist/extensions/mega-events/context-handler.js +11 -198
  37. package/dist/extensions/mega-events/separated-prompt.test/_helpers.js +25 -0
  38. package/dist/src/config.js +2 -0
  39. package/dist/src/dedup-engine.test/_helpers.js +55 -0
  40. package/dist/src/e2e.test/_helpers.js +52 -0
  41. package/dist/src/embedder.js +1 -0
  42. package/dist/src/httpEmbedder.js +6 -0
  43. package/dist/src/hyde.js +146 -0
  44. package/dist/src/importance.test/_helpers.js +5 -0
  45. package/dist/src/memoryGraph/sources/checkpoints.js +78 -0
  46. package/dist/src/memoryGraph/sources/edges.js +17 -0
  47. package/dist/src/memoryGraph/sources/flags.js +22 -0
  48. package/dist/src/memoryGraph/sources/helpers.js +14 -0
  49. package/dist/src/memoryGraph/sources/memories.js +88 -0
  50. package/dist/src/memoryGraph/sources/raptor.js +26 -0
  51. package/dist/src/memoryGraph/sources/turns.js +176 -0
  52. package/dist/src/memoryGraph/sources.js +15 -441
  53. package/dist/src/memoryGraph-gates.test/_helpers.js +120 -0
  54. package/dist/src/ratio.bench.test/_helpers.js +198 -0
  55. package/dist/src/recall/async.js +112 -0
  56. package/dist/src/recall/format.js +149 -0
  57. package/dist/src/recall/memory.js +62 -0
  58. package/dist/src/recall/reformulate.js +82 -0
  59. package/dist/src/recall/sync.js +169 -0
  60. package/dist/src/recall/types.js +1 -0
  61. package/dist/src/recall.js +13 -530
  62. package/dist/src/store/sqlite/schema/core.js +232 -0
  63. package/dist/src/store/sqlite/schema/game.js +65 -0
  64. package/dist/src/store/sqlite/schema/plan-v2.js +107 -0
  65. package/dist/src/store/sqlite/schema/turns.js +59 -0
  66. package/dist/src/store/sqlite/schema.js +8 -441
  67. package/dist/src/store/turns/contract-compliance.test/_helpers.js +21 -0
  68. package/dist/src/store/turns/sqlite-store/admin.js +171 -0
  69. package/dist/src/store/turns/sqlite-store/ctx.js +1 -0
  70. package/dist/src/store/turns/sqlite-store/read.js +111 -0
  71. package/dist/src/store/turns/sqlite-store/rows.js +42 -0
  72. package/dist/src/store/turns/sqlite-store/write.js +102 -0
  73. package/dist/src/store/turns/sqlite-store.js +31 -367
  74. package/dist/src/vectorStore/class.js +356 -0
  75. package/dist/src/vectorStore/hash.js +10 -0
  76. package/dist/src/vectorStore/types.js +2 -0
  77. package/dist/src/vectorStore.js +8 -359
  78. package/dist/src/vectorStore.test/_helpers.js +17 -0
  79. package/extensions/dashboard-client/dist/assets/{CacheTab-BZNnKhh5.js → CacheTab-DPRHjYZ0.js} +2 -2
  80. package/extensions/dashboard-client/dist/assets/{CacheTab-BZNnKhh5.js.map → CacheTab-DPRHjYZ0.js.map} +1 -1
  81. package/extensions/dashboard-client/dist/assets/{EventsTab-CzF5L42U.js → EventsTab-CgwYq-Qf.js} +2 -2
  82. package/extensions/dashboard-client/dist/assets/{EventsTab-CzF5L42U.js.map → EventsTab-CgwYq-Qf.js.map} +1 -1
  83. package/extensions/dashboard-client/dist/assets/{HealthTab-BLpidMrX.js → HealthTab-BgOCjVzR.js} +2 -2
  84. package/extensions/dashboard-client/dist/assets/{HealthTab-BLpidMrX.js.map → HealthTab-BgOCjVzR.js.map} +1 -1
  85. package/extensions/dashboard-client/dist/assets/MaintenanceTab-Yw1yFpsy.js +2 -0
  86. package/extensions/dashboard-client/dist/assets/MaintenanceTab-Yw1yFpsy.js.map +1 -0
  87. package/extensions/dashboard-client/dist/assets/MemoryMapTab-yHUX7Yzi.js +2 -0
  88. package/extensions/dashboard-client/dist/assets/MemoryMapTab-yHUX7Yzi.js.map +1 -0
  89. package/extensions/dashboard-client/dist/assets/{MetricsTab-B0PCysqs.js → MetricsTab-CcH9fP8P.js} +2 -2
  90. package/extensions/dashboard-client/dist/assets/{MetricsTab-B0PCysqs.js.map → MetricsTab-CcH9fP8P.js.map} +1 -1
  91. package/extensions/dashboard-client/dist/assets/{OverviewTab-DsOhqFu4.js → OverviewTab-BOs8ZNev.js} +2 -2
  92. package/extensions/dashboard-client/dist/assets/{OverviewTab-DsOhqFu4.js.map → OverviewTab-BOs8ZNev.js.map} +1 -1
  93. package/extensions/dashboard-client/dist/assets/{ReposTab-B3YKYuOf.js → ReposTab-B-MfSPvg.js} +2 -2
  94. package/extensions/dashboard-client/dist/assets/{ReposTab-B3YKYuOf.js.map → ReposTab-B-MfSPvg.js.map} +1 -1
  95. package/extensions/dashboard-client/dist/assets/{SessionsTab-B96FWcrC.js → SessionsTab-BmeN649Q.js} +2 -2
  96. package/extensions/dashboard-client/dist/assets/{SessionsTab-B96FWcrC.js.map → SessionsTab-BmeN649Q.js.map} +1 -1
  97. package/extensions/dashboard-client/dist/assets/SetupTab-nOknoph5.js +2 -0
  98. package/extensions/dashboard-client/dist/assets/SetupTab-nOknoph5.js.map +1 -0
  99. package/extensions/dashboard-client/dist/assets/{TimeSavedCard-BfkUVTvA.js → TimeSavedCard-DnPg0L0z.js} +2 -2
  100. package/extensions/dashboard-client/dist/assets/{TimeSavedCard-BfkUVTvA.js.map → TimeSavedCard-DnPg0L0z.js.map} +1 -1
  101. package/extensions/dashboard-client/dist/assets/{TopicsTab-DLRsZmXJ.js → TopicsTab-BODHOg_b.js} +2 -2
  102. package/extensions/dashboard-client/dist/assets/{TopicsTab-DLRsZmXJ.js.map → TopicsTab-BODHOg_b.js.map} +1 -1
  103. package/extensions/dashboard-client/dist/assets/{TurnsTab-DKGU2Bf6.js → TurnsTab-BK0I7hKr.js} +2 -2
  104. package/extensions/dashboard-client/dist/assets/{TurnsTab-DKGU2Bf6.js.map → TurnsTab-BK0I7hKr.js.map} +1 -1
  105. package/extensions/dashboard-client/dist/assets/{index-D-lPLRWB.js → index-mOlljTFI.js} +10 -10
  106. package/extensions/dashboard-client/dist/assets/index-mOlljTFI.js.map +1 -0
  107. package/extensions/dashboard-client/dist/assets/{useSSE-ClbbcgIp.js → useSSE-BYOtv1-3.js} +2 -2
  108. package/extensions/dashboard-client/dist/assets/{useSSE-ClbbcgIp.js.map → useSSE-BYOtv1-3.js.map} +1 -1
  109. package/extensions/dashboard-client/dist/index.html +1 -1
  110. package/extensions/dashboard-client/src/App.tsx +0 -4
  111. package/extensions/dashboard-client/src/api/client.ts +16 -0
  112. package/extensions/dashboard-client/src/tabs/MaintenanceTab/ActionsCard.tsx +178 -0
  113. package/extensions/dashboard-client/src/tabs/MaintenanceTab/DbStatsCard.tsx +140 -0
  114. package/extensions/dashboard-client/src/tabs/MaintenanceTab/DebugBundleCard.tsx +109 -0
  115. package/extensions/dashboard-client/src/tabs/MaintenanceTab/HealthMitigationCard.tsx +98 -0
  116. package/extensions/dashboard-client/src/tabs/MaintenanceTab/SchemaHealthCard.tsx +108 -0
  117. package/extensions/dashboard-client/src/tabs/MaintenanceTab.tsx +12 -598
  118. package/extensions/dashboard-client/src/tabs/MemoryMapTab/MemoryMapView.tsx +476 -0
  119. package/extensions/dashboard-client/src/tabs/MemoryMapTab/RaptorTreeView.tsx +163 -0
  120. package/extensions/dashboard-client/src/tabs/MemoryMapTab.tsx +56 -466
  121. package/extensions/dashboard-client/src/tabs/SetupTab/EmbedderHealthCard.tsx +109 -0
  122. package/extensions/dashboard-client/src/tabs/SetupTab/EmbedderSetup.tsx +468 -0
  123. package/extensions/dashboard-client/src/tabs/SetupTab.tsx +23 -484
  124. package/extensions/dashboard-server/api-contracts/embedder-health.ts +32 -0
  125. package/extensions/dashboard-server/api-contracts/endpoints/registry.ts +360 -0
  126. package/extensions/dashboard-server/api-contracts/endpoints/types.ts +350 -0
  127. package/extensions/dashboard-server/api-contracts/endpoints.ts +27 -648
  128. package/extensions/dashboard-server/api-contracts/index.ts +6 -0
  129. package/extensions/dashboard-server/api-contracts/raptor.ts +49 -0
  130. package/extensions/dashboard-server/api-contracts.test/_helpers.ts +47 -0
  131. package/extensions/dashboard-server/routes-cache.test/_helpers.ts +94 -0
  132. package/extensions/dashboard-server/routes-embedder-health.ts +77 -0
  133. package/extensions/dashboard-server/routes-raptor.ts +128 -0
  134. package/extensions/dashboard-server/routes-setup.ts +1 -1
  135. package/extensions/dashboard-server/routes.ts +2 -0
  136. package/extensions/dashboard-server/server.ts +4 -0
  137. package/extensions/mega-cache-replay.test/_helpers.ts +188 -0
  138. package/extensions/mega-commands/dataCommands.ts +169 -0
  139. package/extensions/mega-commands/helpers.ts +62 -0
  140. package/extensions/mega-commands/historyCommands.ts +117 -0
  141. package/extensions/mega-commands/setupCommand.ts +235 -0
  142. package/extensions/mega-commands.ts +25 -538
  143. package/extensions/mega-compact-s38.test/_helpers.ts +201 -0
  144. package/extensions/mega-compact.test/_helpers.ts +237 -0
  145. package/extensions/mega-compact.ts +12 -2
  146. package/extensions/mega-events/agent-handlers/agentEndHandler.ts +238 -0
  147. package/extensions/mega-events/agent-handlers/turnEndHandler/cacheStripe.ts +74 -0
  148. package/extensions/mega-events/agent-handlers/turnEndHandler/contextHealth.ts +50 -0
  149. package/extensions/mega-events/agent-handlers/turnEndHandler/errorRetry.ts +421 -0
  150. package/extensions/mega-events/agent-handlers/turnEndHandler/event.ts +16 -0
  151. package/extensions/mega-events/agent-handlers/turnEndHandler/gameScoring.ts +73 -0
  152. package/extensions/mega-events/agent-handlers/turnEndHandler/lengthStop.ts +29 -0
  153. package/extensions/mega-events/agent-handlers/turnEndHandler/memoryReview.ts +42 -0
  154. package/extensions/mega-events/agent-handlers/turnEndHandler/recordTurnRow.ts +61 -0
  155. package/extensions/mega-events/agent-handlers/turnEndHandler.ts +64 -0
  156. package/extensions/mega-events/agent-handlers.ts +15 -861
  157. package/extensions/mega-events/context-handler/afterCompact.ts +213 -0
  158. package/extensions/mega-events/context-handler/messageText.ts +20 -0
  159. package/extensions/mega-events/context-handler/tailResult.ts +63 -0
  160. package/extensions/mega-events/context-handler.ts +17 -235
  161. package/extensions/mega-events/separated-prompt.test/_helpers.ts +35 -0
  162. package/package.json +1 -1
  163. package/src/config.ts +4 -0
  164. package/src/dedup-engine.test/_helpers.ts +79 -0
  165. package/src/e2e.test/_helpers.ts +59 -0
  166. package/src/embedder.ts +4 -0
  167. package/src/httpEmbedder.ts +7 -0
  168. package/src/hyde.ts +162 -0
  169. package/src/importance.test/_helpers.ts +5 -0
  170. package/src/memoryGraph/sources/checkpoints.ts +99 -0
  171. package/src/memoryGraph/sources/edges.ts +23 -0
  172. package/src/memoryGraph/sources/flags.ts +26 -0
  173. package/src/memoryGraph/sources/helpers.ts +13 -0
  174. package/src/memoryGraph/sources/memories.ts +108 -0
  175. package/src/memoryGraph/sources/raptor.ts +37 -0
  176. package/src/memoryGraph/sources/turns.ts +226 -0
  177. package/src/memoryGraph/sources.ts +19 -544
  178. package/src/memoryGraph-gates.test/_helpers.ts +164 -0
  179. package/src/ratio.bench.test/_helpers.ts +268 -0
  180. package/src/recall/async.ts +142 -0
  181. package/src/recall/format.ts +173 -0
  182. package/src/recall/memory.ts +90 -0
  183. package/src/recall/reformulate.ts +111 -0
  184. package/src/recall/sync.ts +196 -0
  185. package/src/recall/types.ts +63 -0
  186. package/src/recall.ts +25 -712
  187. package/src/store/sqlite/schema/core.ts +233 -0
  188. package/src/store/sqlite/schema/game.ts +66 -0
  189. package/src/store/sqlite/schema/plan-v2.ts +108 -0
  190. package/src/store/sqlite/schema/turns.ts +60 -0
  191. package/src/store/sqlite/schema.ts +13 -441
  192. package/src/store/turns/contract-compliance.test/_helpers.ts +38 -0
  193. package/src/store/turns/sqlite-store/admin.ts +249 -0
  194. package/src/store/turns/sqlite-store/ctx.ts +14 -0
  195. package/src/store/turns/sqlite-store/read.ts +174 -0
  196. package/src/store/turns/sqlite-store/rows.ts +55 -0
  197. package/src/store/turns/sqlite-store/write.ts +193 -0
  198. package/src/store/turns/sqlite-store.ts +33 -514
  199. package/src/vectorStore/class.ts +433 -0
  200. package/src/vectorStore/hash.ts +11 -0
  201. package/src/vectorStore/types.ts +58 -0
  202. package/src/vectorStore.test/_helpers.ts +20 -0
  203. package/src/vectorStore.ts +13 -489
  204. package/extensions/dashboard-client/dist/assets/ConfigTab-DG0WkuuG.js +0 -2
  205. package/extensions/dashboard-client/dist/assets/ConfigTab-DG0WkuuG.js.map +0 -1
  206. package/extensions/dashboard-client/dist/assets/MaintenanceTab-BQF7W7xX.js +0 -2
  207. package/extensions/dashboard-client/dist/assets/MaintenanceTab-BQF7W7xX.js.map +0 -1
  208. package/extensions/dashboard-client/dist/assets/MemoryMapTab-CPtHLv0A.js +0 -2
  209. package/extensions/dashboard-client/dist/assets/MemoryMapTab-CPtHLv0A.js.map +0 -1
  210. package/extensions/dashboard-client/dist/assets/SetupTab-hbzQ_NZv.js +0 -2
  211. package/extensions/dashboard-client/dist/assets/SetupTab-hbzQ_NZv.js.map +0 -1
  212. package/extensions/dashboard-client/dist/assets/index-D-lPLRWB.js.map +0 -1
@@ -1,612 +1,26 @@
1
1
  /**
2
2
  * dashboard-client/src/tabs/MaintenanceTab.tsx — Maintenance tab (v0.11.2 S49B).
3
3
  *
4
- * Three cards:
5
- * 1. Schema Health (schema version + integrity + column audit)
6
- * 2. DB Stats (file sizes + table row counts)
7
- * 3. Actions (one-time maintenance operations with results history)
8
- *
9
- * All three fetch independently; failures in one do not block the others.
4
+ * Delegate-shell (extensions split): three cards (Schema Health, DB Stats,
5
+ * Actions) plus the Debug Bundle and Health Mitigation cards. The heavy card
6
+ * components live in ./MaintenanceTab/* to keep every file under the extensions
7
+ * line limit. All cards fetch independently; failures in one do not block the
8
+ * others.
10
9
  */
11
10
 
12
11
  import type React from "react";
13
- import { useState, useCallback, useEffect } from "react";
12
+ import { useCallback } from "react";
14
13
  import type {
15
14
  DbStatsResponse,
16
15
  SchemaHealthResponse,
17
- MaintenanceAction,
18
- MaintenanceActionResult,
19
- DebugBundleResponse,
20
16
  } from "@contracts";
21
17
  import { useApi } from "../hooks/useApi";
22
- import {
23
- fetchDbStats,
24
- fetchSchemaHealth,
25
- postMaintenanceAction,
26
- fetchDebugBundle,
27
- } from "../api/client";
28
-
29
- // ---------------------------------------------------------------------------
30
- // Action config
31
- // ---------------------------------------------------------------------------
32
-
33
- interface ActionDef {
34
- key: string;
35
- label: string;
36
- desc: string;
37
- dangerous: boolean;
38
- confirm?: string;
39
- daysOld?: boolean;
40
- }
41
-
42
- const ACTIONS: ActionDef[] = [
43
- {
44
- key: "integrity-check",
45
- label: "Integrity Check",
46
- desc: "Run PRAGMA integrity_check",
47
- dangerous: false,
48
- },
49
- {
50
- key: "reconcile-dedup",
51
- label: "Reconcile Dedup Mirror",
52
- desc: "Fix orphan dedup rows + backfill refs",
53
- dangerous: false,
54
- confirm: "Reconcile dedup_mirror (safe read/write)?",
55
- },
56
- {
57
- key: "checkpoint",
58
- label: "WAL Checkpoint",
59
- desc: "Merge WAL into main DB (read-only)",
60
- dangerous: false,
61
- },
62
- {
63
- key: "vacuum",
64
- label: "VACUUM",
65
- desc: "Rebuild DB reclaiming free pages",
66
- dangerous: true,
67
- confirm: "VACUUM rewrites the entire DB. Continue?",
68
- },
69
- {
70
- key: "reindex",
71
- label: "REINDEX",
72
- desc: "Rebuild all indexes",
73
- dangerous: true,
74
- confirm: "REINDEX rebuilds indexes. Continue?",
75
- },
76
- {
77
- key: "fts5-rebuild",
78
- label: "FTS5 Rebuild",
79
- desc: "Rebuild full-text search index",
80
- dangerous: true,
81
- confirm: "Rebuild FTS5 trigram index. Continue?",
82
- },
83
- {
84
- key: "prune",
85
- label: "Prune Old Rows",
86
- desc: "Delete transcripts + epochs older than N days",
87
- dangerous: true,
88
- daysOld: true,
89
- confirm: "Delete old raw_transcript rows. Continue?",
90
- },
91
- ];
92
-
93
- // ---------------------------------------------------------------------------
94
- // Format helpers (local — matches html.ts fmtBytes)
95
- // ---------------------------------------------------------------------------
96
-
97
- function fmtBytes(b: number): string {
98
- if (b < 1024) return `${b} B`;
99
- if (b < 1024 * 1024) return `${(b / 1024).toFixed(1)} KB`;
100
- return `${(b / (1024 * 1024)).toFixed(1)} MB`;
101
- }
102
-
103
- // ---------------------------------------------------------------------------
104
- // DB Stats card
105
- // ---------------------------------------------------------------------------
106
-
107
- function FileSizesCard({
108
- files,
109
- pageSize,
110
- pageCount,
111
- freelistPages,
112
- }: {
113
- files: DbStatsResponse["storage"]["files"];
114
- pageSize: number;
115
- pageCount: number;
116
- freelistPages: number;
117
- }): React.ReactElement {
118
- const total = files.dbBytes + files.walBytes + files.shmBytes;
119
- return (
120
- <div className="stat-section">
121
- <div className="stat-label">File Sizes</div>
122
- <table className="compact-table">
123
- <tbody>
124
- <tr>
125
- <td>sqlite.db</td>
126
- <td className="num">{fmtBytes(files.dbBytes)}</td>
127
- </tr>
128
- {files.walBytes > 0 && (
129
- <tr>
130
- <td>.wal</td>
131
- <td className="num">{fmtBytes(files.walBytes)}</td>
132
- </tr>
133
- )}
134
- {files.shmBytes > 0 && (
135
- <tr>
136
- <td>.shm</td>
137
- <td className="num">{fmtBytes(files.shmBytes)}</td>
138
- </tr>
139
- )}
140
- <tr>
141
- <td>Total</td>
142
- <td className="num">{fmtBytes(total)}</td>
143
- </tr>
144
- <tr>
145
- <td>Page size</td>
146
- <td className="num">{fmtBytes(pageSize)}</td>
147
- </tr>
148
- <tr>
149
- <td>Pages</td>
150
- <td className="num">
151
- {pageCount.toLocaleString()} ({freelistPages.toLocaleString()}{" "}
152
- free)
153
- </td>
154
- </tr>
155
- </tbody>
156
- </table>
157
- </div>
158
- );
159
- }
160
-
161
- function TableRowCountsCard({
162
- tables,
163
- }: {
164
- tables: DbStatsResponse["tables"];
165
- }): React.ReactElement {
166
- const totalRows = tables.reduce((s, t) => s + Math.max(0, t.rowCount), 0);
167
- return (
168
- <div className="stat-section">
169
- <div className="stat-label">
170
- Table Row Counts ({totalRows.toLocaleString()} total)
171
- </div>
172
- <table className="compact-table">
173
- <thead>
174
- <tr>
175
- <th>Table</th>
176
- <th className="num">Rows</th>
177
- </tr>
178
- </thead>
179
- <tbody>
180
- {tables.map((t) => (
181
- <tr key={t.table}>
182
- <td>{t.table}</td>
183
- <td className="num">
184
- {t.rowCount >= 0 ? t.rowCount.toLocaleString() : "—"}
185
- </td>
186
- </tr>
187
- ))}
188
- </tbody>
189
- </table>
190
- </div>
191
- );
192
- }
193
-
194
- function DbStatsCard({
195
- data,
196
- loading,
197
- error,
198
- }: {
199
- data: DbStatsResponse | null;
200
- loading: boolean;
201
- error: Error | null;
202
- }): React.ReactElement {
203
- return (
204
- <div className="card">
205
- <div className="card-header">DB Stats</div>
206
- <div className="card-body">
207
- {loading && !data && <span className="text-muted">Loading…</span>}
208
- {error && !data && <span className="text-error">{error.message}</span>}
209
- {data && (
210
- <>
211
- <FileSizesCard
212
- files={data.storage.files}
213
- pageSize={data.storage.pageSize}
214
- pageCount={data.storage.pageCount}
215
- freelistPages={data.storage.freelistPages}
216
- />
217
- <TableRowCountsCard tables={data.tables} />
218
- </>
219
- )}
220
- </div>
221
- </div>
222
- );
223
- }
224
-
225
- // ---------------------------------------------------------------------------
226
- // Schema Health card
227
- // ---------------------------------------------------------------------------
228
-
229
- function ColumnAuditCard({
230
- columns,
231
- }: {
232
- columns: SchemaHealthResponse["columns"];
233
- }): React.ReactElement {
234
- const missing = columns.filter((c) => !c.present);
235
- return (
236
- <div className="stat-section">
237
- <div className="stat-label">
238
- Column Audit ({columns.length} columns, {missing.length} missing)
239
- </div>
240
- <table className="compact-table">
241
- <thead>
242
- <tr>
243
- <th>Table</th>
244
- <th>Column</th>
245
- <th>Decl</th>
246
- <th>Status</th>
247
- </tr>
248
- </thead>
249
- <tbody>
250
- {columns.map((c) => (
251
- <tr key={`${c.table}.${c.column}`}>
252
- <td>{c.table}</td>
253
- <td>{c.column}</td>
254
- <td className="text-mono">{c.expectedDecl}</td>
255
- <td className={c.present ? "text-ok" : "text-error"}>
256
- {c.present ? "✓" : "MISSING"}
257
- </td>
258
- </tr>
259
- ))}
260
- </tbody>
261
- </table>
262
- </div>
263
- );
264
- }
265
-
266
- function SchemaHealthCard({
267
- data,
268
- loading,
269
- error,
270
- }: {
271
- data: SchemaHealthResponse | null;
272
- loading: boolean;
273
- error: Error | null;
274
- }): React.ReactElement {
275
- return (
276
- <div className="card">
277
- <div className="card-header">
278
- Schema Health
279
- {data && (
280
- <span className={`badge ${data.healthy ? "badge-ok" : "badge-bad"}`}>
281
- {data.healthy ? "HEALTHY" : "DEGRADED"}
282
- </span>
283
- )}
284
- </div>
285
- <div className="card-body">
286
- {loading && !data && <span className="text-muted">Loading…</span>}
287
- {error && !data && <span className="text-error">{error.message}</span>}
288
- {data && (
289
- <>
290
- <div className="stat-row">
291
- <span className="stat-label">Schema version</span>
292
- <span className="num">{data.schemaVersion}</span>
293
- </div>
294
- <div className="stat-row">
295
- <span className="stat-label">Integrity</span>
296
- <span
297
- className={
298
- data.integrity[0] === "ok" ? "text-ok" : "text-error"
299
- }
300
- >
301
- {data.integrity.join("; ")}
302
- </span>
303
- </div>
304
- <ColumnAuditCard columns={data.columns} />
305
- {data.fkCheck.length > 0 && (
306
- <div className="stat-section">
307
- <div className="stat-label text-warn">
308
- FK Check ({data.fkCheck.length})
309
- </div>
310
- {data.fkCheck.map((line, i) => (
311
- <div key={i} className="text-warn text-mono">
312
- {line}
313
- </div>
314
- ))}
315
- </div>
316
- )}
317
- </>
318
- )}
319
- </div>
320
- </div>
321
- );
322
- }
323
-
324
- // ---------------------------------------------------------------------------
325
- // Actions card
326
- // ---------------------------------------------------------------------------
327
-
328
- function ActionsCard(): React.ReactElement {
329
- const [results, setResults] = useState<MaintenanceActionResult[]>([]);
330
- const [running, setRunning] = useState<string | null>(null);
331
- const [days, setDays] = useState("30");
332
-
333
- const handleAction = useCallback(
334
- async (def: ActionDef) => {
335
- const action: MaintenanceAction = def.daysOld
336
- ? { action: "prune", daysOld: Number(days) }
337
- : ({ action: def.key } as MaintenanceAction);
338
-
339
- setRunning(def.key);
340
- try {
341
- const res = await postMaintenanceAction(action);
342
- setResults((prev) =>
343
- [{ ...res, timestamp: Date.now() }, ...prev].slice(0, 20),
344
- );
345
- } catch (err) {
346
- setResults((prev) =>
347
- [
348
- {
349
- operation: def.key,
350
- success: false,
351
- affected: 0,
352
- reclaimedBytes: 0,
353
- summary: err instanceof Error ? err.message : String(err),
354
- timestamp: Date.now(),
355
- },
356
- ...prev,
357
- ].slice(0, 20),
358
- );
359
- } finally {
360
- setRunning(null);
361
- }
362
- },
363
- [days],
364
- );
365
-
366
- return (
367
- <div className="card">
368
- <div className="card-header">Actions</div>
369
- <div className="card-body">
370
- <div className="action-grid">
371
- {ACTIONS.map((def) => {
372
- const isRunning = running === def.key;
373
- const lastResult = results.find((r) => r.operation === def.key);
374
- return (
375
- <div key={def.key} className="action-item">
376
- <div className="action-info">
377
- <div className="action-label">
378
- {def.label}
379
- {def.dangerous && (
380
- <span className="badge badge-warn">DESTRUCTIVE</span>
381
- )}
382
- </div>
383
- <div className="action-desc">{def.desc}</div>
384
- {lastResult && (
385
- <div
386
- className={`action-result ${lastResult.success ? "text-ok" : "text-error"}`}
387
- >
388
- {lastResult.summary}
389
- </div>
390
- )}
391
- </div>
392
- <div className="action-controls">
393
- {def.daysOld && (
394
- <input
395
- type="number"
396
- min={1}
397
- max={365}
398
- value={days}
399
- onChange={(e) => setDays(e.target.value)}
400
- className="days-input"
401
- disabled={isRunning}
402
- />
403
- )}
404
- <button
405
- className={`btn ${def.dangerous ? "btn-danger" : "btn-primary"}`}
406
- disabled={running !== null}
407
- onClick={() => {
408
- if (def.confirm && !window.confirm(def.confirm)) return;
409
- handleAction(def);
410
- }}
411
- >
412
- {isRunning ? "Running…" : "Run"}
413
- </button>
414
- </div>
415
- </div>
416
- );
417
- })}
418
- </div>
419
- </div>
420
- </div>
421
- );
422
- }
423
-
424
- // ---------------------------------------------------------------------------
425
- // Debug bundle card — gather diagnostic info for bug reports
426
- // ---------------------------------------------------------------------------
427
-
428
- function DebugBundleCard(): React.ReactElement {
429
- const [bundle, setBundle] = useState<DebugBundleResponse | null>(null);
430
- const [loading, setLoading] = useState(false);
431
- const [error, setError] = useState<string | null>(null);
432
- const [showJson, setShowJson] = useState(false);
433
-
434
- const gather = useCallback(async () => {
435
- setLoading(true);
436
- setError(null);
437
- try {
438
- const res = await fetchDebugBundle();
439
- setBundle(res);
440
- setShowJson(true);
441
- } catch (err) {
442
- setError(err instanceof Error ? err.message : String(err));
443
- } finally {
444
- setLoading(false);
445
- }
446
- }, []);
447
-
448
- const copyToClipboard = useCallback(() => {
449
- if (!bundle) return;
450
- const text = JSON.stringify(bundle, null, 2);
451
- void navigator.clipboard.writeText(text).catch(() => {});
452
- }, [bundle]);
453
-
454
- const downloadJson = useCallback(() => {
455
- if (!bundle) return;
456
- const text = JSON.stringify(bundle, null, 2);
457
- const blob = new Blob([text], { type: "application/json" });
458
- const url = URL.createObjectURL(blob);
459
- const a = document.createElement("a");
460
- a.href = url;
461
- a.download = `mega-compact-debug-bundle-${bundle.builtAt}.json`;
462
- a.click();
463
- URL.revokeObjectURL(url);
464
- }, [bundle]);
465
-
466
- const criticalCount = bundle?.criticalEvents.length ?? 0;
467
-
468
- return (
469
- <div className="card">
470
- <div className="card-header">
471
- Debug Bundle
472
- {criticalCount > 0 && (
473
- <span className="text-warn" style={{ marginLeft: "1em" }}>
474
- {criticalCount} critical event{criticalCount !== 1 ? "s" : ""} found
475
- </span>
476
- )}
477
- </div>
478
- <div className="card-body">
479
- <p className="text-muted" style={{ marginBottom: "0.75em" }}>
480
- Gather a diagnostic bundle (recent events, config flags, schema health,
481
- store stats) to attach to a bug report. Critical/compaction events are
482
- highlighted.
483
- </p>
484
- <button onClick={gather} disabled={loading} style={{ marginRight: "0.5em" }}>
485
- {loading ? "Gathering…" : "Gather Debug Logs"}
486
- </button>
487
- {error && <div className="text-error">{error}</div>}
488
- {bundle && showJson && (
489
- <>
490
- <div style={{ marginTop: "0.75em", marginBottom: "0.5em" }}>
491
- <button onClick={copyToClipboard} style={{ marginRight: "0.5em" }}>
492
- Copy to clipboard
493
- </button>
494
- <button onClick={downloadJson}>Download JSON</button>
495
- <button
496
- onClick={() => setShowJson((v) => !v)}
497
- style={{ marginLeft: "0.5em" }}
498
- >
499
- {showJson ? "Hide" : "Show"}
500
- </button>
501
- </div>
502
- {criticalCount > 0 && (
503
- <div className="stat-section">
504
- <div className="stat-label text-warn">
505
- Critical events ({criticalCount})
506
- </div>
507
- <pre className="text-mono" style={{ maxHeight: "12em", overflow: "auto" }}>
508
- {JSON.stringify(bundle.criticalEvents, null, 2)}
509
- </pre>
510
- </div>
511
- )}
512
- <pre className="text-mono" style={{ maxHeight: "24em", overflow: "auto" }}>
513
- {JSON.stringify(bundle, null, 2)}
514
- </pre>
515
- </>
516
- )}
517
- </div>
518
- </div>
519
- );
520
- }
521
-
522
- // ---------------------------------------------------------------------------
523
- // Health Mitigation card — toggle auto-mitigation for degraded context
524
- // ---------------------------------------------------------------------------
525
-
526
- function HealthMitigationCard(): React.ReactElement {
527
- const [mitigate, setMitigate] = useState(false);
528
- const [loading, setLoading] = useState(true);
529
- const [saving, setSaving] = useState(false);
530
- const [error, setError] = useState<string | null>(null);
531
-
532
- const load = useCallback(async () => {
533
- try {
534
- const { fetchHealthSettings } = await import("../api/health");
535
- const s = await fetchHealthSettings();
536
- setMitigate(s.mitigate);
537
- } catch (e) {
538
- setError(e instanceof Error ? e.message : String(e));
539
- } finally {
540
- setLoading(false);
541
- }
542
- }, []);
543
-
544
- useEffect(() => { void load(); }, [load]);
545
-
546
- const toggle = useCallback(async () => {
547
- setSaving(true);
548
- setError(null);
549
- try {
550
- const { setHealthMitigate } = await import("../api/health");
551
- const next = !mitigate;
552
- await setHealthMitigate(next);
553
- setMitigate(next);
554
- } catch (e) {
555
- setError(e instanceof Error ? e.message : String(e));
556
- } finally {
557
- setSaving(false);
558
- }
559
- }, [mitigate]);
560
-
561
- return (
562
- <div className="stat-section maintenance-card">
563
- <div className="stat-label">Context Health Mitigation</div>
564
- {loading ? (
565
- <p className="repo-none">Loading…</p>
566
- ) : (
567
- <>
568
- <div className="health-mitigate-row">
569
- <label className="health-mitigate-toggle">
570
- <input
571
- type="checkbox"
572
- checked={mitigate}
573
- onChange={toggle}
574
- disabled={saving}
575
- />
576
- <span>Auto-mitigation {mitigate ? "ON" : "OFF"}</span>
577
- </label>
578
- </div>
579
- <div className="health-mitigate-info">
580
- <p>
581
- When <strong>ON</strong>, the extension automatically intervenes when
582
- context health degrades:
583
- </p>
584
- <ul>
585
- <li><strong>Forced compaction</strong> — when the composite health score
586
- drops below 0.4 (severe drift or garbled output), a compaction is
587
- triggered to flush the degraded context and rebuild from clean
588
- checkpoints, even if the context window isn&apos;t full.</li>
589
- <li><strong>Prefix break</strong> — when KV cache poison is detected
590
- (score &lt; 0.3), the cached prefix is invalidated to force a cache
591
- miss on the next turn, bypassing the corrupted KV state.</li>
592
- </ul>
593
- <p className="health-mitigate-warning">
594
- WARNING: both interventions have costs — forced compaction discards
595
- live context, and prefix breaks kill cache savings. Only enable when
596
- you&apos;re seeing degraded output (garbled text, hallucinations,
597
- loss of coherence) and the Health tab confirms low scores.
598
- </p>
599
- <p>
600
- Also settable via env var: <code>MEGACOMPACT_CONTEXT_HEALTH_MITIGATE=1</code>.
601
- The dashboard toggle persists to the store and takes precedence.
602
- </p>
603
- {error && <p className="health-mitigate-error">Error: {error}</p>}
604
- </div>
605
- </>
606
- )}
607
- </div>
608
- );
609
- }
18
+ import { fetchDbStats, fetchSchemaHealth } from "../api/client";
19
+ import { SchemaHealthCard } from "./MaintenanceTab/SchemaHealthCard";
20
+ import { DbStatsCard } from "./MaintenanceTab/DbStatsCard";
21
+ import { ActionsCard } from "./MaintenanceTab/ActionsCard";
22
+ import { DebugBundleCard } from "./MaintenanceTab/DebugBundleCard";
23
+ import { HealthMitigationCard } from "./MaintenanceTab/HealthMitigationCard";
610
24
 
611
25
  // ---------------------------------------------------------------------------
612
26
  // Main tab component