pi-mega-compact 0.20.74 → 0.20.76
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/config/vector-cortex-enc2c.js +9 -6
- package/dist/extensions/dashboard-server/api-contracts/setup-cortex-native-ort.js +5 -3
- package/dist/extensions/dashboard-server/routes-rag-settings-vector-cortex.js +1 -1
- package/dist/extensions/dashboard-server/setup-cortex-actions-native-ort.js +176 -49
- package/dist/src/config/vector-cortex-enc2c.js +9 -6
- package/dist/src/vector-cortex/encoder/native-qualify-retest.js +9 -5
- package/dist/src/vector-cortex/setup-cortex-blockers-compute.js +5 -3
- package/dist/vector-cortex/encoder/native-qualify-retest.js +9 -5
- package/dist/vector-cortex/setup-cortex-blockers-compute.js +5 -3
- package/extensions/dashboard-client/dist/assets/{AdminTab-CqhIxrlT.js → AdminTab-B8JqsA41.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{AdminTab-CqhIxrlT.js.map → AdminTab-B8JqsA41.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{AreaChart-D4EY7yiY.js → AreaChart-CeaexvWO.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{AreaChart-D4EY7yiY.js.map → AreaChart-CeaexvWO.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{BarChart-r_BFpd7a.js → BarChart-Bhyviy7_.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{BarChart-r_BFpd7a.js.map → BarChart-Bhyviy7_.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{CacheTab-Bf5rwce6.js → CacheTab-C6bFdEHq.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{CacheTab-Bf5rwce6.js.map → CacheTab-C6bFdEHq.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{ConfigTab-RFUXAUIP.js → ConfigTab-CbsdI5yj.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{ConfigTab-RFUXAUIP.js.map → ConfigTab-CbsdI5yj.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{EventsTab-DEqHbSHf.js → EventsTab-kvB5Znx2.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{EventsTab-DEqHbSHf.js.map → EventsTab-kvB5Znx2.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{HealthTab-WGEwtqmO.js → HealthTab-DqEUk5LW.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{HealthTab-WGEwtqmO.js.map → HealthTab-DqEUk5LW.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{MaintenanceTab-ClT1D4P9.js → MaintenanceTab-CS5HqDkY.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{MaintenanceTab-ClT1D4P9.js.map → MaintenanceTab-CS5HqDkY.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{MemoryMapTab-DaAxLJ5x.js → MemoryMapTab-Oq-iqvUq.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{MemoryMapTab-DaAxLJ5x.js.map → MemoryMapTab-Oq-iqvUq.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{MetricsCards-CprVx2Yq.js → MetricsCards-36RVmtPj.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{MetricsCards-CprVx2Yq.js.map → MetricsCards-36RVmtPj.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/MetricsTab-Clkcniuo.js +2 -0
- package/extensions/dashboard-client/dist/assets/{MetricsTab-8WBHRpRp.js.map → MetricsTab-Clkcniuo.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{OverviewTab-C5ClXheK.js → OverviewTab-Cl2Zx7r1.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{OverviewTab-C5ClXheK.js.map → OverviewTab-Cl2Zx7r1.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{ReposTab-BOX5sOBg.js → ReposTab-DUoDgjk-.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{ReposTab-BOX5sOBg.js.map → ReposTab-DUoDgjk-.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{SessionsTab-DKUO5gCp.js → SessionsTab-hEQ_OAfB.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{SessionsTab-DKUO5gCp.js.map → SessionsTab-hEQ_OAfB.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{SetupTab-CeeRk5Rd.js → SetupTab-Bqibg0cD.js} +3 -3
- package/extensions/dashboard-client/dist/assets/SetupTab-Bqibg0cD.js.map +1 -0
- package/extensions/dashboard-client/dist/assets/{TimeSavedCard-Dlhljae9.js → TimeSavedCard-9QMQUc7L.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{TimeSavedCard-Dlhljae9.js.map → TimeSavedCard-9QMQUc7L.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{TurnMemoryView-B8fWymMP.js → TurnMemoryView-DAfqhJqd.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{TurnMemoryView-B8fWymMP.js.map → TurnMemoryView-DAfqhJqd.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/TurnsTab-C-uZNH2F.js +2 -0
- package/extensions/dashboard-client/dist/assets/{TurnsTab-kJ4sfWSd.js.map → TurnsTab-C-uZNH2F.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{VcStatusBadge-FJZlkrD7.js → VcStatusBadge-DyOagOVb.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{VcStatusBadge-FJZlkrD7.js.map → VcStatusBadge-DyOagOVb.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{VectorCortexTab-C1iE6z4c.js → VectorCortexTab-BxsbSUGv.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{VectorCortexTab-C1iE6z4c.js.map → VectorCortexTab-BxsbSUGv.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{WikiTab-BXqRiTbt.js → WikiTab-CjefloQb.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{WikiTab-BXqRiTbt.js.map → WikiTab-CjefloQb.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{button-CUeN3VyF.js → button-D-9nb4Bw.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{button-CUeN3VyF.js.map → button-D-9nb4Bw.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{card-DtOD33bZ.js → card-Dvl16_R5.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{card-DtOD33bZ.js.map → card-Dvl16_R5.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{client-extra-_tIKSPZ3.js → client-extra-BShDrG99.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{client-extra-_tIKSPZ3.js.map → client-extra-BShDrG99.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{generateCategoricalChart-8AyWGIrK.js → generateCategoricalChart-Q_V4fqVi.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{generateCategoricalChart-8AyWGIrK.js.map → generateCategoricalChart-Q_V4fqVi.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{index-BBJ8LglL.js → index-CL6Af_JZ.js} +3 -3
- package/extensions/dashboard-client/dist/assets/{index-BBJ8LglL.js.map → index-CL6Af_JZ.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{switch-Drm0yRgr.js → switch-0MNUTR9I.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{switch-Drm0yRgr.js.map → switch-0MNUTR9I.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{toggle-DnRtZDPW.js → toggle-DHbWo-CW.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{toggle-DnRtZDPW.js.map → toggle-DHbWo-CW.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{useSSE-l_bpRt_v.js → useSSE-DcBpzKtI.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{useSSE-l_bpRt_v.js.map → useSSE-DcBpzKtI.js.map} +1 -1
- package/extensions/dashboard-client/dist/index.html +1 -1
- package/extensions/dashboard-client/src/tabs/SetupTab/CortexActionsCard.tsx +15 -7
- package/extensions/dashboard-client/src/tabs/SetupTab/CortexRetestCard.tsx +11 -1
- package/extensions/dashboard-client/src/tabs/SetupTab/CortexRuntimeCard.tsx +1 -1
- package/extensions/dashboard-server/api-contracts/setup-cortex-native-ort.ts +5 -3
- package/extensions/dashboard-server/routes-rag-settings-vector-cortex.ts +1 -1
- package/extensions/dashboard-server/setup-cortex-actions-native-ort.ts +203 -51
- package/package.json +1 -1
- package/src/config/vector-cortex-enc2c.ts +9 -6
- package/src/vector-cortex/encoder/native-qualify-retest.ts +9 -5
- package/src/vector-cortex/setup-cortex-blockers-compute.ts +5 -3
- package/extensions/dashboard-client/dist/assets/MetricsTab-8WBHRpRp.js +0 -2
- package/extensions/dashboard-client/dist/assets/SetupTab-CeeRk5Rd.js.map +0 -1
- package/extensions/dashboard-client/dist/assets/TurnsTab-kJ4sfWSd.js +0 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"mappings":"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","names":["ColumnAuditCard","columns","missing","c","jsxs","jsx","SchemaHealthCard","data","loading","error","Card","CardHeader","CardTitle","Badge","CardContent","Fragment","line","i","fmtBytes","b","FileSizesCard","files","pageSize","pageCount","freelistPages","total","TableRowCountsCard","tables","totalRows","t","DbStatsCard","ACTIONS","ActionsCard","results","setResults","useState","running","setRunning","days","setDays","handleAction","useCallback","def","action","res","postMaintenanceAction","prev","err","isRunning","lastResult","r","e","Button","DebugBundleCard","bundle","setBundle","setLoading","setError","showJson","setShowJson","gather","fetchDebugBundle","copyToClipboard","text","downloadJson","blob","url","a","criticalCount","v","HealthMitigationCard","mitigate","setMitigate","saving","setSaving","load","fetchHealthSettings","__vitePreload","s","useEffect","toggle","setHealthMitigate","next","Switch","MaintenanceTab","dbStats","statsLoading","statsError","useApi","fetchDbStats","schemaHealth","healthLoading","healthError","fetchSchemaHealth"],"ignoreList":[],"sources":["../../src/tabs/MaintenanceTab/SchemaHealthCard.tsx","../../src/tabs/MaintenanceTab/DbStatsCard.tsx","../../src/tabs/MaintenanceTab/ActionsCard.tsx","../../src/tabs/MaintenanceTab/DebugBundleCard.tsx","../../src/tabs/MaintenanceTab/HealthMitigationCard.tsx","../../src/tabs/MaintenanceTab.tsx"],"sourcesContent":["/**\n * dashboard-client/src/tabs/MaintenanceTab/SchemaHealthCard.tsx — Schema Health card.\n *\n * Extracted from MaintenanceTab.tsx (delegate-shell split). Renders schema\n * version, integrity check, column audit, and FK check from\n * GET /api/maintenance/schema-health.\n */\nimport type React from \"react\";\nimport type { SchemaHealthResponse } from \"@contracts\";\nimport { Badge } from \"../../components/ui/badge\";\nimport {\n\tCard,\n\tCardHeader,\n\tCardTitle,\n\tCardContent,\n} from \"../../components/ui/card\";\n\n// ---------------------------------------------------------------------------\n// Schema Health card\n// ---------------------------------------------------------------------------\n\nfunction ColumnAuditCard({\n\tcolumns,\n}: {\n\tcolumns: SchemaHealthResponse[\"columns\"];\n}): React.ReactElement {\n\tconst missing = columns.filter((c) => !c.present);\n\treturn (\n\t\t<div className=\"mt-3\">\n\t\t\t<div className=\"text-xs font-semibold text-muted-foreground\">\n\t\t\t\tColumn Audit ({columns.length} columns, {missing.length} missing)\n\t\t\t</div>\n\t\t\t<table className=\"mt-1 w-full border-collapse text-sm\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th className=\"border-b border-border px-2 py-1 text-left font-medium text-muted-foreground\">\n\t\t\t\t\t\t\tTable\n\t\t\t\t\t\t</th>\n\t\t\t\t\t\t<th className=\"border-b border-border px-2 py-1 text-left font-medium text-muted-foreground\">\n\t\t\t\t\t\t\tColumn\n\t\t\t\t\t\t</th>\n\t\t\t\t\t\t<th className=\"border-b border-border px-2 py-1 text-left font-medium text-muted-foreground\">\n\t\t\t\t\t\t\tDecl\n\t\t\t\t\t\t</th>\n\t\t\t\t\t\t<th className=\"border-b border-border px-2 py-1 text-left font-medium text-muted-foreground\">\n\t\t\t\t\t\t\tStatus\n\t\t\t\t\t\t</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\t\t\t\t<tbody>\n\t\t\t\t\t{columns.map((c) => (\n\t\t\t\t\t\t<tr key={`${c.table}.${c.column}`} className=\"border-b border-border/50\">\n\t\t\t\t\t\t\t<td className=\"px-2 py-1\">{c.table}</td>\n\t\t\t\t\t\t\t<td className=\"px-2 py-1\">{c.column}</td>\n\t\t\t\t\t\t\t<td className=\"px-2 py-1 font-mono\">{c.expectedDecl}</td>\n\t\t\t\t\t\t\t<td className={`px-2 py-1 ${c.present ? \"text-emerald-400\" : \"text-red-400\"}`}>\n\t\t\t\t\t\t\t\t{c.present ? \"✓\" : \"MISSING\"}\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t))}\n\t\t\t\t</tbody>\n\t\t\t</table>\n\t\t</div>\n\t);\n}\n\nexport function SchemaHealthCard({\n\tdata,\n\tloading,\n\terror,\n}: {\n\tdata: SchemaHealthResponse | null;\n\tloading: boolean;\n\terror: Error | null;\n}): React.ReactElement {\n\treturn (\n\t\t<Card>\n\t\t\t<CardHeader className=\"flex-row items-center justify-between space-y-0\">\n\t\t\t\t<CardTitle>Schema Health</CardTitle>\n\t\t\t\t{data && (\n\t\t\t\t\t<Badge variant={data.healthy ? \"success\" : \"danger\"}>\n\t\t\t\t\t\t{data.healthy ? \"HEALTHY\" : \"DEGRADED\"}\n\t\t\t\t\t</Badge>\n\t\t\t\t)}\n\t\t\t</CardHeader>\n\t\t\t<CardContent>\n\t\t\t\t{loading && !data && (\n\t\t\t\t\t<span className=\"text-sm text-muted-foreground\">Loading…</span>\n\t\t\t\t)}\n\t\t\t\t{error && !data && (\n\t\t\t\t\t<span className=\"text-sm text-red-400\">{error.message}</span>\n\t\t\t\t)}\n\t\t\t\t{data && (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<div className=\"flex items-baseline justify-between border-b border-border py-1 text-sm\">\n\t\t\t\t\t\t\t<span className=\"text-muted-foreground\">Schema version</span>\n\t\t\t\t\t\t\t<span className=\"font-semibold\">{data.schemaVersion}</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div className=\"flex items-baseline justify-between border-b border-border py-1 text-sm\">\n\t\t\t\t\t\t\t<span className=\"text-muted-foreground\">Integrity</span>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tclassName={\n\t\t\t\t\t\t\t\t\tdata.integrity[0] === \"ok\"\n\t\t\t\t\t\t\t\t\t\t? \"text-emerald-400\"\n\t\t\t\t\t\t\t\t\t\t: \"text-red-400\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{data.integrity.join(\"; \")}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<ColumnAuditCard columns={data.columns} />\n\t\t\t\t\t\t{data.fkCheck.length > 0 && (\n\t\t\t\t\t\t\t<div className=\"mt-3\">\n\t\t\t\t\t\t\t\t<div className=\"text-xs font-semibold text-amber-400\">\n\t\t\t\t\t\t\t\t\tFK Check ({data.fkCheck.length})\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t{data.fkCheck.map((line, i) => (\n\t\t\t\t\t\t\t\t\t<div key={i} className=\"font-mono text-xs text-amber-400\">\n\t\t\t\t\t\t\t\t\t\t{line}\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t</CardContent>\n\t\t</Card>\n\t);\n}\n","/**\n * dashboard-client/src/tabs/MaintenanceTab/DbStatsCard.tsx — DB Stats card.\n *\n * Extracted from MaintenanceTab.tsx (delegate-shell split). Renders file sizes\n * and table row counts from GET /api/maintenance.\n */\nimport type React from \"react\";\nimport type { DbStatsResponse } from \"@contracts\";\nimport {\n\tCard,\n\tCardHeader,\n\tCardTitle,\n\tCardContent,\n} from \"../../components/ui/card\";\n\n// ---------------------------------------------------------------------------\n// Format helpers (local — matches html.ts fmtBytes)\n// ---------------------------------------------------------------------------\n\nexport function fmtBytes(b: number): string {\n\tif (b < 1024) return `${b} B`;\n\tif (b < 1024 * 1024) return `${(b / 1024).toFixed(1)} KB`;\n\treturn `${(b / (1024 * 1024)).toFixed(1)} MB`;\n}\n\n// ---------------------------------------------------------------------------\n// DB Stats card\n// ---------------------------------------------------------------------------\n\nfunction FileSizesCard({\n\tfiles,\n\tpageSize,\n\tpageCount,\n\tfreelistPages,\n}: {\n\tfiles: DbStatsResponse[\"storage\"][\"files\"];\n\tpageSize: number;\n\tpageCount: number;\n\tfreelistPages: number;\n}): React.ReactElement {\n\tconst total = files.dbBytes + files.walBytes + files.shmBytes;\n\treturn (\n\t\t<div className=\"mt-3\">\n\t\t\t<div className=\"text-xs font-semibold text-muted-foreground\">File Sizes</div>\n\t\t\t<table className=\"mt-1 w-full border-collapse text-sm\">\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr className=\"border-b border-border/50\">\n\t\t\t\t\t\t<td className=\"px-2 py-1\">sqlite.db</td>\n\t\t\t\t\t\t<td className=\"px-2 py-1 text-right font-semibold\">\n\t\t\t\t\t\t\t{fmtBytes(files.dbBytes)}\n\t\t\t\t\t\t</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t{files.walBytes > 0 && (\n\t\t\t\t\t\t<tr className=\"border-b border-border/50\">\n\t\t\t\t\t\t\t<td className=\"px-2 py-1\">.wal</td>\n\t\t\t\t\t\t\t<td className=\"px-2 py-1 text-right font-semibold\">\n\t\t\t\t\t\t\t\t{fmtBytes(files.walBytes)}\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t)}\n\t\t\t\t\t{files.shmBytes > 0 && (\n\t\t\t\t\t\t<tr className=\"border-b border-border/50\">\n\t\t\t\t\t\t\t<td className=\"px-2 py-1\">.shm</td>\n\t\t\t\t\t\t\t<td className=\"px-2 py-1 text-right font-semibold\">\n\t\t\t\t\t\t\t\t{fmtBytes(files.shmBytes)}\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t)}\n\t\t\t\t\t<tr className=\"border-b border-border/50\">\n\t\t\t\t\t\t<td className=\"px-2 py-1\">Total</td>\n\t\t\t\t\t\t<td className=\"px-2 py-1 text-right font-semibold\">\n\t\t\t\t\t\t\t{fmtBytes(total)}\n\t\t\t\t\t\t</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr className=\"border-b border-border/50\">\n\t\t\t\t\t\t<td className=\"px-2 py-1\">Page size</td>\n\t\t\t\t\t\t<td className=\"px-2 py-1 text-right font-semibold\">\n\t\t\t\t\t\t\t{fmtBytes(pageSize)}\n\t\t\t\t\t\t</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td className=\"px-2 py-1\">Pages</td>\n\t\t\t\t\t\t<td className=\"px-2 py-1 text-right font-semibold\">\n\t\t\t\t\t\t\t{pageCount.toLocaleString()} ({freelistPages.toLocaleString()}{\" \"}\n\t\t\t\t\t\t\tfree)\n\t\t\t\t\t\t</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\t\t</div>\n\t);\n}\n\nfunction TableRowCountsCard({\n\ttables,\n}: {\n\ttables: DbStatsResponse[\"tables\"];\n}): React.ReactElement {\n\tconst totalRows = tables.reduce((s, t) => s + Math.max(0, t.rowCount), 0);\n\treturn (\n\t\t<div className=\"mt-3\">\n\t\t\t<div className=\"text-xs font-semibold text-muted-foreground\">\n\t\t\t\tTable Row Counts ({totalRows.toLocaleString()} total)\n\t\t\t</div>\n\t\t\t<table className=\"mt-1 w-full border-collapse text-sm\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th className=\"border-b border-border px-2 py-1 text-left font-medium text-muted-foreground\">\n\t\t\t\t\t\t\tTable\n\t\t\t\t\t\t</th>\n\t\t\t\t\t\t<th className=\"border-b border-border px-2 py-1 text-right font-medium text-muted-foreground\">\n\t\t\t\t\t\t\tRows\n\t\t\t\t\t\t</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\t\t\t\t<tbody>\n\t\t\t\t\t{tables.map((t) => (\n\t\t\t\t\t\t<tr key={t.table} className=\"border-b border-border/50\">\n\t\t\t\t\t\t\t<td className=\"px-2 py-1\">{t.table}</td>\n\t\t\t\t\t\t\t<td className=\"px-2 py-1 text-right\">\n\t\t\t\t\t\t\t\t{t.rowCount >= 0 ? t.rowCount.toLocaleString() : \"—\"}\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t))}\n\t\t\t\t</tbody>\n\t\t\t</table>\n\t\t</div>\n\t);\n}\n\nexport function DbStatsCard({\n\tdata,\n\tloading,\n\terror,\n}: {\n\tdata: DbStatsResponse | null;\n\tloading: boolean;\n\terror: Error | null;\n}): React.ReactElement {\n\treturn (\n\t\t<Card>\n\t\t\t<CardHeader>\n\t\t\t\t<CardTitle>DB Stats</CardTitle>\n\t\t\t</CardHeader>\n\t\t\t<CardContent>\n\t\t\t\t{loading && !data && (\n\t\t\t\t\t<span className=\"text-sm text-muted-foreground\">Loading…</span>\n\t\t\t\t)}\n\t\t\t\t{error && !data && (\n\t\t\t\t\t<span className=\"text-sm text-red-400\">{error.message}</span>\n\t\t\t\t)}\n\t\t\t\t{data && (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<FileSizesCard\n\t\t\t\t\t\t\tfiles={data.storage.files}\n\t\t\t\t\t\t\tpageSize={data.storage.pageSize}\n\t\t\t\t\t\t\tpageCount={data.storage.pageCount}\n\t\t\t\t\t\t\tfreelistPages={data.storage.freelistPages}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<TableRowCountsCard tables={data.tables} />\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t</CardContent>\n\t\t</Card>\n\t);\n}\n","/**\n * dashboard-client/src/tabs/MaintenanceTab/ActionsCard.tsx — Actions card.\n *\n * Extracted from MaintenanceTab.tsx (delegate-shell split). One-time\n * maintenance operations (vacuum, checkpoint, reindex, prune, …) with a\n * results history.\n */\nimport type React from \"react\";\nimport { useState, useCallback } from \"react\";\nimport type {\n\tMaintenanceAction,\n\tMaintenanceActionResult,\n} from \"@contracts\";\nimport { postMaintenanceAction } from \"../../api/client\";\nimport { Badge } from \"../../components/ui/badge\";\nimport { Button } from \"../../components/ui/button\";\nimport { Card, CardHeader, CardTitle } from \"../../components/ui/card\";\n\n// ---------------------------------------------------------------------------\n// Action config\n// ---------------------------------------------------------------------------\n\ninterface ActionDef {\n\tkey: string;\n\tlabel: string;\n\tdesc: string;\n\tdangerous: boolean;\n\tconfirm?: string;\n\tdaysOld?: boolean;\n}\n\nconst ACTIONS: ActionDef[] = [\n\t{\n\t\tkey: \"integrity-check\",\n\t\tlabel: \"Integrity Check\",\n\t\tdesc: \"Run PRAGMA integrity_check\",\n\t\tdangerous: false,\n\t},\n\t{\n\t\tkey: \"reconcile-dedup\",\n\t\tlabel: \"Reconcile Dedup Mirror\",\n\t\tdesc: \"Fix orphan dedup rows + backfill refs\",\n\t\tdangerous: false,\n\t\tconfirm: \"Reconcile dedup_mirror (safe read/write)?\",\n\t},\n\t{\n\t\tkey: \"checkpoint\",\n\t\tlabel: \"WAL Checkpoint\",\n\t\tdesc: \"Merge WAL into main DB (read-only)\",\n\t\tdangerous: false,\n\t},\n\t{\n\t\tkey: \"vacuum\",\n\t\tlabel: \"VACUUM\",\n\t\tdesc: \"Rebuild DB reclaiming free pages\",\n\t\tdangerous: true,\n\t\tconfirm: \"VACUUM rewrites the entire DB. Continue?\",\n\t},\n\t{\n\t\tkey: \"reindex\",\n\t\tlabel: \"REINDEX\",\n\t\tdesc: \"Rebuild all indexes\",\n\t\tdangerous: true,\n\t\tconfirm: \"REINDEX rebuilds indexes. Continue?\",\n\t},\n\t{\n\t\tkey: \"fts5-rebuild\",\n\t\tlabel: \"FTS5 Rebuild\",\n\t\tdesc: \"Rebuild full-text search index\",\n\t\tdangerous: true,\n\t\tconfirm: \"Rebuild FTS5 trigram index. Continue?\",\n\t},\n\t{\n\t\tkey: \"prune\",\n\t\tlabel: \"Prune Old Rows\",\n\t\tdesc: \"Delete transcripts + epochs older than N days\",\n\t\tdangerous: true,\n\t\tdaysOld: true,\n\t\tconfirm: \"Delete old raw_transcript rows. Continue?\",\n\t},\n];\n\n// ---------------------------------------------------------------------------\n// Actions card\n// ---------------------------------------------------------------------------\n\nexport function ActionsCard(): React.ReactElement {\n\tconst [results, setResults] = useState<MaintenanceActionResult[]>([]);\n\tconst [running, setRunning] = useState<string | null>(null);\n\tconst [days, setDays] = useState(\"30\");\n\n\tconst handleAction = useCallback(\n\t\tasync (def: ActionDef) => {\n\t\t\tconst action: MaintenanceAction = def.daysOld\n\t\t\t\t? { action: \"prune\", daysOld: Number(days) }\n\t\t\t\t: ({ action: def.key } as MaintenanceAction);\n\n\t\t\tsetRunning(def.key);\n\t\t\ttry {\n\t\t\t\tconst res = await postMaintenanceAction(action);\n\t\t\t\tsetResults((prev) =>\n\t\t\t\t\t[{ ...res, timestamp: Date.now() }, ...prev].slice(0, 20),\n\t\t\t\t);\n\t\t\t} catch (err) {\n\t\t\t\tsetResults((prev) =>\n\t\t\t\t\t[\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\toperation: def.key,\n\t\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\t\taffected: 0,\n\t\t\t\t\t\t\treclaimedBytes: 0,\n\t\t\t\t\t\t\tsummary: err instanceof Error ? err.message : String(err),\n\t\t\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\t\t},\n\t\t\t\t\t\t...prev,\n\t\t\t\t\t].slice(0, 20),\n\t\t\t\t);\n\t\t\t} finally {\n\t\t\t\tsetRunning(null);\n\t\t\t}\n\t\t},\n\t\t[days],\n\t);\n\n\treturn (\n\t\t<Card>\n\t\t\t<CardHeader>\n\t\t\t\t<CardTitle>Actions</CardTitle>\n\t\t\t</CardHeader>\n\t\t\t<div className=\"grid grid-cols-1 gap-3 lg:grid-cols-2\">\n\t\t\t\t{ACTIONS.map((def) => {\n\t\t\t\t\tconst isRunning = running === def.key;\n\t\t\t\t\tconst lastResult = results.find((r) => r.operation === def.key);\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tkey={def.key}\n\t\t\t\t\t\t\tclassName=\"flex items-start justify-between gap-3 rounded-lg border border-border/60 p-3\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<div className=\"min-w-0\">\n\t\t\t\t\t\t\t\t<div className=\"flex flex-wrap items-center gap-2\">\n\t\t\t\t\t\t\t\t\t<span className=\"font-semibold\">{def.label}</span>\n\t\t\t\t\t\t\t\t\t{def.dangerous && <Badge variant=\"danger\">DESTRUCTIVE</Badge>}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<div className=\"mt-1 text-xs text-muted-foreground\">{def.desc}</div>\n\t\t\t\t\t\t\t\t{lastResult && (\n\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\tclassName={`mt-1 text-xs ${lastResult.success ? \"text-emerald-400\" : \"text-red-400\"}`}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{lastResult.summary}\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div className=\"flex shrink-0 items-center gap-2\">\n\t\t\t\t\t\t\t\t{def.daysOld && (\n\t\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\t\ttype=\"number\"\n\t\t\t\t\t\t\t\t\t\tmin={1}\n\t\t\t\t\t\t\t\t\t\tmax={365}\n\t\t\t\t\t\t\t\t\t\tvalue={days}\n\t\t\t\t\t\t\t\t\t\tonChange={(e) => setDays(e.target.value)}\n\t\t\t\t\t\t\t\t\t\tclassName=\"w-16 rounded-md border border-border bg-bg-elevated/50 px-2 py-1 text-sm outline-none focus:border-primary\"\n\t\t\t\t\t\t\t\t\t\tdisabled={isRunning}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tvariant={def.dangerous ? \"ghost\" : \"default\"}\n\t\t\t\t\t\t\t\t\tclassName={\n\t\t\t\t\t\t\t\t\t\tdef.dangerous\n\t\t\t\t\t\t\t\t\t\t\t? \"border border-red-500/50 text-red-400 hover:bg-red-500/10 hover:text-red-300\"\n\t\t\t\t\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tdisabled={running !== null}\n\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\tif (def.confirm && !window.confirm(def.confirm)) return;\n\t\t\t\t\t\t\t\t\t\thandleAction(def);\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{isRunning ? \"Running…\" : \"Run\"}\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t);\n\t\t\t\t})}\n\t\t\t</div>\n\t\t</Card>\n\t);\n}\n","/**\n * dashboard-client/src/tabs/MaintenanceTab/DebugBundleCard.tsx — Debug Bundle card.\n *\n * Extracted from MaintenanceTab.tsx (delegate-shell split). Gather a diagnostic\n * bundle (events, config, schema health, store stats) and let the user copy or\n * download it for bug reports.\n */\nimport type React from \"react\";\nimport { useState, useCallback } from \"react\";\nimport type { DebugBundleResponse } from \"@contracts\";\nimport { fetchDebugBundle } from \"../../api/client\";\nimport { Button } from \"../../components/ui/button\";\nimport {\n\tCard,\n\tCardHeader,\n\tCardTitle,\n\tCardContent,\n} from \"../../components/ui/card\";\n\n// ---------------------------------------------------------------------------\n// Debug bundle card — gather diagnostic info for bug reports\n// ---------------------------------------------------------------------------\n\nexport function DebugBundleCard(): React.ReactElement {\n\tconst [bundle, setBundle] = useState<DebugBundleResponse | null>(null);\n\tconst [loading, setLoading] = useState(false);\n\tconst [error, setError] = useState<string | null>(null);\n\tconst [showJson, setShowJson] = useState(false);\n\n\tconst gather = useCallback(async () => {\n\t\tsetLoading(true);\n\t\tsetError(null);\n\t\ttry {\n\t\t\tconst res = await fetchDebugBundle();\n\t\t\tsetBundle(res);\n\t\t\tsetShowJson(true);\n\t\t} catch (err) {\n\t\t\tsetError(err instanceof Error ? err.message : String(err));\n\t\t} finally {\n\t\t\tsetLoading(false);\n\t\t}\n\t}, []);\n\n\tconst copyToClipboard = useCallback(() => {\n\t\tif (!bundle) return;\n\t\tconst text = JSON.stringify(bundle, null, 2);\n\t\tvoid navigator.clipboard.writeText(text).catch(() => {});\n\t}, [bundle]);\n\n\tconst downloadJson = useCallback(() => {\n\t\tif (!bundle) return;\n\t\tconst text = JSON.stringify(bundle, null, 2);\n\t\tconst blob = new Blob([text], { type: \"application/json\" });\n\t\tconst url = URL.createObjectURL(blob);\n\t\tconst a = document.createElement(\"a\");\n\t\ta.href = url;\n\t\ta.download = `mega-compact-debug-bundle-${bundle.builtAt}.json`;\n\t\ta.click();\n\t\tURL.revokeObjectURL(url);\n\t}, [bundle]);\n\n\tconst criticalCount = bundle?.criticalEvents.length ?? 0;\n\n\treturn (\n\t\t<Card>\n\t\t\t<CardHeader className=\"flex-row items-center justify-between space-y-0\">\n\t\t\t\t<CardTitle>Debug Bundle</CardTitle>\n\t\t\t\t{criticalCount > 0 && (\n\t\t\t\t\t<span className=\"text-xs text-amber-400\">\n\t\t\t\t\t\t{criticalCount} critical event{criticalCount !== 1 ? \"s\" : \"\"} found\n\t\t\t\t\t</span>\n\t\t\t\t)}\n\t\t\t</CardHeader>\n\t\t\t<CardContent>\n\t\t\t\t<p className=\"mb-3 text-sm text-muted-foreground\">\n\t\t\t\t\tGather a diagnostic bundle (recent events, config flags, schema health,\n\t\t\t\t\tstore stats) to attach to a bug report. Critical/compaction events are\n\t\t\t\t\thighlighted.\n\t\t\t\t</p>\n\t\t\t\t<Button type=\"button\" variant=\"glass\" onClick={gather} disabled={loading}>\n\t\t\t\t\t{loading ? \"Gathering…\" : \"Gather Debug Logs\"}\n\t\t\t\t</Button>\n\t\t\t\t{error && <div className=\"mt-2 text-sm text-red-400\">{error}</div>}\n\t\t\t\t{bundle && showJson && (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<div className=\"mb-2 mt-3 flex gap-2\">\n\t\t\t\t\t\t\t<Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={copyToClipboard}>\n\t\t\t\t\t\t\t\tCopy to clipboard\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t<Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={downloadJson}>\n\t\t\t\t\t\t\t\tDownload JSON\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tvariant=\"outline\"\n\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\tonClick={() => setShowJson((v) => !v)}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{showJson ? \"Hide\" : \"Show\"}\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t{criticalCount > 0 && (\n\t\t\t\t\t\t\t<div className=\"mt-3\">\n\t\t\t\t\t\t\t\t<div className=\"text-xs font-semibold text-amber-400\">\n\t\t\t\t\t\t\t\t\tCritical events ({criticalCount})\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<pre className=\"max-h-48 overflow-auto rounded-md border border-border/60 bg-bg-elevated/40 p-3 font-mono text-xs\">\n\t\t\t\t\t\t\t\t\t{JSON.stringify(bundle.criticalEvents, null, 2)}\n\t\t\t\t\t\t\t\t</pre>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t<pre className=\"mt-3 max-h-96 overflow-auto rounded-md border border-border/60 bg-bg-elevated/40 p-3 font-mono text-xs\">\n\t\t\t\t\t\t\t{JSON.stringify(bundle, null, 2)}\n\t\t\t\t\t\t</pre>\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t</CardContent>\n\t\t</Card>\n\t);\n}\n","/**\n * dashboard-client/src/tabs/MaintenanceTab/HealthMitigationCard.tsx — Health\n * Mitigation card.\n *\n * Extracted from MaintenanceTab.tsx (delegate-shell split). Toggles auto-\n * mitigation for degraded context (forced compaction / prefix break).\n */\nimport type React from \"react\";\nimport { useState, useCallback, useEffect } from \"react\";\nimport { Switch } from \"../../components/ui/switch\";\nimport {\n\tCard,\n\tCardHeader,\n\tCardTitle,\n\tCardContent,\n} from \"../../components/ui/card\";\n\n// ---------------------------------------------------------------------------\n// Health Mitigation card — toggle auto-mitigation for degraded context\n// ---------------------------------------------------------------------------\n\nexport function HealthMitigationCard(): React.ReactElement {\n\tconst [mitigate, setMitigate] = useState(false);\n\tconst [loading, setLoading] = useState(true);\n\tconst [saving, setSaving] = useState(false);\n\tconst [error, setError] = useState<string | null>(null);\n\n\tconst load = useCallback(async () => {\n\t\ttry {\n\t\t\tconst { fetchHealthSettings } = await import(\"../../api/health\");\n\t\t\tconst s = await fetchHealthSettings();\n\t\t\tsetMitigate(s.mitigate);\n\t\t} catch (e) {\n\t\t\tsetError(e instanceof Error ? e.message : String(e));\n\t\t} finally {\n\t\t\tsetLoading(false);\n\t\t}\n\t}, []);\n\n\tuseEffect(() => { void load(); }, [load]);\n\n\tconst toggle = useCallback(async () => {\n\t\tsetSaving(true);\n\t\tsetError(null);\n\t\ttry {\n\t\t\tconst { setHealthMitigate } = await import(\"../../api/health\");\n\t\t\tconst next = !mitigate;\n\t\t\tawait setHealthMitigate(next);\n\t\t\tsetMitigate(next);\n\t\t} catch (e) {\n\t\t\tsetError(e instanceof Error ? e.message : String(e));\n\t\t} finally {\n\t\t\tsetSaving(false);\n\t\t}\n\t}, [mitigate]);\n\n\treturn (\n\t\t<Card>\n\t\t\t<CardHeader>\n\t\t\t\t<CardTitle>Context Health Mitigation</CardTitle>\n\t\t\t</CardHeader>\n\t\t\t<CardContent>\n\t\t\t\t{loading ? (\n\t\t\t\t\t<p className=\"text-sm text-muted-foreground\">Loading…</p>\n\t\t\t\t) : (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t\t\t\t<Switch\n\t\t\t\t\t\t\t\tchecked={mitigate}\n\t\t\t\t\t\t\t\tonCheckedChange={toggle}\n\t\t\t\t\t\t\t\tdisabled={saving}\n\t\t\t\t\t\t\t\taria-label=\"Context health auto-mitigation\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<span className=\"text-sm\">\n\t\t\t\t\t\t\t\tAuto-mitigation {mitigate ? \"ON\" : \"OFF\"}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div className=\"mt-3 space-y-2 text-sm\">\n\t\t\t\t\t\t\t<p>\n\t\t\t\t\t\t\t\tWhen <strong>ON</strong>, the extension automatically intervenes\n\t\t\t\t\t\t\t\twhen context health degrades:\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t<ul className=\"list-disc space-y-1 pl-5\">\n\t\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t\t<strong>Forced compaction</strong> — when the composite health\n\t\t\t\t\t\t\t\t\tscore drops below 0.4 (severe drift or garbled output), a\n\t\t\t\t\t\t\t\t\tcompaction is triggered to flush the degraded context and\n\t\t\t\t\t\t\t\t\trebuild from clean checkpoints, even if the context window\n\t\t\t\t\t\t\t\t\tisn't full.\n\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t\t<strong>Prefix break</strong> — when KV cache poison is\n\t\t\t\t\t\t\t\t\tdetected (score < 0.3), the cached prefix is invalidated to\n\t\t\t\t\t\t\t\t\tforce a cache miss on the next turn, bypassing the corrupted KV\n\t\t\t\t\t\t\t\t\tstate.\n\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t</ul>\n\t\t\t\t\t\t\t<p className=\"rounded-md border border-amber-500/30 bg-amber-500/5 p-3 text-amber-400\">\n\t\t\t\t\t\t\t\tWARNING: both interventions have costs — forced compaction discards\n\t\t\t\t\t\t\t\tlive context, and prefix breaks kill cache savings. Only enable\n\t\t\t\t\t\t\t\twhen you're seeing degraded output (garbled text,\n\t\t\t\t\t\t\t\thallucinations, loss of coherence) and the Health tab confirms low\n\t\t\t\t\t\t\t\tscores.\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t<p className=\"text-muted-foreground\">\n\t\t\t\t\t\t\t\tAlso settable via env var:{\" \"}\n\t\t\t\t\t\t\t\t<code>MEGACOMPACT_CONTEXT_HEALTH_MITIGATE=1</code>. The dashboard\n\t\t\t\t\t\t\t\ttoggle persists to the store and takes precedence.\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t{error && <p className=\"text-sm text-red-400\">Error: {error}</p>}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t</CardContent>\n\t\t</Card>\n\t);\n}\n","/**\n * dashboard-client/src/tabs/MaintenanceTab.tsx — Maintenance tab (v0.11.2 S49B).\n *\n * Delegate-shell (extensions split): three cards (Schema Health, DB Stats,\n * Actions) plus the Debug Bundle and Health Mitigation cards. The heavy card\n * components live in ./MaintenanceTab/* to keep every file under the extensions\n * line limit. All cards fetch independently; failures in one do not block the\n * others.\n */\n\nimport type React from \"react\";\nimport { useCallback } from \"react\";\nimport type {\n\tDbStatsResponse,\n\tSchemaHealthResponse,\n} from \"@contracts\";\nimport { useApi } from \"../hooks/useApi\";\nimport { fetchDbStats, fetchSchemaHealth } from \"../api/client\";\nimport { SchemaHealthCard } from \"./MaintenanceTab/SchemaHealthCard\";\nimport { DbStatsCard } from \"./MaintenanceTab/DbStatsCard\";\nimport { ActionsCard } from \"./MaintenanceTab/ActionsCard\";\nimport { DebugBundleCard } from \"./MaintenanceTab/DebugBundleCard\";\nimport { HealthMitigationCard } from \"./MaintenanceTab/HealthMitigationCard\";\n\n// ---------------------------------------------------------------------------\n// Main tab component\n// ---------------------------------------------------------------------------\n\nexport default function MaintenanceTab(): React.ReactElement {\n\tconst {\n\t\tdata: dbStats,\n\t\tloading: statsLoading,\n\t\terror: statsError,\n\t} = useApi<DbStatsResponse>(\n\t\tuseCallback(() => fetchDbStats(), []),\n\t\t{ pollInterval: 15000 },\n\t);\n\n\tconst {\n\t\tdata: schemaHealth,\n\t\tloading: healthLoading,\n\t\terror: healthError,\n\t} = useApi<SchemaHealthResponse>(\n\t\tuseCallback(() => fetchSchemaHealth(), []),\n\t\t{ pollInterval: 10000 },\n\t);\n\n\treturn (\n\t\t<div className=\"flex flex-col gap-4\">\n\t\t\t<div className=\"grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-3\">\n\t\t\t\t<SchemaHealthCard\n\t\t\t\t\tdata={schemaHealth}\n\t\t\t\t\tloading={healthLoading}\n\t\t\t\t\terror={healthError}\n\t\t\t\t/>\n\t\t\t\t<DbStatsCard data={dbStats} loading={statsLoading} error={statsError} />\n\t\t\t</div>\n\t\t\t<ActionsCard />\n\t\t\t<DebugBundleCard />\n\t\t\t<HealthMitigationCard />\n\t\t</div>\n\t);\n}\n"],"file":"assets/MaintenanceTab-ClT1D4P9.js"}
|
|
1
|
+
{"version":3,"mappings":"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","names":["ColumnAuditCard","columns","missing","c","jsxs","jsx","SchemaHealthCard","data","loading","error","Card","CardHeader","CardTitle","Badge","CardContent","Fragment","line","i","fmtBytes","b","FileSizesCard","files","pageSize","pageCount","freelistPages","total","TableRowCountsCard","tables","totalRows","t","DbStatsCard","ACTIONS","ActionsCard","results","setResults","useState","running","setRunning","days","setDays","handleAction","useCallback","def","action","res","postMaintenanceAction","prev","err","isRunning","lastResult","r","e","Button","DebugBundleCard","bundle","setBundle","setLoading","setError","showJson","setShowJson","gather","fetchDebugBundle","copyToClipboard","text","downloadJson","blob","url","a","criticalCount","v","HealthMitigationCard","mitigate","setMitigate","saving","setSaving","load","fetchHealthSettings","__vitePreload","s","useEffect","toggle","setHealthMitigate","next","Switch","MaintenanceTab","dbStats","statsLoading","statsError","useApi","fetchDbStats","schemaHealth","healthLoading","healthError","fetchSchemaHealth"],"ignoreList":[],"sources":["../../src/tabs/MaintenanceTab/SchemaHealthCard.tsx","../../src/tabs/MaintenanceTab/DbStatsCard.tsx","../../src/tabs/MaintenanceTab/ActionsCard.tsx","../../src/tabs/MaintenanceTab/DebugBundleCard.tsx","../../src/tabs/MaintenanceTab/HealthMitigationCard.tsx","../../src/tabs/MaintenanceTab.tsx"],"sourcesContent":["/**\n * dashboard-client/src/tabs/MaintenanceTab/SchemaHealthCard.tsx — Schema Health card.\n *\n * Extracted from MaintenanceTab.tsx (delegate-shell split). Renders schema\n * version, integrity check, column audit, and FK check from\n * GET /api/maintenance/schema-health.\n */\nimport type React from \"react\";\nimport type { SchemaHealthResponse } from \"@contracts\";\nimport { Badge } from \"../../components/ui/badge\";\nimport {\n\tCard,\n\tCardHeader,\n\tCardTitle,\n\tCardContent,\n} from \"../../components/ui/card\";\n\n// ---------------------------------------------------------------------------\n// Schema Health card\n// ---------------------------------------------------------------------------\n\nfunction ColumnAuditCard({\n\tcolumns,\n}: {\n\tcolumns: SchemaHealthResponse[\"columns\"];\n}): React.ReactElement {\n\tconst missing = columns.filter((c) => !c.present);\n\treturn (\n\t\t<div className=\"mt-3\">\n\t\t\t<div className=\"text-xs font-semibold text-muted-foreground\">\n\t\t\t\tColumn Audit ({columns.length} columns, {missing.length} missing)\n\t\t\t</div>\n\t\t\t<table className=\"mt-1 w-full border-collapse text-sm\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th className=\"border-b border-border px-2 py-1 text-left font-medium text-muted-foreground\">\n\t\t\t\t\t\t\tTable\n\t\t\t\t\t\t</th>\n\t\t\t\t\t\t<th className=\"border-b border-border px-2 py-1 text-left font-medium text-muted-foreground\">\n\t\t\t\t\t\t\tColumn\n\t\t\t\t\t\t</th>\n\t\t\t\t\t\t<th className=\"border-b border-border px-2 py-1 text-left font-medium text-muted-foreground\">\n\t\t\t\t\t\t\tDecl\n\t\t\t\t\t\t</th>\n\t\t\t\t\t\t<th className=\"border-b border-border px-2 py-1 text-left font-medium text-muted-foreground\">\n\t\t\t\t\t\t\tStatus\n\t\t\t\t\t\t</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\t\t\t\t<tbody>\n\t\t\t\t\t{columns.map((c) => (\n\t\t\t\t\t\t<tr key={`${c.table}.${c.column}`} className=\"border-b border-border/50\">\n\t\t\t\t\t\t\t<td className=\"px-2 py-1\">{c.table}</td>\n\t\t\t\t\t\t\t<td className=\"px-2 py-1\">{c.column}</td>\n\t\t\t\t\t\t\t<td className=\"px-2 py-1 font-mono\">{c.expectedDecl}</td>\n\t\t\t\t\t\t\t<td className={`px-2 py-1 ${c.present ? \"text-emerald-400\" : \"text-red-400\"}`}>\n\t\t\t\t\t\t\t\t{c.present ? \"✓\" : \"MISSING\"}\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t))}\n\t\t\t\t</tbody>\n\t\t\t</table>\n\t\t</div>\n\t);\n}\n\nexport function SchemaHealthCard({\n\tdata,\n\tloading,\n\terror,\n}: {\n\tdata: SchemaHealthResponse | null;\n\tloading: boolean;\n\terror: Error | null;\n}): React.ReactElement {\n\treturn (\n\t\t<Card>\n\t\t\t<CardHeader className=\"flex-row items-center justify-between space-y-0\">\n\t\t\t\t<CardTitle>Schema Health</CardTitle>\n\t\t\t\t{data && (\n\t\t\t\t\t<Badge variant={data.healthy ? \"success\" : \"danger\"}>\n\t\t\t\t\t\t{data.healthy ? \"HEALTHY\" : \"DEGRADED\"}\n\t\t\t\t\t</Badge>\n\t\t\t\t)}\n\t\t\t</CardHeader>\n\t\t\t<CardContent>\n\t\t\t\t{loading && !data && (\n\t\t\t\t\t<span className=\"text-sm text-muted-foreground\">Loading…</span>\n\t\t\t\t)}\n\t\t\t\t{error && !data && (\n\t\t\t\t\t<span className=\"text-sm text-red-400\">{error.message}</span>\n\t\t\t\t)}\n\t\t\t\t{data && (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<div className=\"flex items-baseline justify-between border-b border-border py-1 text-sm\">\n\t\t\t\t\t\t\t<span className=\"text-muted-foreground\">Schema version</span>\n\t\t\t\t\t\t\t<span className=\"font-semibold\">{data.schemaVersion}</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div className=\"flex items-baseline justify-between border-b border-border py-1 text-sm\">\n\t\t\t\t\t\t\t<span className=\"text-muted-foreground\">Integrity</span>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tclassName={\n\t\t\t\t\t\t\t\t\tdata.integrity[0] === \"ok\"\n\t\t\t\t\t\t\t\t\t\t? \"text-emerald-400\"\n\t\t\t\t\t\t\t\t\t\t: \"text-red-400\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{data.integrity.join(\"; \")}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<ColumnAuditCard columns={data.columns} />\n\t\t\t\t\t\t{data.fkCheck.length > 0 && (\n\t\t\t\t\t\t\t<div className=\"mt-3\">\n\t\t\t\t\t\t\t\t<div className=\"text-xs font-semibold text-amber-400\">\n\t\t\t\t\t\t\t\t\tFK Check ({data.fkCheck.length})\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t{data.fkCheck.map((line, i) => (\n\t\t\t\t\t\t\t\t\t<div key={i} className=\"font-mono text-xs text-amber-400\">\n\t\t\t\t\t\t\t\t\t\t{line}\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t</CardContent>\n\t\t</Card>\n\t);\n}\n","/**\n * dashboard-client/src/tabs/MaintenanceTab/DbStatsCard.tsx — DB Stats card.\n *\n * Extracted from MaintenanceTab.tsx (delegate-shell split). Renders file sizes\n * and table row counts from GET /api/maintenance.\n */\nimport type React from \"react\";\nimport type { DbStatsResponse } from \"@contracts\";\nimport {\n\tCard,\n\tCardHeader,\n\tCardTitle,\n\tCardContent,\n} from \"../../components/ui/card\";\n\n// ---------------------------------------------------------------------------\n// Format helpers (local — matches html.ts fmtBytes)\n// ---------------------------------------------------------------------------\n\nexport function fmtBytes(b: number): string {\n\tif (b < 1024) return `${b} B`;\n\tif (b < 1024 * 1024) return `${(b / 1024).toFixed(1)} KB`;\n\treturn `${(b / (1024 * 1024)).toFixed(1)} MB`;\n}\n\n// ---------------------------------------------------------------------------\n// DB Stats card\n// ---------------------------------------------------------------------------\n\nfunction FileSizesCard({\n\tfiles,\n\tpageSize,\n\tpageCount,\n\tfreelistPages,\n}: {\n\tfiles: DbStatsResponse[\"storage\"][\"files\"];\n\tpageSize: number;\n\tpageCount: number;\n\tfreelistPages: number;\n}): React.ReactElement {\n\tconst total = files.dbBytes + files.walBytes + files.shmBytes;\n\treturn (\n\t\t<div className=\"mt-3\">\n\t\t\t<div className=\"text-xs font-semibold text-muted-foreground\">File Sizes</div>\n\t\t\t<table className=\"mt-1 w-full border-collapse text-sm\">\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr className=\"border-b border-border/50\">\n\t\t\t\t\t\t<td className=\"px-2 py-1\">sqlite.db</td>\n\t\t\t\t\t\t<td className=\"px-2 py-1 text-right font-semibold\">\n\t\t\t\t\t\t\t{fmtBytes(files.dbBytes)}\n\t\t\t\t\t\t</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t{files.walBytes > 0 && (\n\t\t\t\t\t\t<tr className=\"border-b border-border/50\">\n\t\t\t\t\t\t\t<td className=\"px-2 py-1\">.wal</td>\n\t\t\t\t\t\t\t<td className=\"px-2 py-1 text-right font-semibold\">\n\t\t\t\t\t\t\t\t{fmtBytes(files.walBytes)}\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t)}\n\t\t\t\t\t{files.shmBytes > 0 && (\n\t\t\t\t\t\t<tr className=\"border-b border-border/50\">\n\t\t\t\t\t\t\t<td className=\"px-2 py-1\">.shm</td>\n\t\t\t\t\t\t\t<td className=\"px-2 py-1 text-right font-semibold\">\n\t\t\t\t\t\t\t\t{fmtBytes(files.shmBytes)}\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t)}\n\t\t\t\t\t<tr className=\"border-b border-border/50\">\n\t\t\t\t\t\t<td className=\"px-2 py-1\">Total</td>\n\t\t\t\t\t\t<td className=\"px-2 py-1 text-right font-semibold\">\n\t\t\t\t\t\t\t{fmtBytes(total)}\n\t\t\t\t\t\t</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr className=\"border-b border-border/50\">\n\t\t\t\t\t\t<td className=\"px-2 py-1\">Page size</td>\n\t\t\t\t\t\t<td className=\"px-2 py-1 text-right font-semibold\">\n\t\t\t\t\t\t\t{fmtBytes(pageSize)}\n\t\t\t\t\t\t</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td className=\"px-2 py-1\">Pages</td>\n\t\t\t\t\t\t<td className=\"px-2 py-1 text-right font-semibold\">\n\t\t\t\t\t\t\t{pageCount.toLocaleString()} ({freelistPages.toLocaleString()}{\" \"}\n\t\t\t\t\t\t\tfree)\n\t\t\t\t\t\t</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\t\t</div>\n\t);\n}\n\nfunction TableRowCountsCard({\n\ttables,\n}: {\n\ttables: DbStatsResponse[\"tables\"];\n}): React.ReactElement {\n\tconst totalRows = tables.reduce((s, t) => s + Math.max(0, t.rowCount), 0);\n\treturn (\n\t\t<div className=\"mt-3\">\n\t\t\t<div className=\"text-xs font-semibold text-muted-foreground\">\n\t\t\t\tTable Row Counts ({totalRows.toLocaleString()} total)\n\t\t\t</div>\n\t\t\t<table className=\"mt-1 w-full border-collapse text-sm\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th className=\"border-b border-border px-2 py-1 text-left font-medium text-muted-foreground\">\n\t\t\t\t\t\t\tTable\n\t\t\t\t\t\t</th>\n\t\t\t\t\t\t<th className=\"border-b border-border px-2 py-1 text-right font-medium text-muted-foreground\">\n\t\t\t\t\t\t\tRows\n\t\t\t\t\t\t</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\t\t\t\t<tbody>\n\t\t\t\t\t{tables.map((t) => (\n\t\t\t\t\t\t<tr key={t.table} className=\"border-b border-border/50\">\n\t\t\t\t\t\t\t<td className=\"px-2 py-1\">{t.table}</td>\n\t\t\t\t\t\t\t<td className=\"px-2 py-1 text-right\">\n\t\t\t\t\t\t\t\t{t.rowCount >= 0 ? t.rowCount.toLocaleString() : \"—\"}\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t))}\n\t\t\t\t</tbody>\n\t\t\t</table>\n\t\t</div>\n\t);\n}\n\nexport function DbStatsCard({\n\tdata,\n\tloading,\n\terror,\n}: {\n\tdata: DbStatsResponse | null;\n\tloading: boolean;\n\terror: Error | null;\n}): React.ReactElement {\n\treturn (\n\t\t<Card>\n\t\t\t<CardHeader>\n\t\t\t\t<CardTitle>DB Stats</CardTitle>\n\t\t\t</CardHeader>\n\t\t\t<CardContent>\n\t\t\t\t{loading && !data && (\n\t\t\t\t\t<span className=\"text-sm text-muted-foreground\">Loading…</span>\n\t\t\t\t)}\n\t\t\t\t{error && !data && (\n\t\t\t\t\t<span className=\"text-sm text-red-400\">{error.message}</span>\n\t\t\t\t)}\n\t\t\t\t{data && (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<FileSizesCard\n\t\t\t\t\t\t\tfiles={data.storage.files}\n\t\t\t\t\t\t\tpageSize={data.storage.pageSize}\n\t\t\t\t\t\t\tpageCount={data.storage.pageCount}\n\t\t\t\t\t\t\tfreelistPages={data.storage.freelistPages}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<TableRowCountsCard tables={data.tables} />\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t</CardContent>\n\t\t</Card>\n\t);\n}\n","/**\n * dashboard-client/src/tabs/MaintenanceTab/ActionsCard.tsx — Actions card.\n *\n * Extracted from MaintenanceTab.tsx (delegate-shell split). One-time\n * maintenance operations (vacuum, checkpoint, reindex, prune, …) with a\n * results history.\n */\nimport type React from \"react\";\nimport { useState, useCallback } from \"react\";\nimport type {\n\tMaintenanceAction,\n\tMaintenanceActionResult,\n} from \"@contracts\";\nimport { postMaintenanceAction } from \"../../api/client\";\nimport { Badge } from \"../../components/ui/badge\";\nimport { Button } from \"../../components/ui/button\";\nimport { Card, CardHeader, CardTitle } from \"../../components/ui/card\";\n\n// ---------------------------------------------------------------------------\n// Action config\n// ---------------------------------------------------------------------------\n\ninterface ActionDef {\n\tkey: string;\n\tlabel: string;\n\tdesc: string;\n\tdangerous: boolean;\n\tconfirm?: string;\n\tdaysOld?: boolean;\n}\n\nconst ACTIONS: ActionDef[] = [\n\t{\n\t\tkey: \"integrity-check\",\n\t\tlabel: \"Integrity Check\",\n\t\tdesc: \"Run PRAGMA integrity_check\",\n\t\tdangerous: false,\n\t},\n\t{\n\t\tkey: \"reconcile-dedup\",\n\t\tlabel: \"Reconcile Dedup Mirror\",\n\t\tdesc: \"Fix orphan dedup rows + backfill refs\",\n\t\tdangerous: false,\n\t\tconfirm: \"Reconcile dedup_mirror (safe read/write)?\",\n\t},\n\t{\n\t\tkey: \"checkpoint\",\n\t\tlabel: \"WAL Checkpoint\",\n\t\tdesc: \"Merge WAL into main DB (read-only)\",\n\t\tdangerous: false,\n\t},\n\t{\n\t\tkey: \"vacuum\",\n\t\tlabel: \"VACUUM\",\n\t\tdesc: \"Rebuild DB reclaiming free pages\",\n\t\tdangerous: true,\n\t\tconfirm: \"VACUUM rewrites the entire DB. Continue?\",\n\t},\n\t{\n\t\tkey: \"reindex\",\n\t\tlabel: \"REINDEX\",\n\t\tdesc: \"Rebuild all indexes\",\n\t\tdangerous: true,\n\t\tconfirm: \"REINDEX rebuilds indexes. Continue?\",\n\t},\n\t{\n\t\tkey: \"fts5-rebuild\",\n\t\tlabel: \"FTS5 Rebuild\",\n\t\tdesc: \"Rebuild full-text search index\",\n\t\tdangerous: true,\n\t\tconfirm: \"Rebuild FTS5 trigram index. Continue?\",\n\t},\n\t{\n\t\tkey: \"prune\",\n\t\tlabel: \"Prune Old Rows\",\n\t\tdesc: \"Delete transcripts + epochs older than N days\",\n\t\tdangerous: true,\n\t\tdaysOld: true,\n\t\tconfirm: \"Delete old raw_transcript rows. Continue?\",\n\t},\n];\n\n// ---------------------------------------------------------------------------\n// Actions card\n// ---------------------------------------------------------------------------\n\nexport function ActionsCard(): React.ReactElement {\n\tconst [results, setResults] = useState<MaintenanceActionResult[]>([]);\n\tconst [running, setRunning] = useState<string | null>(null);\n\tconst [days, setDays] = useState(\"30\");\n\n\tconst handleAction = useCallback(\n\t\tasync (def: ActionDef) => {\n\t\t\tconst action: MaintenanceAction = def.daysOld\n\t\t\t\t? { action: \"prune\", daysOld: Number(days) }\n\t\t\t\t: ({ action: def.key } as MaintenanceAction);\n\n\t\t\tsetRunning(def.key);\n\t\t\ttry {\n\t\t\t\tconst res = await postMaintenanceAction(action);\n\t\t\t\tsetResults((prev) =>\n\t\t\t\t\t[{ ...res, timestamp: Date.now() }, ...prev].slice(0, 20),\n\t\t\t\t);\n\t\t\t} catch (err) {\n\t\t\t\tsetResults((prev) =>\n\t\t\t\t\t[\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\toperation: def.key,\n\t\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\t\taffected: 0,\n\t\t\t\t\t\t\treclaimedBytes: 0,\n\t\t\t\t\t\t\tsummary: err instanceof Error ? err.message : String(err),\n\t\t\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\t\t},\n\t\t\t\t\t\t...prev,\n\t\t\t\t\t].slice(0, 20),\n\t\t\t\t);\n\t\t\t} finally {\n\t\t\t\tsetRunning(null);\n\t\t\t}\n\t\t},\n\t\t[days],\n\t);\n\n\treturn (\n\t\t<Card>\n\t\t\t<CardHeader>\n\t\t\t\t<CardTitle>Actions</CardTitle>\n\t\t\t</CardHeader>\n\t\t\t<div className=\"grid grid-cols-1 gap-3 lg:grid-cols-2\">\n\t\t\t\t{ACTIONS.map((def) => {\n\t\t\t\t\tconst isRunning = running === def.key;\n\t\t\t\t\tconst lastResult = results.find((r) => r.operation === def.key);\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tkey={def.key}\n\t\t\t\t\t\t\tclassName=\"flex items-start justify-between gap-3 rounded-lg border border-border/60 p-3\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<div className=\"min-w-0\">\n\t\t\t\t\t\t\t\t<div className=\"flex flex-wrap items-center gap-2\">\n\t\t\t\t\t\t\t\t\t<span className=\"font-semibold\">{def.label}</span>\n\t\t\t\t\t\t\t\t\t{def.dangerous && <Badge variant=\"danger\">DESTRUCTIVE</Badge>}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<div className=\"mt-1 text-xs text-muted-foreground\">{def.desc}</div>\n\t\t\t\t\t\t\t\t{lastResult && (\n\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\tclassName={`mt-1 text-xs ${lastResult.success ? \"text-emerald-400\" : \"text-red-400\"}`}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{lastResult.summary}\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div className=\"flex shrink-0 items-center gap-2\">\n\t\t\t\t\t\t\t\t{def.daysOld && (\n\t\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\t\ttype=\"number\"\n\t\t\t\t\t\t\t\t\t\tmin={1}\n\t\t\t\t\t\t\t\t\t\tmax={365}\n\t\t\t\t\t\t\t\t\t\tvalue={days}\n\t\t\t\t\t\t\t\t\t\tonChange={(e) => setDays(e.target.value)}\n\t\t\t\t\t\t\t\t\t\tclassName=\"w-16 rounded-md border border-border bg-bg-elevated/50 px-2 py-1 text-sm outline-none focus:border-primary\"\n\t\t\t\t\t\t\t\t\t\tdisabled={isRunning}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tvariant={def.dangerous ? \"ghost\" : \"default\"}\n\t\t\t\t\t\t\t\t\tclassName={\n\t\t\t\t\t\t\t\t\t\tdef.dangerous\n\t\t\t\t\t\t\t\t\t\t\t? \"border border-red-500/50 text-red-400 hover:bg-red-500/10 hover:text-red-300\"\n\t\t\t\t\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tdisabled={running !== null}\n\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\tif (def.confirm && !window.confirm(def.confirm)) return;\n\t\t\t\t\t\t\t\t\t\thandleAction(def);\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{isRunning ? \"Running…\" : \"Run\"}\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t);\n\t\t\t\t})}\n\t\t\t</div>\n\t\t</Card>\n\t);\n}\n","/**\n * dashboard-client/src/tabs/MaintenanceTab/DebugBundleCard.tsx — Debug Bundle card.\n *\n * Extracted from MaintenanceTab.tsx (delegate-shell split). Gather a diagnostic\n * bundle (events, config, schema health, store stats) and let the user copy or\n * download it for bug reports.\n */\nimport type React from \"react\";\nimport { useState, useCallback } from \"react\";\nimport type { DebugBundleResponse } from \"@contracts\";\nimport { fetchDebugBundle } from \"../../api/client\";\nimport { Button } from \"../../components/ui/button\";\nimport {\n\tCard,\n\tCardHeader,\n\tCardTitle,\n\tCardContent,\n} from \"../../components/ui/card\";\n\n// ---------------------------------------------------------------------------\n// Debug bundle card — gather diagnostic info for bug reports\n// ---------------------------------------------------------------------------\n\nexport function DebugBundleCard(): React.ReactElement {\n\tconst [bundle, setBundle] = useState<DebugBundleResponse | null>(null);\n\tconst [loading, setLoading] = useState(false);\n\tconst [error, setError] = useState<string | null>(null);\n\tconst [showJson, setShowJson] = useState(false);\n\n\tconst gather = useCallback(async () => {\n\t\tsetLoading(true);\n\t\tsetError(null);\n\t\ttry {\n\t\t\tconst res = await fetchDebugBundle();\n\t\t\tsetBundle(res);\n\t\t\tsetShowJson(true);\n\t\t} catch (err) {\n\t\t\tsetError(err instanceof Error ? err.message : String(err));\n\t\t} finally {\n\t\t\tsetLoading(false);\n\t\t}\n\t}, []);\n\n\tconst copyToClipboard = useCallback(() => {\n\t\tif (!bundle) return;\n\t\tconst text = JSON.stringify(bundle, null, 2);\n\t\tvoid navigator.clipboard.writeText(text).catch(() => {});\n\t}, [bundle]);\n\n\tconst downloadJson = useCallback(() => {\n\t\tif (!bundle) return;\n\t\tconst text = JSON.stringify(bundle, null, 2);\n\t\tconst blob = new Blob([text], { type: \"application/json\" });\n\t\tconst url = URL.createObjectURL(blob);\n\t\tconst a = document.createElement(\"a\");\n\t\ta.href = url;\n\t\ta.download = `mega-compact-debug-bundle-${bundle.builtAt}.json`;\n\t\ta.click();\n\t\tURL.revokeObjectURL(url);\n\t}, [bundle]);\n\n\tconst criticalCount = bundle?.criticalEvents.length ?? 0;\n\n\treturn (\n\t\t<Card>\n\t\t\t<CardHeader className=\"flex-row items-center justify-between space-y-0\">\n\t\t\t\t<CardTitle>Debug Bundle</CardTitle>\n\t\t\t\t{criticalCount > 0 && (\n\t\t\t\t\t<span className=\"text-xs text-amber-400\">\n\t\t\t\t\t\t{criticalCount} critical event{criticalCount !== 1 ? \"s\" : \"\"} found\n\t\t\t\t\t</span>\n\t\t\t\t)}\n\t\t\t</CardHeader>\n\t\t\t<CardContent>\n\t\t\t\t<p className=\"mb-3 text-sm text-muted-foreground\">\n\t\t\t\t\tGather a diagnostic bundle (recent events, config flags, schema health,\n\t\t\t\t\tstore stats) to attach to a bug report. Critical/compaction events are\n\t\t\t\t\thighlighted.\n\t\t\t\t</p>\n\t\t\t\t<Button type=\"button\" variant=\"glass\" onClick={gather} disabled={loading}>\n\t\t\t\t\t{loading ? \"Gathering…\" : \"Gather Debug Logs\"}\n\t\t\t\t</Button>\n\t\t\t\t{error && <div className=\"mt-2 text-sm text-red-400\">{error}</div>}\n\t\t\t\t{bundle && showJson && (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<div className=\"mb-2 mt-3 flex gap-2\">\n\t\t\t\t\t\t\t<Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={copyToClipboard}>\n\t\t\t\t\t\t\t\tCopy to clipboard\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t<Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={downloadJson}>\n\t\t\t\t\t\t\t\tDownload JSON\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tvariant=\"outline\"\n\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\tonClick={() => setShowJson((v) => !v)}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{showJson ? \"Hide\" : \"Show\"}\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t{criticalCount > 0 && (\n\t\t\t\t\t\t\t<div className=\"mt-3\">\n\t\t\t\t\t\t\t\t<div className=\"text-xs font-semibold text-amber-400\">\n\t\t\t\t\t\t\t\t\tCritical events ({criticalCount})\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<pre className=\"max-h-48 overflow-auto rounded-md border border-border/60 bg-bg-elevated/40 p-3 font-mono text-xs\">\n\t\t\t\t\t\t\t\t\t{JSON.stringify(bundle.criticalEvents, null, 2)}\n\t\t\t\t\t\t\t\t</pre>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t<pre className=\"mt-3 max-h-96 overflow-auto rounded-md border border-border/60 bg-bg-elevated/40 p-3 font-mono text-xs\">\n\t\t\t\t\t\t\t{JSON.stringify(bundle, null, 2)}\n\t\t\t\t\t\t</pre>\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t</CardContent>\n\t\t</Card>\n\t);\n}\n","/**\n * dashboard-client/src/tabs/MaintenanceTab/HealthMitigationCard.tsx — Health\n * Mitigation card.\n *\n * Extracted from MaintenanceTab.tsx (delegate-shell split). Toggles auto-\n * mitigation for degraded context (forced compaction / prefix break).\n */\nimport type React from \"react\";\nimport { useState, useCallback, useEffect } from \"react\";\nimport { Switch } from \"../../components/ui/switch\";\nimport {\n\tCard,\n\tCardHeader,\n\tCardTitle,\n\tCardContent,\n} from \"../../components/ui/card\";\n\n// ---------------------------------------------------------------------------\n// Health Mitigation card — toggle auto-mitigation for degraded context\n// ---------------------------------------------------------------------------\n\nexport function HealthMitigationCard(): React.ReactElement {\n\tconst [mitigate, setMitigate] = useState(false);\n\tconst [loading, setLoading] = useState(true);\n\tconst [saving, setSaving] = useState(false);\n\tconst [error, setError] = useState<string | null>(null);\n\n\tconst load = useCallback(async () => {\n\t\ttry {\n\t\t\tconst { fetchHealthSettings } = await import(\"../../api/health\");\n\t\t\tconst s = await fetchHealthSettings();\n\t\t\tsetMitigate(s.mitigate);\n\t\t} catch (e) {\n\t\t\tsetError(e instanceof Error ? e.message : String(e));\n\t\t} finally {\n\t\t\tsetLoading(false);\n\t\t}\n\t}, []);\n\n\tuseEffect(() => { void load(); }, [load]);\n\n\tconst toggle = useCallback(async () => {\n\t\tsetSaving(true);\n\t\tsetError(null);\n\t\ttry {\n\t\t\tconst { setHealthMitigate } = await import(\"../../api/health\");\n\t\t\tconst next = !mitigate;\n\t\t\tawait setHealthMitigate(next);\n\t\t\tsetMitigate(next);\n\t\t} catch (e) {\n\t\t\tsetError(e instanceof Error ? e.message : String(e));\n\t\t} finally {\n\t\t\tsetSaving(false);\n\t\t}\n\t}, [mitigate]);\n\n\treturn (\n\t\t<Card>\n\t\t\t<CardHeader>\n\t\t\t\t<CardTitle>Context Health Mitigation</CardTitle>\n\t\t\t</CardHeader>\n\t\t\t<CardContent>\n\t\t\t\t{loading ? (\n\t\t\t\t\t<p className=\"text-sm text-muted-foreground\">Loading…</p>\n\t\t\t\t) : (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t\t\t\t<Switch\n\t\t\t\t\t\t\t\tchecked={mitigate}\n\t\t\t\t\t\t\t\tonCheckedChange={toggle}\n\t\t\t\t\t\t\t\tdisabled={saving}\n\t\t\t\t\t\t\t\taria-label=\"Context health auto-mitigation\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<span className=\"text-sm\">\n\t\t\t\t\t\t\t\tAuto-mitigation {mitigate ? \"ON\" : \"OFF\"}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div className=\"mt-3 space-y-2 text-sm\">\n\t\t\t\t\t\t\t<p>\n\t\t\t\t\t\t\t\tWhen <strong>ON</strong>, the extension automatically intervenes\n\t\t\t\t\t\t\t\twhen context health degrades:\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t<ul className=\"list-disc space-y-1 pl-5\">\n\t\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t\t<strong>Forced compaction</strong> — when the composite health\n\t\t\t\t\t\t\t\t\tscore drops below 0.4 (severe drift or garbled output), a\n\t\t\t\t\t\t\t\t\tcompaction is triggered to flush the degraded context and\n\t\t\t\t\t\t\t\t\trebuild from clean checkpoints, even if the context window\n\t\t\t\t\t\t\t\t\tisn't full.\n\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t\t<strong>Prefix break</strong> — when KV cache poison is\n\t\t\t\t\t\t\t\t\tdetected (score < 0.3), the cached prefix is invalidated to\n\t\t\t\t\t\t\t\t\tforce a cache miss on the next turn, bypassing the corrupted KV\n\t\t\t\t\t\t\t\t\tstate.\n\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t</ul>\n\t\t\t\t\t\t\t<p className=\"rounded-md border border-amber-500/30 bg-amber-500/5 p-3 text-amber-400\">\n\t\t\t\t\t\t\t\tWARNING: both interventions have costs — forced compaction discards\n\t\t\t\t\t\t\t\tlive context, and prefix breaks kill cache savings. Only enable\n\t\t\t\t\t\t\t\twhen you're seeing degraded output (garbled text,\n\t\t\t\t\t\t\t\thallucinations, loss of coherence) and the Health tab confirms low\n\t\t\t\t\t\t\t\tscores.\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t<p className=\"text-muted-foreground\">\n\t\t\t\t\t\t\t\tAlso settable via env var:{\" \"}\n\t\t\t\t\t\t\t\t<code>MEGACOMPACT_CONTEXT_HEALTH_MITIGATE=1</code>. The dashboard\n\t\t\t\t\t\t\t\ttoggle persists to the store and takes precedence.\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t{error && <p className=\"text-sm text-red-400\">Error: {error}</p>}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t</CardContent>\n\t\t</Card>\n\t);\n}\n","/**\n * dashboard-client/src/tabs/MaintenanceTab.tsx — Maintenance tab (v0.11.2 S49B).\n *\n * Delegate-shell (extensions split): three cards (Schema Health, DB Stats,\n * Actions) plus the Debug Bundle and Health Mitigation cards. The heavy card\n * components live in ./MaintenanceTab/* to keep every file under the extensions\n * line limit. All cards fetch independently; failures in one do not block the\n * others.\n */\n\nimport type React from \"react\";\nimport { useCallback } from \"react\";\nimport type {\n\tDbStatsResponse,\n\tSchemaHealthResponse,\n} from \"@contracts\";\nimport { useApi } from \"../hooks/useApi\";\nimport { fetchDbStats, fetchSchemaHealth } from \"../api/client\";\nimport { SchemaHealthCard } from \"./MaintenanceTab/SchemaHealthCard\";\nimport { DbStatsCard } from \"./MaintenanceTab/DbStatsCard\";\nimport { ActionsCard } from \"./MaintenanceTab/ActionsCard\";\nimport { DebugBundleCard } from \"./MaintenanceTab/DebugBundleCard\";\nimport { HealthMitigationCard } from \"./MaintenanceTab/HealthMitigationCard\";\n\n// ---------------------------------------------------------------------------\n// Main tab component\n// ---------------------------------------------------------------------------\n\nexport default function MaintenanceTab(): React.ReactElement {\n\tconst {\n\t\tdata: dbStats,\n\t\tloading: statsLoading,\n\t\terror: statsError,\n\t} = useApi<DbStatsResponse>(\n\t\tuseCallback(() => fetchDbStats(), []),\n\t\t{ pollInterval: 15000 },\n\t);\n\n\tconst {\n\t\tdata: schemaHealth,\n\t\tloading: healthLoading,\n\t\terror: healthError,\n\t} = useApi<SchemaHealthResponse>(\n\t\tuseCallback(() => fetchSchemaHealth(), []),\n\t\t{ pollInterval: 10000 },\n\t);\n\n\treturn (\n\t\t<div className=\"flex flex-col gap-4\">\n\t\t\t<div className=\"grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-3\">\n\t\t\t\t<SchemaHealthCard\n\t\t\t\t\tdata={schemaHealth}\n\t\t\t\t\tloading={healthLoading}\n\t\t\t\t\terror={healthError}\n\t\t\t\t/>\n\t\t\t\t<DbStatsCard data={dbStats} loading={statsLoading} error={statsError} />\n\t\t\t</div>\n\t\t\t<ActionsCard />\n\t\t\t<DebugBundleCard />\n\t\t\t<HealthMitigationCard />\n\t\t</div>\n\t);\n}\n"],"file":"assets/MaintenanceTab-CS5HqDkY.js"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{j as e,r as u,m as V,n as z}from"./index-BBJ8LglL.js";import{T as P}from"./toggle-DnRtZDPW.js";const S={checkpoint:"#6366f1",turn:"#58a6ff","turn-content":"#22c55e",memory:"#f59e0b"},U={checkpoint:"Checkpoint",turn:"Turn","turn-content":"Turn Content",memory:"Memory"};function Y(t,s){return`M 0,-${s} L ${t},0 L 0,${s} L -${t},0 Z`}function Q(t){return!t||t==="active"?1:.5}function X(t,s,l,h,n,p,c){const x=p?S[h]??"#6366f1":"#d1d5db",i=n?"#ef4444":"none",m=Q(c);switch(h){case"checkpoint":return e.jsx("circle",{cx:t,cy:s,r:n?l+3:l,fill:x,opacity:m,stroke:i,strokeWidth:n?2:0});case"turn":return e.jsx("circle",{cx:t,cy:s,r:n?l+3:l,fill:"none",stroke:x,strokeWidth:2.5,opacity:m});case"turn-content":return e.jsxs("g",{children:[e.jsx("circle",{cx:t,cy:s,r:n?l+3:l,fill:"none",stroke:x,strokeWidth:2.5,opacity:m}),e.jsx("circle",{cx:t,cy:s,r:Math.max(3,l*.3),fill:x,opacity:m})]});case"memory":const d=l*.85,g=l*.85;return e.jsx("path",{d:Y(d,g),transform:`translate(${t}, ${s})`,fill:x,opacity:m,stroke:i,strokeWidth:n?2:0})}}const Z=5e3,O=.005,D=.01,_=.9,J=.1,L=50;function K(t){const s=t.nodes.map((n,p)=>{const c=2*Math.PI*p/Math.max(t.nodes.length,1),x=200;return{...n,pos:{x:Math.cos(c)*x+300,y:Math.sin(c)*x+200},vx:0,vy:0,pinned:!1}}),l=new Map;s.forEach((n,p)=>l.set(n.id,p));const h=t.edges.map(n=>{const p=l.get(n.source),c=l.get(n.target);return p===void 0||c===void 0||p===c?null:{source:p,target:c,weight:n.weight,type:n.type}}).filter(n=>n!==null);return{nodes:s,edges:h}}function ee(t){const{nodes:s,edges:l}=t,h=s.length;if(h!==0)for(let n=0;n<h;n++){if(s[n].pinned)continue;let p=0,c=0;for(let i=0;i<h;i++){if(n===i)continue;const m=s[n].pos.x-s[i].pos.x,d=s[n].pos.y-s[i].pos.y,g=m*m+d*d||1,v=Z/g,y=Math.sqrt(g);p+=m/y*v,c+=d/y*v}for(const i of l){let m;if(i.source===n)m=i.target;else if(i.target===n)m=i.source;else continue;const d=s[m].pos.x-s[n].pos.x,g=s[m].pos.y-s[n].pos.y;p+=d*O*i.weight,c+=g*O*i.weight}p-=s[n].pos.x*D,c-=s[n].pos.y*D,s[n].vx=(s[n].vx+p)*_,s[n].vy=(s[n].vy+c)*_;const x=Math.sqrt(s[n].vx*s[n].vx+s[n].vy*s[n].vy);x>L&&(s[n].vx=s[n].vx/x*L,s[n].vy=s[n].vy/x*L),x>J&&(s[n].pos.x+=s[n].vx,s[n].pos.y+=s[n].vy)}}const te=300,re=.3,k=900,w=600,f=40;function M(t){switch(t){case"temporal":return"#6366f1";case"semantic":return"#22c55e";case"raptor_parent":return"#f59e0b"}}const N=({color:t,shape:s,label:l})=>{const h={display:"inline-block",width:"10px",height:"10px",verticalAlign:"middle",marginRight:"3px",borderRadius:s.startsWith("hollow")||s==="filled-circle"?"50%":void 0};let n;return s==="line"?e.jsx("span",{style:{color:t,marginRight:"6px"},children:l}):(s==="filled-circle"?n=e.jsx("span",{style:{...h,backgroundColor:t}}):s==="hollow-circle"?n=e.jsx("span",{style:{...h,border:`2px solid ${t}`,backgroundColor:"transparent"}}):s==="hollow-ring"?n=e.jsx("span",{style:{...h,border:`2px solid ${t}`,backgroundColor:"transparent",position:"relative"},children:e.jsx("span",{style:{display:"block",width:"4px",height:"4px",borderRadius:"50%",backgroundColor:t,margin:"2px auto"}})}):n=e.jsx("span",{style:{...h,clipPath:"polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%)",backgroundColor:t}}),e.jsxs(e.Fragment,{children:[e.jsxs("span",{className:"memory-map-legend-item",children:[n,l]})," "]}))},se=()=>{const[t,s]=u.useState(null),[l,h]=u.useState(!0),[n,p]=u.useState(null),[c,x]=u.useState(null),[i,m]=u.useState(""),[d]=u.useState(""),[g,v]=u.useState(0),y=u.useRef(null),T=u.useRef(0);u.useEffect(()=>{let r=!1;const o=new URLSearchParams;return d&&o.set("sessionId",d),o.set("threshold","0.7"),o.set("maxEdgesPerNode","4"),h(!0),p(null),fetch(`/api/memory-map?${o.toString()}`).then(a=>{if(!a.ok)throw new Error(`HTTP ${a.status}`);return a.json()}).then(a=>{r||(s(a),y.current=K(a),v(1),h(!1))}).catch(a=>{r||(p(a instanceof Error?a.message:"Unknown error"),h(!1))}),()=>{r=!0,cancelAnimationFrame(T.current)}},[d]),u.useEffect(()=>{if(!y.current||g===0)return;const r=y.current;let o=0;const a=()=>{o>=te||(ee(r),o++,v(o),T.current=requestAnimationFrame(a))};return T.current=requestAnimationFrame(a),()=>cancelAnimationFrame(T.current)},[g]);const F=u.useCallback((r,o)=>{const a=y.current;a&&(a.nodes[o].pinned=!a.nodes[o].pinned,a.nodes[o].pinned||(a.nodes[o].vx=0,a.nodes[o].vy=0),x(b=>b?.id===r.id?null:r),v(b=>b+1))},[]),A=u.useMemo(()=>{const r=y.current;if(!r||!i)return null;const o=i.toLowerCase();return new Set(r.nodes.map((a,b)=>a.summaryTruncated.toLowerCase().includes(o)||a.label.toLowerCase().includes(o)?b:-1).filter(a=>a>=0))},[i]),C=u.useMemo(()=>{const r=t?.validation;return r?r.gatesPassed<r.gatesRun?{level:"red",label:"Gate failure"}:r.warnings.length>0?{level:"yellow",label:`${r.warnings.length} warning(s)`}:{level:"green",label:"Healthy"}:{level:"yellow",label:"No validation"}},[t?.validation]),W={green:"#22c55e",yellow:"#eab308",red:"#ef4444"},H=u.useMemo(()=>{const r=t?.validation;if(!r)return`${t?.metadata.totalNodes??0} nodes`;const o=[];return r.sources.checkpoint>0&&o.push(`${r.sources.checkpoint} checkpoints`),r.sources.turn>0&&o.push(`${r.sources.turn} turns`),r.sources.turnContent>0&&o.push(`${r.sources.turnContent} turn-content`),r.sources.memory>0&&o.push(`${r.sources.memory} memories`),o.length===0&&o.push(`${t?.metadata.totalNodes??0} nodes`),o.join(" · ")},[t?.validation,t?.metadata.totalNodes]),I=u.useMemo(()=>{const r=t?.validation;if(!r)return"";const o=[];return o.push(r.sources.checkpoint>0?"✓ checkpoints":"✗ checkpoints"),o.push(r.sources.turn>0?"✓ turns":"✗ turns"),o.push(r.sources.turnContent>0?"✓ turn-content":"✗ turn-content"),o.push(r.sources.memory>0?"✓ memories":"✗ memories"),o.join(" | ")},[t?.validation]),B=u.useMemo(()=>{const r=t?.validation;return r?r.sources.checkpoint===0&&r.sources.turn===0&&r.sources.turnContent===0&&r.sources.memory===0:t?.metadata.totalNodes===0},[t?.validation,t?.metadata.totalNodes]);if(l)return e.jsx("div",{className:"rounded-lg border border-border bg-bg-card p-6 text-center text-sm text-muted-foreground",children:"Loading memory graph..."});if(n)return e.jsxs("div",{className:"rounded-lg border border-border bg-bg-card p-6 text-center text-sm",children:[e.jsxs("p",{className:"text-red-400",children:["Failed to load memory map: ",n]}),e.jsx("button",{className:"mt-3 rounded-md border border-border px-3 py-1.5 text-sm transition-colors hover:bg-bg-elevated hover:text-foreground",onClick:()=>v(r=>r+1),children:"Retry"})]});if(!t||!y.current||B)return e.jsx("div",{className:"rounded-lg border border-border bg-bg-card p-6 text-sm text-muted-foreground",children:e.jsx("p",{children:"Memories appear after your first compaction. The graph shows checkpoints (compaction summaries) linked by semantic similarity and time. Run a longer session or lower the compaction tier to see it sooner."})});const j=y.current;return e.jsxs("div",{className:"flex flex-col gap-3",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("input",{type:"text",placeholder:"Search memories...",value:i,onInput:r=>m(r.target.value),className:"w-56 rounded-md border border-border bg-bg-elevated/50 px-3 py-2 text-sm outline-none transition-colors focus:border-primary"}),e.jsxs("span",{className:"text-xs text-muted-foreground",children:[e.jsx("span",{children:H})," · ",e.jsxs("span",{children:[t.edges.length," edges"]})]}),e.jsx("span",{className:"ml-auto rounded-full px-2 py-1 text-[11px] font-semibold text-white",style:{backgroundColor:W[C.level]??"#6b7280"},title:`Validation: ${C.label}`,children:C.level==="green"?"Healthy":C.level==="yellow"?"Warnings":"Critical"})]}),I?e.jsx("div",{className:"text-[11px] text-muted-foreground",children:I}):null,e.jsxs("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-1 rounded-lg border border-border/60 bg-bg-card px-3 py-2 text-xs",children:[e.jsx("span",{className:"font-semibold text-muted-foreground",children:"Nodes:"}),e.jsx(N,{type:"node",color:S.checkpoint,shape:"filled-circle",label:"Checkpoint"}),e.jsx(N,{type:"node",color:S.turn,shape:"hollow-circle",label:"Turn"}),e.jsx(N,{type:"node",color:S["turn-content"],shape:"hollow-ring",label:"Turn Content"}),e.jsx(N,{type:"node",color:S.memory,shape:"diamond",label:"Memory"}),e.jsx("span",{className:"font-semibold text-muted-foreground",children:"Edges:"}),e.jsx(N,{type:"edge",color:M("semantic"),shape:"line",label:"Semantic"}),e.jsx(N,{type:"edge",color:M("temporal"),shape:"line",label:"Temporal"}),e.jsx(N,{type:"edge",color:M("raptor_parent"),shape:"line",label:"Raptor"})]}),e.jsxs("svg",{width:k,height:w,viewBox:`0 0 ${k} ${w}`,className:"memory-map-svg",children:[j.edges.map((r,o)=>{const a=j.nodes[r.source],b=j.nodes[r.target],R=M(r.type),E=Math.max(1,r.weight*2.5);return e.jsx("line",{x1:f+a.pos.x/(j.nodes.length||1)*(k-2*f),y1:f+a.pos.y/(j.nodes.length||1)*(w-2*f),x2:f+b.pos.x/(j.nodes.length||1)*(k-2*f),y2:f+b.pos.y/(j.nodes.length||1)*(w-2*f),stroke:R,strokeWidth:E,opacity:re},`edge-${o}`)}),j.nodes.map((r,o)=>{const a=f+r.pos.x/(j.nodes.length||1)*(k-2*f),b=f+r.pos.y/(j.nodes.length||1)*(w-2*f),R=Math.min(20,8+r.tokenEstimate/500),E=A?A.has(o):!0,G=c?.id===r.id,q=r.label.length>20?r.label.slice(0,18)+"...":r.label;return e.jsxs("g",{className:"memory-map-node-group",onClick:()=>F(r,o),style:{cursor:"pointer"},children:[X(a,b,R,r.nodeType,G,E,r.dedupStatus),e.jsx("text",{x:a,y:b+R+12,textAnchor:"middle",fontSize:"9px",fill:"#374151",className:"memory-map-label",children:q})]},`node-${o}`)})]}),c?e.jsxs("div",{className:"rounded-lg border border-border/60 bg-bg-card p-4 text-sm",children:[e.jsxs("h3",{className:"font-heading text-base font-semibold",children:[e.jsx("span",{className:"mr-1.5 text-xs font-normal text-muted-foreground",children:U[c.nodeType]}),c.label]}),e.jsx("p",{className:"mt-1",children:c.summaryTruncated}),c.topicSummary?e.jsxs("p",{className:"mt-1",children:["Topic: ",c.topicSummary]}):null,e.jsxs("p",{className:"mt-1",children:["Tokens: ",c.tokenEstimate," | Decisions: ",c.decisionCount]}),e.jsxs("p",{children:["Session: ",c.sessionId]}),e.jsxs("p",{children:["Raptor Level: ",c.raptorLevel]}),e.jsx("p",{className:"mt-1 text-muted-foreground",children:c.textSnippet})]}):null]})};function ne(t){return t===0?"#d4a017":t===1?"#3b82f6":"#14b8a6"}function $(t){return t?new Date(t).toLocaleString():"—"}function oe({node:t}){const s=ne(t.level),l=t.children.length>0?`${t.children.length} child${t.children.length===1?"":"ren"}`:"leaf";return e.jsxs("div",{style:{background:"#14142b",border:`1px solid ${s}`,borderRadius:"8px",padding:"0.75rem 1rem",marginBottom:"0.6rem",marginLeft:t.level*24,maxWidth:"90%"},children:[e.jsxs("div",{style:{display:"flex",gap:"0.75rem",alignItems:"center",marginBottom:"0.35rem"},children:[e.jsxs("span",{style:{display:"inline-block",background:s,color:"#fff",borderRadius:"10px",padding:"1px 8px",fontSize:"11px",fontWeight:600},children:["L",t.level]}),e.jsxs("span",{style:{fontSize:"12px",color:"#6b7280"},children:[l," · ",t.tokenEstimate," tok · ",t.qualityMarker]}),e.jsx("span",{style:{fontSize:"12px",color:"#6b7280",marginLeft:"auto"},children:$(t.builtAt)})]}),e.jsx("div",{style:{fontSize:"0.92rem",color:"#e5e7eb"},children:t.summary})]})}function le(){const[t,s]=u.useState(null),[l,h]=u.useState(null),[n,p]=u.useState(!0),[c,x]=u.useState(null);if(u.useEffect(()=>{let d=!1;return p(!0),x(null),Promise.all([V(),z()]).then(([g,v])=>{d||(s(g),h(v),p(!1))}).catch(g=>{d||(x(g instanceof Error?g.message:"Unknown error"),p(!1))}),()=>{d=!0}},[]),n)return e.jsx("div",{className:"rounded-lg border border-border bg-bg-card p-6 text-center text-sm text-muted-foreground",children:"Loading RAPTOR tree..."});if(c)return e.jsx("div",{className:"rounded-lg border border-dashed border-border bg-bg-card p-8 text-center text-sm",children:e.jsxs("p",{className:"text-red-400",children:["Failed to load RAPTOR tree: ",c]})});if(!t||t.empty||t.nodes.length===0)return e.jsx("div",{className:"rounded-lg border border-dashed border-border bg-bg-card p-8 text-center text-sm text-muted-foreground",children:e.jsx("p",{children:"No RAPTOR tree built yet — run a compaction (the tree builds during compaction)."})});const i=l&&!l.empty?l.builds[0]:null,m=i?.coherenceScore!=null?Math.round(i.coherenceScore*100):null;return e.jsxs("div",{className:"w-full p-4",children:[e.jsxs("div",{className:"mb-4 flex items-center gap-6 text-sm text-muted-foreground",children:[e.jsxs("span",{children:[e.jsx("strong",{children:t.nodes.length})," nodes"]}),e.jsxs("span",{children:[e.jsx("strong",{children:t.levels+1})," levels"]}),e.jsxs("span",{children:["Built ",$(t.builtAt??0)]}),i&&e.jsxs(e.Fragment,{children:[e.jsxs("span",{children:["Coherence:"," ",e.jsx("strong",{style:{color:m!=null&&m>=70?"#22c55e":"#f59e0b"},children:m!=null?`${m}%`:"—"})]}),e.jsxs("span",{children:["Leaves: ",e.jsx("strong",{children:i.leafCount})]}),e.jsxs("span",{children:["Depth: ",e.jsx("strong",{children:i.depth})]}),i.timedOut&&e.jsx("span",{style:{color:"#ef4444"},children:"budget timeout"})]})]}),l&&!l.empty&&l.builds.length>1&&e.jsxs("details",{className:"mb-4",children:[e.jsxs("summary",{className:"cursor-pointer text-xs text-muted-foreground",children:["Build history (",l.builds.length," builds)"]}),e.jsx("div",{className:"mt-2 space-y-1",children:l.builds.slice(0,10).map(d=>e.jsxs("div",{className:"flex items-center gap-4 text-xs text-muted-foreground",children:[e.jsx("span",{children:$(d.completedAt)}),e.jsxs("span",{children:[d.nodeCount," nodes"]}),e.jsxs("span",{children:[d.leafCount," leaves"]}),e.jsxs("span",{children:["depth ",d.depth]}),e.jsxs("span",{children:["coherence"," ",d.coherenceScore!=null?`${Math.round(d.coherenceScore*100)}%`:"—"]}),d.timedOut&&e.jsx("span",{style:{color:"#ef4444"},children:"timeout"})]},d.buildId))})]}),t.nodes.map(d=>e.jsx(oe,{node:d},d.id))]})}const ie=()=>{const[t,s]=u.useState("map");return e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsxs("nav",{className:"flex gap-2 border-b border-border pb-2 pt-2","aria-label":"Memory map sections",children:[e.jsx(P,{pressed:t==="map",onClick:()=>s("map"),"aria-label":"Memory Map view",children:"Memory Map"}),e.jsx(P,{pressed:t==="raptor",onClick:()=>s("raptor"),"aria-label":"RAPTOR Tree view",children:"RAPTOR Tree"})]}),t==="map"&&e.jsx(se,{}),t==="raptor"&&e.jsx(le,{})]})};export{ie as default};
|
|
2
|
-
//# sourceMappingURL=MemoryMapTab-
|
|
1
|
+
import{j as e,r as u,m as V,n as z}from"./index-CL6Af_JZ.js";import{T as P}from"./toggle-DHbWo-CW.js";const S={checkpoint:"#6366f1",turn:"#58a6ff","turn-content":"#22c55e",memory:"#f59e0b"},U={checkpoint:"Checkpoint",turn:"Turn","turn-content":"Turn Content",memory:"Memory"};function Y(t,s){return`M 0,-${s} L ${t},0 L 0,${s} L -${t},0 Z`}function Q(t){return!t||t==="active"?1:.5}function X(t,s,l,h,n,p,c){const x=p?S[h]??"#6366f1":"#d1d5db",i=n?"#ef4444":"none",m=Q(c);switch(h){case"checkpoint":return e.jsx("circle",{cx:t,cy:s,r:n?l+3:l,fill:x,opacity:m,stroke:i,strokeWidth:n?2:0});case"turn":return e.jsx("circle",{cx:t,cy:s,r:n?l+3:l,fill:"none",stroke:x,strokeWidth:2.5,opacity:m});case"turn-content":return e.jsxs("g",{children:[e.jsx("circle",{cx:t,cy:s,r:n?l+3:l,fill:"none",stroke:x,strokeWidth:2.5,opacity:m}),e.jsx("circle",{cx:t,cy:s,r:Math.max(3,l*.3),fill:x,opacity:m})]});case"memory":const d=l*.85,g=l*.85;return e.jsx("path",{d:Y(d,g),transform:`translate(${t}, ${s})`,fill:x,opacity:m,stroke:i,strokeWidth:n?2:0})}}const Z=5e3,O=.005,D=.01,_=.9,J=.1,L=50;function K(t){const s=t.nodes.map((n,p)=>{const c=2*Math.PI*p/Math.max(t.nodes.length,1),x=200;return{...n,pos:{x:Math.cos(c)*x+300,y:Math.sin(c)*x+200},vx:0,vy:0,pinned:!1}}),l=new Map;s.forEach((n,p)=>l.set(n.id,p));const h=t.edges.map(n=>{const p=l.get(n.source),c=l.get(n.target);return p===void 0||c===void 0||p===c?null:{source:p,target:c,weight:n.weight,type:n.type}}).filter(n=>n!==null);return{nodes:s,edges:h}}function ee(t){const{nodes:s,edges:l}=t,h=s.length;if(h!==0)for(let n=0;n<h;n++){if(s[n].pinned)continue;let p=0,c=0;for(let i=0;i<h;i++){if(n===i)continue;const m=s[n].pos.x-s[i].pos.x,d=s[n].pos.y-s[i].pos.y,g=m*m+d*d||1,v=Z/g,y=Math.sqrt(g);p+=m/y*v,c+=d/y*v}for(const i of l){let m;if(i.source===n)m=i.target;else if(i.target===n)m=i.source;else continue;const d=s[m].pos.x-s[n].pos.x,g=s[m].pos.y-s[n].pos.y;p+=d*O*i.weight,c+=g*O*i.weight}p-=s[n].pos.x*D,c-=s[n].pos.y*D,s[n].vx=(s[n].vx+p)*_,s[n].vy=(s[n].vy+c)*_;const x=Math.sqrt(s[n].vx*s[n].vx+s[n].vy*s[n].vy);x>L&&(s[n].vx=s[n].vx/x*L,s[n].vy=s[n].vy/x*L),x>J&&(s[n].pos.x+=s[n].vx,s[n].pos.y+=s[n].vy)}}const te=300,re=.3,k=900,w=600,f=40;function M(t){switch(t){case"temporal":return"#6366f1";case"semantic":return"#22c55e";case"raptor_parent":return"#f59e0b"}}const N=({color:t,shape:s,label:l})=>{const h={display:"inline-block",width:"10px",height:"10px",verticalAlign:"middle",marginRight:"3px",borderRadius:s.startsWith("hollow")||s==="filled-circle"?"50%":void 0};let n;return s==="line"?e.jsx("span",{style:{color:t,marginRight:"6px"},children:l}):(s==="filled-circle"?n=e.jsx("span",{style:{...h,backgroundColor:t}}):s==="hollow-circle"?n=e.jsx("span",{style:{...h,border:`2px solid ${t}`,backgroundColor:"transparent"}}):s==="hollow-ring"?n=e.jsx("span",{style:{...h,border:`2px solid ${t}`,backgroundColor:"transparent",position:"relative"},children:e.jsx("span",{style:{display:"block",width:"4px",height:"4px",borderRadius:"50%",backgroundColor:t,margin:"2px auto"}})}):n=e.jsx("span",{style:{...h,clipPath:"polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%)",backgroundColor:t}}),e.jsxs(e.Fragment,{children:[e.jsxs("span",{className:"memory-map-legend-item",children:[n,l]})," "]}))},se=()=>{const[t,s]=u.useState(null),[l,h]=u.useState(!0),[n,p]=u.useState(null),[c,x]=u.useState(null),[i,m]=u.useState(""),[d]=u.useState(""),[g,v]=u.useState(0),y=u.useRef(null),T=u.useRef(0);u.useEffect(()=>{let r=!1;const o=new URLSearchParams;return d&&o.set("sessionId",d),o.set("threshold","0.7"),o.set("maxEdgesPerNode","4"),h(!0),p(null),fetch(`/api/memory-map?${o.toString()}`).then(a=>{if(!a.ok)throw new Error(`HTTP ${a.status}`);return a.json()}).then(a=>{r||(s(a),y.current=K(a),v(1),h(!1))}).catch(a=>{r||(p(a instanceof Error?a.message:"Unknown error"),h(!1))}),()=>{r=!0,cancelAnimationFrame(T.current)}},[d]),u.useEffect(()=>{if(!y.current||g===0)return;const r=y.current;let o=0;const a=()=>{o>=te||(ee(r),o++,v(o),T.current=requestAnimationFrame(a))};return T.current=requestAnimationFrame(a),()=>cancelAnimationFrame(T.current)},[g]);const F=u.useCallback((r,o)=>{const a=y.current;a&&(a.nodes[o].pinned=!a.nodes[o].pinned,a.nodes[o].pinned||(a.nodes[o].vx=0,a.nodes[o].vy=0),x(b=>b?.id===r.id?null:r),v(b=>b+1))},[]),A=u.useMemo(()=>{const r=y.current;if(!r||!i)return null;const o=i.toLowerCase();return new Set(r.nodes.map((a,b)=>a.summaryTruncated.toLowerCase().includes(o)||a.label.toLowerCase().includes(o)?b:-1).filter(a=>a>=0))},[i]),C=u.useMemo(()=>{const r=t?.validation;return r?r.gatesPassed<r.gatesRun?{level:"red",label:"Gate failure"}:r.warnings.length>0?{level:"yellow",label:`${r.warnings.length} warning(s)`}:{level:"green",label:"Healthy"}:{level:"yellow",label:"No validation"}},[t?.validation]),W={green:"#22c55e",yellow:"#eab308",red:"#ef4444"},H=u.useMemo(()=>{const r=t?.validation;if(!r)return`${t?.metadata.totalNodes??0} nodes`;const o=[];return r.sources.checkpoint>0&&o.push(`${r.sources.checkpoint} checkpoints`),r.sources.turn>0&&o.push(`${r.sources.turn} turns`),r.sources.turnContent>0&&o.push(`${r.sources.turnContent} turn-content`),r.sources.memory>0&&o.push(`${r.sources.memory} memories`),o.length===0&&o.push(`${t?.metadata.totalNodes??0} nodes`),o.join(" · ")},[t?.validation,t?.metadata.totalNodes]),I=u.useMemo(()=>{const r=t?.validation;if(!r)return"";const o=[];return o.push(r.sources.checkpoint>0?"✓ checkpoints":"✗ checkpoints"),o.push(r.sources.turn>0?"✓ turns":"✗ turns"),o.push(r.sources.turnContent>0?"✓ turn-content":"✗ turn-content"),o.push(r.sources.memory>0?"✓ memories":"✗ memories"),o.join(" | ")},[t?.validation]),B=u.useMemo(()=>{const r=t?.validation;return r?r.sources.checkpoint===0&&r.sources.turn===0&&r.sources.turnContent===0&&r.sources.memory===0:t?.metadata.totalNodes===0},[t?.validation,t?.metadata.totalNodes]);if(l)return e.jsx("div",{className:"rounded-lg border border-border bg-bg-card p-6 text-center text-sm text-muted-foreground",children:"Loading memory graph..."});if(n)return e.jsxs("div",{className:"rounded-lg border border-border bg-bg-card p-6 text-center text-sm",children:[e.jsxs("p",{className:"text-red-400",children:["Failed to load memory map: ",n]}),e.jsx("button",{className:"mt-3 rounded-md border border-border px-3 py-1.5 text-sm transition-colors hover:bg-bg-elevated hover:text-foreground",onClick:()=>v(r=>r+1),children:"Retry"})]});if(!t||!y.current||B)return e.jsx("div",{className:"rounded-lg border border-border bg-bg-card p-6 text-sm text-muted-foreground",children:e.jsx("p",{children:"Memories appear after your first compaction. The graph shows checkpoints (compaction summaries) linked by semantic similarity and time. Run a longer session or lower the compaction tier to see it sooner."})});const j=y.current;return e.jsxs("div",{className:"flex flex-col gap-3",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("input",{type:"text",placeholder:"Search memories...",value:i,onInput:r=>m(r.target.value),className:"w-56 rounded-md border border-border bg-bg-elevated/50 px-3 py-2 text-sm outline-none transition-colors focus:border-primary"}),e.jsxs("span",{className:"text-xs text-muted-foreground",children:[e.jsx("span",{children:H})," · ",e.jsxs("span",{children:[t.edges.length," edges"]})]}),e.jsx("span",{className:"ml-auto rounded-full px-2 py-1 text-[11px] font-semibold text-white",style:{backgroundColor:W[C.level]??"#6b7280"},title:`Validation: ${C.label}`,children:C.level==="green"?"Healthy":C.level==="yellow"?"Warnings":"Critical"})]}),I?e.jsx("div",{className:"text-[11px] text-muted-foreground",children:I}):null,e.jsxs("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-1 rounded-lg border border-border/60 bg-bg-card px-3 py-2 text-xs",children:[e.jsx("span",{className:"font-semibold text-muted-foreground",children:"Nodes:"}),e.jsx(N,{type:"node",color:S.checkpoint,shape:"filled-circle",label:"Checkpoint"}),e.jsx(N,{type:"node",color:S.turn,shape:"hollow-circle",label:"Turn"}),e.jsx(N,{type:"node",color:S["turn-content"],shape:"hollow-ring",label:"Turn Content"}),e.jsx(N,{type:"node",color:S.memory,shape:"diamond",label:"Memory"}),e.jsx("span",{className:"font-semibold text-muted-foreground",children:"Edges:"}),e.jsx(N,{type:"edge",color:M("semantic"),shape:"line",label:"Semantic"}),e.jsx(N,{type:"edge",color:M("temporal"),shape:"line",label:"Temporal"}),e.jsx(N,{type:"edge",color:M("raptor_parent"),shape:"line",label:"Raptor"})]}),e.jsxs("svg",{width:k,height:w,viewBox:`0 0 ${k} ${w}`,className:"memory-map-svg",children:[j.edges.map((r,o)=>{const a=j.nodes[r.source],b=j.nodes[r.target],R=M(r.type),E=Math.max(1,r.weight*2.5);return e.jsx("line",{x1:f+a.pos.x/(j.nodes.length||1)*(k-2*f),y1:f+a.pos.y/(j.nodes.length||1)*(w-2*f),x2:f+b.pos.x/(j.nodes.length||1)*(k-2*f),y2:f+b.pos.y/(j.nodes.length||1)*(w-2*f),stroke:R,strokeWidth:E,opacity:re},`edge-${o}`)}),j.nodes.map((r,o)=>{const a=f+r.pos.x/(j.nodes.length||1)*(k-2*f),b=f+r.pos.y/(j.nodes.length||1)*(w-2*f),R=Math.min(20,8+r.tokenEstimate/500),E=A?A.has(o):!0,G=c?.id===r.id,q=r.label.length>20?r.label.slice(0,18)+"...":r.label;return e.jsxs("g",{className:"memory-map-node-group",onClick:()=>F(r,o),style:{cursor:"pointer"},children:[X(a,b,R,r.nodeType,G,E,r.dedupStatus),e.jsx("text",{x:a,y:b+R+12,textAnchor:"middle",fontSize:"9px",fill:"#374151",className:"memory-map-label",children:q})]},`node-${o}`)})]}),c?e.jsxs("div",{className:"rounded-lg border border-border/60 bg-bg-card p-4 text-sm",children:[e.jsxs("h3",{className:"font-heading text-base font-semibold",children:[e.jsx("span",{className:"mr-1.5 text-xs font-normal text-muted-foreground",children:U[c.nodeType]}),c.label]}),e.jsx("p",{className:"mt-1",children:c.summaryTruncated}),c.topicSummary?e.jsxs("p",{className:"mt-1",children:["Topic: ",c.topicSummary]}):null,e.jsxs("p",{className:"mt-1",children:["Tokens: ",c.tokenEstimate," | Decisions: ",c.decisionCount]}),e.jsxs("p",{children:["Session: ",c.sessionId]}),e.jsxs("p",{children:["Raptor Level: ",c.raptorLevel]}),e.jsx("p",{className:"mt-1 text-muted-foreground",children:c.textSnippet})]}):null]})};function ne(t){return t===0?"#d4a017":t===1?"#3b82f6":"#14b8a6"}function $(t){return t?new Date(t).toLocaleString():"—"}function oe({node:t}){const s=ne(t.level),l=t.children.length>0?`${t.children.length} child${t.children.length===1?"":"ren"}`:"leaf";return e.jsxs("div",{style:{background:"#14142b",border:`1px solid ${s}`,borderRadius:"8px",padding:"0.75rem 1rem",marginBottom:"0.6rem",marginLeft:t.level*24,maxWidth:"90%"},children:[e.jsxs("div",{style:{display:"flex",gap:"0.75rem",alignItems:"center",marginBottom:"0.35rem"},children:[e.jsxs("span",{style:{display:"inline-block",background:s,color:"#fff",borderRadius:"10px",padding:"1px 8px",fontSize:"11px",fontWeight:600},children:["L",t.level]}),e.jsxs("span",{style:{fontSize:"12px",color:"#6b7280"},children:[l," · ",t.tokenEstimate," tok · ",t.qualityMarker]}),e.jsx("span",{style:{fontSize:"12px",color:"#6b7280",marginLeft:"auto"},children:$(t.builtAt)})]}),e.jsx("div",{style:{fontSize:"0.92rem",color:"#e5e7eb"},children:t.summary})]})}function le(){const[t,s]=u.useState(null),[l,h]=u.useState(null),[n,p]=u.useState(!0),[c,x]=u.useState(null);if(u.useEffect(()=>{let d=!1;return p(!0),x(null),Promise.all([V(),z()]).then(([g,v])=>{d||(s(g),h(v),p(!1))}).catch(g=>{d||(x(g instanceof Error?g.message:"Unknown error"),p(!1))}),()=>{d=!0}},[]),n)return e.jsx("div",{className:"rounded-lg border border-border bg-bg-card p-6 text-center text-sm text-muted-foreground",children:"Loading RAPTOR tree..."});if(c)return e.jsx("div",{className:"rounded-lg border border-dashed border-border bg-bg-card p-8 text-center text-sm",children:e.jsxs("p",{className:"text-red-400",children:["Failed to load RAPTOR tree: ",c]})});if(!t||t.empty||t.nodes.length===0)return e.jsx("div",{className:"rounded-lg border border-dashed border-border bg-bg-card p-8 text-center text-sm text-muted-foreground",children:e.jsx("p",{children:"No RAPTOR tree built yet — run a compaction (the tree builds during compaction)."})});const i=l&&!l.empty?l.builds[0]:null,m=i?.coherenceScore!=null?Math.round(i.coherenceScore*100):null;return e.jsxs("div",{className:"w-full p-4",children:[e.jsxs("div",{className:"mb-4 flex items-center gap-6 text-sm text-muted-foreground",children:[e.jsxs("span",{children:[e.jsx("strong",{children:t.nodes.length})," nodes"]}),e.jsxs("span",{children:[e.jsx("strong",{children:t.levels+1})," levels"]}),e.jsxs("span",{children:["Built ",$(t.builtAt??0)]}),i&&e.jsxs(e.Fragment,{children:[e.jsxs("span",{children:["Coherence:"," ",e.jsx("strong",{style:{color:m!=null&&m>=70?"#22c55e":"#f59e0b"},children:m!=null?`${m}%`:"—"})]}),e.jsxs("span",{children:["Leaves: ",e.jsx("strong",{children:i.leafCount})]}),e.jsxs("span",{children:["Depth: ",e.jsx("strong",{children:i.depth})]}),i.timedOut&&e.jsx("span",{style:{color:"#ef4444"},children:"budget timeout"})]})]}),l&&!l.empty&&l.builds.length>1&&e.jsxs("details",{className:"mb-4",children:[e.jsxs("summary",{className:"cursor-pointer text-xs text-muted-foreground",children:["Build history (",l.builds.length," builds)"]}),e.jsx("div",{className:"mt-2 space-y-1",children:l.builds.slice(0,10).map(d=>e.jsxs("div",{className:"flex items-center gap-4 text-xs text-muted-foreground",children:[e.jsx("span",{children:$(d.completedAt)}),e.jsxs("span",{children:[d.nodeCount," nodes"]}),e.jsxs("span",{children:[d.leafCount," leaves"]}),e.jsxs("span",{children:["depth ",d.depth]}),e.jsxs("span",{children:["coherence"," ",d.coherenceScore!=null?`${Math.round(d.coherenceScore*100)}%`:"—"]}),d.timedOut&&e.jsx("span",{style:{color:"#ef4444"},children:"timeout"})]},d.buildId))})]}),t.nodes.map(d=>e.jsx(oe,{node:d},d.id))]})}const ie=()=>{const[t,s]=u.useState("map");return e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsxs("nav",{className:"flex gap-2 border-b border-border pb-2 pt-2","aria-label":"Memory map sections",children:[e.jsx(P,{pressed:t==="map",onClick:()=>s("map"),"aria-label":"Memory Map view",children:"Memory Map"}),e.jsx(P,{pressed:t==="raptor",onClick:()=>s("raptor"),"aria-label":"RAPTOR Tree view",children:"RAPTOR Tree"})]}),t==="map"&&e.jsx(se,{}),t==="raptor"&&e.jsx(le,{})]})};export{ie as default};
|
|
2
|
+
//# sourceMappingURL=MemoryMapTab-Oq-iqvUq.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MemoryMapTab-DaAxLJ5x.js","sources":["../../src/memory-map-shapes.tsx","../../src/memory-map-layout.ts","../../src/tabs/MemoryMapTab/MemoryMapView.tsx","../../src/tabs/MemoryMapTab/RaptorTreeView.tsx","../../src/tabs/MemoryMapTab.tsx"],"sourcesContent":["/**\n * memory-map-shapes.tsx — Node shape rendering utilities for MemoryMapTab (D3).\n *\n * Node shape encodes nodeType: checkpoint = filled circle, turn = hollow circle,\n * turn-content = hollow+ring, memory = diamond.\n * Delegate-shell pattern: thin rendering helpers, no state, no side effects.\n */\nimport type React from \"react\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type NodeType = \"checkpoint\" | \"turn\" | \"turn-content\" | \"memory\";\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nexport const NODE_COLORS: Record<NodeType, string> = {\n checkpoint: \"#6366f1\",\n turn: \"#58a6ff\",\n \"turn-content\": \"#22c55e\",\n memory: \"#f59e0b\",\n};\n\nexport const NODE_TYPE_LABELS: Record<NodeType, string> = {\n checkpoint: \"Checkpoint\",\n turn: \"Turn\",\n \"turn-content\": \"Turn Content\",\n memory: \"Memory\",\n};\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** SVG path for a diamond centered at (0,0) with given half-width/height. */\nfunction diamondPath(hw: number, hh: number): string {\n return `M 0,-${hh} L ${hw},0 L 0,${hh} L -${hw},0 Z`;\n}\n\nfunction nodeOpacity(dedupStatus: string | undefined): number {\n if (!dedupStatus || dedupStatus === \"active\") return 1;\n return 0.5;\n}\n\n// ---------------------------------------------------------------------------\n// Render function\n// ---------------------------------------------------------------------------\n\n/** Render an SVG shape for a node based on its nodeType. */\nexport function renderNodeShape(\n cx: number,\n cy: number,\n radius: number,\n nodeType: NodeType,\n isSelected: boolean,\n isFiltered: boolean,\n dedupStatus: string | undefined,\n): React.ReactElement {\n const fill = isFiltered ? NODE_COLORS[nodeType] ?? \"#6366f1\" : \"#d1d5db\";\n const strokeColor = isSelected ? \"#ef4444\" : \"none\";\n const opacity = nodeOpacity(dedupStatus);\n\n switch (nodeType) {\n case \"checkpoint\":\n return (\n <circle\n cx={cx}\n cy={cy}\n r={isSelected ? radius + 3 : radius}\n fill={fill}\n opacity={opacity}\n stroke={strokeColor}\n strokeWidth={isSelected ? 2 : 0}\n />\n );\n case \"turn\":\n return (\n <circle\n cx={cx}\n cy={cy}\n r={isSelected ? radius + 3 : radius}\n fill=\"none\"\n stroke={fill}\n strokeWidth={2.5}\n opacity={opacity}\n />\n );\n case \"turn-content\":\n return (\n <g>\n <circle\n cx={cx}\n cy={cy}\n r={isSelected ? radius + 3 : radius}\n fill=\"none\"\n stroke={fill}\n strokeWidth={2.5}\n opacity={opacity}\n />\n <circle\n cx={cx}\n cy={cy}\n r={Math.max(3, radius * 0.3)}\n fill={fill}\n opacity={opacity}\n />\n </g>\n );\n case \"memory\":\n const hw = radius * 0.85;\n const hh = radius * 0.85;\n return (\n <path\n d={diamondPath(hw, hh)}\n transform={`translate(${cx}, ${cy})`}\n fill={fill}\n opacity={opacity}\n stroke={strokeColor}\n strokeWidth={isSelected ? 2 : 0}\n />\n );\n }\n}\n","/**\n * memory-map-layout.ts — Force-directed layout engine for MemoryMapTab (D3).\n *\n * Uses Coulomb repulsion + Hooke attraction + center gravity to arrange nodes.\n * No external graph library. Mutates layout in place.\n * Self-contained types: only needs id + edges from graph data.\n */\n\n// ---------------------------------------------------------------------------\n// Types (self-contained — mirrors the subset used by the layout engine)\n// ---------------------------------------------------------------------------\n\ninterface GraphNodeMin {\n readonly id: string;\n readonly nodeType: string;\n readonly label: string;\n readonly summaryTruncated: string;\n readonly tokenEstimate: number;\n readonly timestamp: number;\n readonly dedupStatus: string | undefined;\n readonly raptorLevel: number;\n readonly topicSummary: string | undefined;\n readonly decisionCount: number;\n readonly textSnippet: string;\n readonly sessionId: string;\n}\n\ninterface GraphEdgeMin {\n readonly source: string;\n readonly target: string;\n readonly weight: number;\n readonly type: \"temporal\" | \"semantic\" | \"raptor_parent\";\n}\n\nexport interface Position {\n x: number;\n y: number;\n}\n\nexport interface LayoutNode extends GraphNodeMin {\n pos: Position;\n vx: number;\n vy: number;\n pinned: boolean;\n}\n\nexport interface LayoutEdge {\n source: number;\n target: number;\n weight: number;\n type: GraphEdgeMin[\"type\"];\n}\n\nexport interface Layout {\n nodes: LayoutNode[];\n edges: LayoutEdge[];\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst REPULSION = 5_000;\nconst ATTRACTION = 0.005;\nconst CENTER_GRAVITY = 0.01;\nconst DAMPING = 0.9;\nconst MIN_VELOCITY = 0.1;\nconst SPEED_LIMIT = 50;\n\n// ---------------------------------------------------------------------------\n// Build\n// ---------------------------------------------------------------------------\n\n/** Build initial layout from graph data. */\nexport function buildLayout(data: { nodes: GraphNodeMin[]; edges: GraphEdgeMin[] }): Layout {\n const nodes: LayoutNode[] = data.nodes.map((n, i) => {\n const angle = (2 * Math.PI * i) / Math.max(data.nodes.length, 1);\n const radius = 200;\n return {\n ...n,\n pos: { x: Math.cos(angle) * radius + 300, y: Math.sin(angle) * radius + 200 },\n vx: 0,\n vy: 0,\n pinned: false,\n };\n });\n\n const nodeIndex = new Map<string, number>();\n nodes.forEach((n, i) => nodeIndex.set(n.id, i));\n\n const edges: LayoutEdge[] = data.edges\n .map((e) => {\n const si = nodeIndex.get(e.source);\n const ti = nodeIndex.get(e.target);\n if (si === undefined || ti === undefined || si === ti) return null;\n return { source: si, target: ti, weight: e.weight, type: e.type };\n })\n .filter((e): e is LayoutEdge => e !== null);\n\n return { nodes, edges };\n}\n\n// ---------------------------------------------------------------------------\n// Apply forces\n// ---------------------------------------------------------------------------\n\n/** Apply one iteration of the force simulation. Mutates layout in place. */\nexport function applyForces(layout: Layout): void {\n const { nodes, edges } = layout;\n const n = nodes.length;\n if (n === 0) return;\n\n for (let i = 0; i < n; i++) {\n if (nodes[i].pinned) continue;\n let fx = 0;\n let fy = 0;\n\n // Coulomb repulsion\n for (let j = 0; j < n; j++) {\n if (i === j) continue;\n const dx = nodes[i].pos.x - nodes[j].pos.x;\n const dy = nodes[i].pos.y - nodes[j].pos.y;\n const distSq = dx * dx + dy * dy || 1;\n const force = REPULSION / distSq;\n const dist = Math.sqrt(distSq);\n fx += (dx / dist) * force;\n fy += (dy / dist) * force;\n }\n\n // Hooke attraction along edges\n for (const e of edges) {\n let other: number;\n if (e.source === i) other = e.target;\n else if (e.target === i) other = e.source;\n else continue;\n const dx = nodes[other].pos.x - nodes[i].pos.x;\n const dy = nodes[other].pos.y - nodes[i].pos.y;\n fx += dx * ATTRACTION * e.weight;\n fy += dy * ATTRACTION * e.weight;\n }\n\n // Center gravity\n fx -= nodes[i].pos.x * CENTER_GRAVITY;\n fy -= nodes[i].pos.y * CENTER_GRAVITY;\n\n nodes[i].vx = (nodes[i].vx + fx) * DAMPING;\n nodes[i].vy = (nodes[i].vy + fy) * DAMPING;\n\n const speed = Math.sqrt(nodes[i].vx * nodes[i].vx + nodes[i].vy * nodes[i].vy);\n if (speed > SPEED_LIMIT) {\n nodes[i].vx = (nodes[i].vx / speed) * SPEED_LIMIT;\n nodes[i].vy = (nodes[i].vy / speed) * SPEED_LIMIT;\n }\n\n if (speed > MIN_VELOCITY) {\n nodes[i].pos.x += nodes[i].vx;\n nodes[i].pos.y += nodes[i].vy;\n }\n }\n}\n","/**\n * MemoryMapTab/MemoryMapView.tsx — D3 memory map with force-directed graph.\n * Node shape encodes nodeType: checkpoint=filled circle, turn=hollow circle,\n * turn-content=hollow+ring, memory=diamond.\n * Fetches from /api/memory-map, renders SVG force layout.\n */\nimport type React from \"react\";\nimport { useEffect, useRef, useState, useCallback, useMemo } from \"react\";\nimport { renderNodeShape, NODE_COLORS, NODE_TYPE_LABELS } from \"../../memory-map-shapes.js\";\nimport type { NodeType } from \"../../memory-map-shapes.js\";\nimport { buildLayout, applyForces } from \"../../memory-map-layout.js\";\nimport type { LayoutNode, LayoutEdge } from \"../../memory-map-layout.js\";\n\n// Types (mirror of api-contracts/memory-map.ts — client-side only)\n\ninterface GraphNode {\n id: string;\n sessionId: string;\n label: string;\n summaryTruncated: string;\n tokenEstimate: number;\n timestamp: number;\n dedupStatus: string | undefined;\n raptorLevel: number;\n topicSummary: string | undefined;\n decisionCount: number;\n textSnippet: string;\n /** Source type discriminator for UI node-shape encoding. */\n nodeType: \"checkpoint\" | \"turn\" | \"turn-content\" | \"memory\";\n}\n\ninterface GraphEdge {\n source: string;\n target: string;\n weight: number;\n type: \"temporal\" | \"semantic\" | \"raptor_parent\";\n}\n\ninterface GraphValidationReport {\n readonly gatesRun: number;\n readonly gatesPassed: number;\n readonly dropped: { nodes: number; edges: number };\n readonly warnings: Array<{ gate: string; code: string; count: number }>;\n readonly sources: {\n checkpoint: number;\n turn: number;\n turnContent: number;\n memory: number;\n };\n readonly builtAt: number;\n}\n\ninterface GraphMetadata {\n totalNodes: number;\n totalEdges: number;\n avgWeight: number;\n nodeTypeBreakdown: Record<string, number>;\n edgeTypeBreakdown: Record<string, number>;\n}\n\ninterface MemoryMapResponse {\n nodes: GraphNode[];\n edges: GraphEdge[];\n metadata: GraphMetadata;\n /** Validation report from the 9-gate pipeline. Optional for backward compat. */\n validation?: GraphValidationReport;\n}\n\n// Simulation rendering constants (layout math is in memory-map-layout.ts)\n\nconst MAX_ITERATIONS = 300;\nconst EDGE_ALPHA = 0.3;\nconst SVG_WIDTH = 900;\nconst SVG_HEIGHT = 600;\nconst PADDING = 40;\n\n// Helpers\n\nfunction edgeColor(type: GraphEdge[\"type\"]): string {\n switch (type) {\n case \"temporal\":\n return \"#6366f1\"; // indigo\n case \"semantic\":\n return \"#22c55e\"; // green\n case \"raptor_parent\":\n return \"#f59e0b\"; // amber\n }\n}\n\n// Minimal legend swatch component\ninterface SwatchProps {\n type: \"node\" | \"edge\";\n color: string;\n shape: \"filled-circle\" | \"hollow-circle\" | \"hollow-ring\" | \"diamond\" | \"line\";\n label: string;\n}\nconst Swatch: React.FC<SwatchProps> = ({ color, shape, label }) => {\n const base: React.CSSProperties = {\n display: \"inline-block\",\n width: \"10px\",\n height: \"10px\",\n verticalAlign: \"middle\",\n marginRight: \"3px\",\n borderRadius: shape.startsWith(\"hollow\") || shape === \"filled-circle\" ? \"50%\" : undefined,\n };\n let swatch: JSX.Element;\n if (shape === \"line\") {\n return <span style={{ color, marginRight: \"6px\" }}>{label}</span>;\n } else if (shape === \"filled-circle\") {\n swatch = <span style={{ ...base, backgroundColor: color }} />;\n } else if (shape === \"hollow-circle\") {\n swatch = <span style={{ ...base, border: `2px solid ${color}`, backgroundColor: \"transparent\" }} />;\n } else if (shape === \"hollow-ring\") {\n swatch = (\n <span style={{ ...base, border: `2px solid ${color}`, backgroundColor: \"transparent\", position: \"relative\" }}>\n <span style={{ display: \"block\", width: \"4px\", height: \"4px\", borderRadius: \"50%\", backgroundColor: color, margin: \"2px auto\" }} />\n </span>\n );\n } else {\n swatch = <span style={{ ...base, clipPath: \"polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%)\", backgroundColor: color }} />;\n }\n return <><span className=\"memory-map-legend-item\">{swatch}{label}</span> </>;\n};\n\n// Force simulation engine (delegated to memory-map-layout.ts)\nconst MemoryMapView: React.FC = () => {\n const [data, setData] = useState<MemoryMapResponse | null>(null);\n const [loading, setLoading] = useState<boolean>(true);\n const [error, setError] = useState<string | null>(null);\n const [selectedNode, setSelectedNode] = useState<GraphNode | null>(null);\n const [searchQuery, setSearchQuery] = useState<string>(\"\");\n const [filterSession] = useState<string>(\"\");\n const [frame, setFrame] = useState<number>(0);\n\n const layoutRef = useRef<{ nodes: LayoutNode[]; edges: LayoutEdge[] } | null>(null);\n const animRef = useRef<number>(0);\n\n // Fetch graph data when filterSession changes\n useEffect(() => {\n let cancelled = false;\n const params = new URLSearchParams();\n if (filterSession) params.set(\"sessionId\", filterSession);\n params.set(\"threshold\", \"0.7\");\n params.set(\"maxEdgesPerNode\", \"4\");\n\n setLoading(true);\n setError(null);\n\n fetch(`/api/memory-map?${params.toString()}`)\n .then((r) => {\n if (!r.ok) throw new Error(`HTTP ${r.status}`);\n return r.json() as Promise<MemoryMapResponse>;\n })\n .then((d) => {\n if (!cancelled) {\n setData(d);\n layoutRef.current = buildLayout(d);\n setFrame(1);\n setLoading(false);\n }\n })\n .catch((e: unknown) => {\n if (!cancelled) {\n setError(e instanceof Error ? e.message : \"Unknown error\");\n setLoading(false);\n }\n });\n\n return () => {\n cancelled = true;\n cancelAnimationFrame(animRef.current);\n };\n }, [filterSession]);\n\n // Run force simulation via requestAnimationFrame\n useEffect(() => {\n if (!layoutRef.current || frame === 0) return;\n\n const layout = layoutRef.current;\n let iter = 0;\n\n const tick = () => {\n if (iter >= MAX_ITERATIONS) return;\n applyForces(layout);\n iter++;\n setFrame(iter);\n animRef.current = requestAnimationFrame(tick);\n };\n\n animRef.current = requestAnimationFrame(tick);\n return () => cancelAnimationFrame(animRef.current);\n }, [frame]);\n\n // Toggle pin / select a node\n const handleNodeClick = useCallback((node: LayoutNode, index: number) => {\n const layout = layoutRef.current;\n if (!layout) return;\n layout.nodes[index].pinned = !layout.nodes[index].pinned;\n if (!layout.nodes[index].pinned) {\n layout.nodes[index].vx = 0;\n layout.nodes[index].vy = 0;\n }\n setSelectedNode((prev) => (prev?.id === node.id ? null : (node as unknown as GraphNode)));\n setFrame((s) => s + 1);\n }, []);\n\n // Filtered node indices for search\n const filteredSet = useMemo<Set<number> | null>(() => {\n const layout = layoutRef.current;\n if (!layout || !searchQuery) return null;\n const q = searchQuery.toLowerCase();\n return new Set(\n layout.nodes\n .map((n, i) =>\n n.summaryTruncated.toLowerCase().includes(q) || n.label.toLowerCase().includes(q) ? i : -1,\n )\n .filter((i) => i >= 0),\n );\n }, [searchQuery]);\n\n // Health indicator helpers (D3)\n\n /**\n * Derive graph health from validation report:\n * green = all gates passed + no warnings\n * yellow = warnings present but no critical gate failed\n * red = a critical gate (gatesRun > gatesPassed) failed\n */\n const graphHealth = useMemo<{ level: \"green\" | \"yellow\" | \"red\"; label: string }>(() => {\n const v = data?.validation;\n if (!v) return { level: \"yellow\", label: \"No validation\" };\n if (v.gatesPassed < v.gatesRun) return { level: \"red\", label: \"Gate failure\" };\n if (v.warnings.length > 0) return { level: \"yellow\", label: `${v.warnings.length} warning(s)` };\n return { level: \"green\", label: \"Healthy\" };\n }, [data?.validation]);\n\n const healthColor: Record<string, string> = {\n green: \"#22c55e\",\n yellow: \"#eab308\",\n red: \"#ef4444\",\n };\n\n // Source availability indicators (D3)\n\n /** Count badge fragments from validation.sources. */\n const countBadge = useMemo<string>(() => {\n const v = data?.validation;\n if (!v) {\n const totalNodes = data?.metadata.totalNodes ?? 0;\n return `${totalNodes} nodes`;\n }\n const parts: string[] = [];\n if (v.sources.checkpoint > 0) parts.push(`${v.sources.checkpoint} checkpoints`);\n if (v.sources.turn > 0) parts.push(`${v.sources.turn} turns`);\n if (v.sources.turnContent > 0) parts.push(`${v.sources.turnContent} turn-content`);\n if (v.sources.memory > 0) parts.push(`${v.sources.memory} memories`);\n if (parts.length === 0) {\n parts.push(`${data?.metadata.totalNodes ?? 0} nodes`);\n }\n return parts.join(\" · \");\n }, [data?.validation, data?.metadata.totalNodes]);\n\n /** Per-source availability: ✓ for available sources, ✗ for empty ones. */\n const sourceAvail = useMemo<string>(() => {\n const v = data?.validation;\n if (!v) return \"\";\n const parts: string[] = [];\n parts.push(v.sources.checkpoint > 0 ? \"✓ checkpoints\" : \"✗ checkpoints\");\n parts.push(v.sources.turn > 0 ? \"✓ turns\" : \"✗ turns\");\n parts.push(v.sources.turnContent > 0 ? \"✓ turn-content\" : \"✗ turn-content\");\n parts.push(v.sources.memory > 0 ? \"✓ memories\" : \"✗ memories\");\n return parts.join(\" | \");\n }, [data?.validation]);\n\n /** Whether all four sources are empty (true empty state). */\n const allSourcesEmpty = useMemo<boolean>(() => {\n const v = data?.validation;\n if (!v) return data?.metadata.totalNodes === 0;\n return (\n v.sources.checkpoint === 0 &&\n v.sources.turn === 0 &&\n v.sources.turnContent === 0 &&\n v.sources.memory === 0\n );\n }, [data?.validation, data?.metadata.totalNodes]);\n\n // Loading state\n\n if (loading) {\n return (\n <div className=\"rounded-lg border border-border bg-bg-card p-6 text-center text-sm text-muted-foreground\">\n Loading memory graph...\n </div>\n );\n }\n\n // Error state\n\n if (error) {\n return (\n <div className=\"rounded-lg border border-border bg-bg-card p-6 text-center text-sm\">\n <p className=\"text-red-400\">Failed to load memory map: {error}</p>\n <button\n className=\"mt-3 rounded-md border border-border px-3 py-1.5 text-sm transition-colors hover:bg-bg-elevated hover:text-foreground\"\n onClick={() => setFrame((s) => s + 1)}\n >\n Retry\n </button>\n </div>\n );\n }\n\n // Empty state (D2)\n\n if (!data || !layoutRef.current || allSourcesEmpty) {\n return (\n <div className=\"rounded-lg border border-border bg-bg-card p-6 text-sm text-muted-foreground\">\n <p>Memories appear after your first compaction. The graph shows checkpoints (compaction summaries) linked by semantic similarity and time. Run a longer session or lower the compaction tier to see it sooner.</p>\n </div>\n );\n }\n\n const layout = layoutRef.current;\n\n // Render\n\n return (\n <div className=\"flex flex-col gap-3\">\n {/* Toolbar */}\n <div className=\"flex flex-wrap items-center gap-3\">\n <input\n type=\"text\"\n placeholder=\"Search memories...\"\n value={searchQuery}\n onInput={(e: React.FormEvent<HTMLInputElement>) =>\n setSearchQuery((e.target as HTMLInputElement).value)\n }\n className=\"w-56 rounded-md border border-border bg-bg-elevated/50 px-3 py-2 text-sm outline-none transition-colors focus:border-primary\"\n />\n <span className=\"text-xs text-muted-foreground\">\n <span>{countBadge}</span>\n {\" · \"}\n <span>{data.edges.length} edges</span>\n </span>\n {/* Graph-health indicator */}\n <span\n className=\"ml-auto rounded-full px-2 py-1 text-[11px] font-semibold text-white\"\n style={{ backgroundColor: healthColor[graphHealth.level] ?? \"#6b7280\" }}\n title={`Validation: ${graphHealth.label}`}\n >\n {graphHealth.level === \"green\" ? \"Healthy\" : graphHealth.level === \"yellow\" ? \"Warnings\" : \"Critical\"}\n </span>\n </div>\n\n {/* Source availability indicators */}\n {sourceAvail ? (\n <div className=\"text-[11px] text-muted-foreground\">{sourceAvail}</div>\n ) : null}\n\n {/* Legend — node types + edge types */}\n <div className=\"flex flex-wrap items-center gap-x-4 gap-y-1 rounded-lg border border-border/60 bg-bg-card px-3 py-2 text-xs\">\n <span className=\"font-semibold text-muted-foreground\">Nodes:</span>\n <Swatch type=\"node\" color={NODE_COLORS.checkpoint} shape=\"filled-circle\" label=\"Checkpoint\" />\n <Swatch type=\"node\" color={NODE_COLORS.turn} shape=\"hollow-circle\" label=\"Turn\" />\n <Swatch type=\"node\" color={NODE_COLORS[\"turn-content\"]} shape=\"hollow-ring\" label=\"Turn Content\" />\n <Swatch type=\"node\" color={NODE_COLORS.memory} shape=\"diamond\" label=\"Memory\" />\n <span className=\"font-semibold text-muted-foreground\">Edges:</span>\n <Swatch type=\"edge\" color={edgeColor(\"semantic\")} shape=\"line\" label=\"Semantic\" />\n <Swatch type=\"edge\" color={edgeColor(\"temporal\")} shape=\"line\" label=\"Temporal\" />\n <Swatch type=\"edge\" color={edgeColor(\"raptor_parent\")} shape=\"line\" label=\"Raptor\" />\n </div>\n\n {/* SVG graph */}\n <svg\n width={SVG_WIDTH}\n height={SVG_HEIGHT}\n viewBox={`0 0 ${SVG_WIDTH} ${SVG_HEIGHT}`}\n className=\"memory-map-svg\"\n >\n {/* Edges */}\n {layout.edges.map((e, i) => {\n const src = layout.nodes[e.source];\n const tgt = layout.nodes[e.target];\n const color = edgeColor(e.type);\n const strokeW = Math.max(1, e.weight * 2.5);\n return (\n <line\n key={`edge-${i}`}\n x1={PADDING + (src.pos.x / (layout.nodes.length || 1)) * (SVG_WIDTH - 2 * PADDING)}\n y1={PADDING + (src.pos.y / (layout.nodes.length || 1)) * (SVG_HEIGHT - 2 * PADDING)}\n x2={PADDING + (tgt.pos.x / (layout.nodes.length || 1)) * (SVG_WIDTH - 2 * PADDING)}\n y2={PADDING + (tgt.pos.y / (layout.nodes.length || 1)) * (SVG_HEIGHT - 2 * PADDING)}\n stroke={color}\n strokeWidth={strokeW}\n opacity={EDGE_ALPHA}\n />\n );\n })}\n\n {/* Nodes — shape encodes nodeType */}\n {layout.nodes.map((n, i) => {\n const cx =\n PADDING + (n.pos.x / (layout.nodes.length || 1)) * (SVG_WIDTH - 2 * PADDING);\n const cy =\n PADDING + (n.pos.y / (layout.nodes.length || 1)) * (SVG_HEIGHT - 2 * PADDING);\n const radius = Math.min(20, 8 + n.tokenEstimate / 500);\n const isFiltered = filteredSet ? filteredSet.has(i) : true;\n const isSelected = selectedNode?.id === n.id;\n const nodeLabel = n.label.length > 20 ? n.label.slice(0, 18) + \"...\" : n.label;\n\n return (\n <g\n key={`node-${i}`}\n className=\"memory-map-node-group\"\n onClick={() => handleNodeClick(n, i)}\n style={{ cursor: \"pointer\" }}\n >\n {renderNodeShape(cx, cy, radius, n.nodeType as NodeType, isSelected, isFiltered, n.dedupStatus)}\n <text\n x={cx}\n y={cy + radius + 12}\n textAnchor=\"middle\"\n fontSize=\"9px\"\n fill=\"#374151\"\n className=\"memory-map-label\"\n >\n {nodeLabel}\n </text>\n </g>\n );\n })}\n </svg>\n\n {/* Node detail panel */}\n {selectedNode ? (\n <div className=\"rounded-lg border border-border/60 bg-bg-card p-4 text-sm\">\n <h3 className=\"font-heading text-base font-semibold\">\n <span className=\"mr-1.5 text-xs font-normal text-muted-foreground\">\n {NODE_TYPE_LABELS[selectedNode.nodeType]}\n </span>\n {selectedNode.label}\n </h3>\n <p className=\"mt-1\">{selectedNode.summaryTruncated}</p>\n {selectedNode.topicSummary ? (\n <p className=\"mt-1\">Topic: {selectedNode.topicSummary}</p>\n ) : null}\n <p className=\"mt-1\">\n Tokens: {selectedNode.tokenEstimate} | Decisions: {selectedNode.decisionCount}\n </p>\n <p>Session: {selectedNode.sessionId}</p>\n <p>Raptor Level: {selectedNode.raptorLevel}</p>\n <p className=\"mt-1 text-muted-foreground\">{selectedNode.textSnippet}</p>\n </div>\n ) : null}\n </div>\n );\n};\n\nexport default MemoryMapView;\n","/**\n * MemoryMapTab/RaptorTreeView.tsx — RAPTOR tree sub-tab (Part B).\n *\n * Fetches the hierarchical RAPTOR tree from /api/raptor-tree (defaults to the\n * most recent session with nodes) and renders it as level-indented summary\n * cards. No D3 needed — CSS indentation encodes hierarchy.\n */\nimport type React from \"react\";\nimport { useEffect, useState } from \"react\";\nimport { fetchRaptorTree, fetchRaptorBuildHistory } from \"../../api/client\";\nimport type {\n\tRaptorTreeResponse,\n\tRaptorNodeDTO,\n\tRaptorBuildHistoryResponse,\n} from \"@contracts\";\n\n/** Per-level border color for node cards. */\nfunction levelColor(level: number): string {\n\tif (level === 0) return \"#d4a017\"; // gold — root\n\tif (level === 1) return \"#3b82f6\"; // blue\n\treturn \"#14b8a6\"; // teal — level 2+\n}\n\nfunction formatDate(ts: number): string {\n\tif (!ts) return \"—\";\n\treturn new Date(ts).toLocaleString();\n}\n\nfunction NodeCard({ node }: { node: RaptorNodeDTO }): React.ReactElement {\n\tconst border = levelColor(node.level);\n\tconst childrenLabel =\n\t\tnode.children.length > 0\n\t\t\t? `${node.children.length} child${node.children.length === 1 ? \"\" : \"ren\"}`\n\t\t\t: \"leaf\";\n\treturn (\n\t\t<div\n\t\t\tstyle={{\n\t\t\t\tbackground: \"#14142b\",\n\t\t\t\tborder: `1px solid ${border}`,\n\t\t\t\tborderRadius: \"8px\",\n\t\t\t\tpadding: \"0.75rem 1rem\",\n\t\t\t\tmarginBottom: \"0.6rem\",\n\t\t\t\tmarginLeft: node.level * 24,\n\t\t\t\tmaxWidth: \"90%\",\n\t\t\t}}\n\t\t>\n\t\t\t<div style={{ display: \"flex\", gap: \"0.75rem\", alignItems: \"center\", marginBottom: \"0.35rem\" }}>\n\t\t\t\t<span\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tdisplay: \"inline-block\",\n\t\t\t\t\t\tbackground: border,\n\t\t\t\t\t\tcolor: \"#fff\",\n\t\t\t\t\t\tborderRadius: \"10px\",\n\t\t\t\t\t\tpadding: \"1px 8px\",\n\t\t\t\t\t\tfontSize: \"11px\",\n\t\t\t\t\t\tfontWeight: 600,\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\tL{node.level}\n\t\t\t\t</span>\n\t\t\t\t<span style={{ fontSize: \"12px\", color: \"#6b7280\" }}>\n\t\t\t\t\t{childrenLabel} · {node.tokenEstimate} tok · {node.qualityMarker}\n\t\t\t\t</span>\n\t\t\t\t<span style={{ fontSize: \"12px\", color: \"#6b7280\", marginLeft: \"auto\" }}>\n\t\t\t\t\t{formatDate(node.builtAt)}\n\t\t\t\t</span>\n\t\t\t</div>\n\t\t\t<div style={{ fontSize: \"0.92rem\", color: \"#e5e7eb\" }}>{node.summary}</div>\n\t\t</div>\n\t);\n}\n\nexport default function RaptorTreeView(): React.ReactElement {\n\tconst [data, setData] = useState<RaptorTreeResponse | null>(null);\n\tconst [history, setHistory] = useState<RaptorBuildHistoryResponse | null>(null);\n\tconst [loading, setLoading] = useState<boolean>(true);\n\tconst [error, setError] = useState<string | null>(null);\n\n\tuseEffect(() => {\n\t\tlet cancelled = false;\n\t\tsetLoading(true);\n\t\tsetError(null);\n\t\tPromise.all([fetchRaptorTree(), fetchRaptorBuildHistory()])\n\t\t\t.then(([d, h]) => {\n\t\t\t\tif (!cancelled) {\n\t\t\t\t\tsetData(d);\n\t\t\t\t\tsetHistory(h);\n\t\t\t\t\tsetLoading(false);\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch((e: unknown) => {\n\t\t\t\tif (!cancelled) {\n\t\t\t\t\tsetError(e instanceof Error ? e.message : \"Unknown error\");\n\t\t\t\t\tsetLoading(false);\n\t\t\t\t}\n\t\t\t});\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, []);\n\n\tif (loading) {\n\t\treturn (\n\t\t\t<div className=\"rounded-lg border border-border bg-bg-card p-6 text-center text-sm text-muted-foreground\">\n\t\t\t\tLoading RAPTOR tree...\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (error) {\n\t\treturn (\n\t\t\t<div className=\"rounded-lg border border-dashed border-border bg-bg-card p-8 text-center text-sm\">\n\t\t\t\t<p className=\"text-red-400\">Failed to load RAPTOR tree: {error}</p>\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (!data || data.empty || data.nodes.length === 0) {\n\t\treturn (\n\t\t\t<div className=\"rounded-lg border border-dashed border-border bg-bg-card p-8 text-center text-sm text-muted-foreground\">\n\t\t\t\t<p>\n\t\t\t\t\tNo RAPTOR tree built yet — run a compaction (the tree builds during\n\t\t\t\t\tcompaction).\n\t\t\t\t</p>\n\t\t\t</div>\n\t\t);\n\t}\n\n\tconst latestBuild = history && !history.empty ? history.builds[0] : null;\n\tconst coherencePct = latestBuild?.coherenceScore != null\n\t\t? Math.round(latestBuild.coherenceScore * 100)\n\t\t: null;\n\n\treturn (\n\t\t<div className=\"w-full p-4\">\n\t\t\t<div className=\"mb-4 flex items-center gap-6 text-sm text-muted-foreground\">\n\t\t\t\t<span>\n\t\t\t\t\t<strong>{data.nodes.length}</strong> nodes\n\t\t\t\t</span>\n\t\t\t\t<span>\n\t\t\t\t\t<strong>{data.levels + 1}</strong> levels\n\t\t\t\t</span>\n\t\t\t\t<span>Built {formatDate(data.builtAt ?? 0)}</span>\n\t\t\t\t{latestBuild && (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\tCoherence:{\" \"}\n\t\t\t\t\t\t\t<strong style={{ color: coherencePct != null && coherencePct >= 70 ? \"#22c55e\" : \"#f59e0b\" }}>\n\t\t\t\t\t\t\t\t{coherencePct != null ? `${coherencePct}%` : \"—\"}\n\t\t\t\t\t\t\t</strong>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\tLeaves: <strong>{latestBuild.leafCount}</strong>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\tDepth: <strong>{latestBuild.depth}</strong>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t\t{latestBuild.timedOut && (\n\t\t\t\t\t\t\t<span style={{ color: \"#ef4444\" }}>budget timeout</span>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t\t{history && !history.empty && history.builds.length > 1 && (\n\t\t\t\t<details className=\"mb-4\">\n\t\t\t\t\t<summary className=\"cursor-pointer text-xs text-muted-foreground\">\n\t\t\t\t\t\tBuild history ({history.builds.length} builds)\n\t\t\t\t\t</summary>\n\t\t\t\t\t<div className=\"mt-2 space-y-1\">\n\t\t\t\t\t\t{history.builds.slice(0, 10).map((b) => (\n\t\t\t\t\t\t\t<div key={b.buildId} className=\"flex items-center gap-4 text-xs text-muted-foreground\">\n\t\t\t\t\t\t\t\t<span>{formatDate(b.completedAt)}</span>\n\t\t\t\t\t\t\t\t<span>{b.nodeCount} nodes</span>\n\t\t\t\t\t\t\t\t<span>{b.leafCount} leaves</span>\n\t\t\t\t\t\t\t\t<span>depth {b.depth}</span>\n\t\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t\tcoherence{\" \"}\n\t\t\t\t\t\t\t\t\t{b.coherenceScore != null\n\t\t\t\t\t\t\t\t\t\t? `${Math.round(b.coherenceScore * 100)}%`\n\t\t\t\t\t\t\t\t\t\t: \"—\"}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t{b.timedOut && <span style={{ color: \"#ef4444\" }}>timeout</span>}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</div>\n\t\t\t\t</details>\n\t\t\t)}\n\t\t\t{data.nodes.map((node) => (\n\t\t\t\t<NodeCard key={node.id} node={node} />\n\t\t\t))}\n\t\t</div>\n\t);\n}\n","/**\n * MemoryMapTab.tsx — Sub-tab shell under Memory Map (Part B).\n *\n * Hosts two sub-tabs: the D3 force-directed Memory Map (MemoryMapView) and\n * the hierarchical RAPTOR tree (RaptorTreeView). The heavy rendering logic\n * lives in ./MemoryMapTab/* to keep every file under the extensions limit.\n */\nimport type React from \"react\";\nimport { useState } from \"react\";\nimport MemoryMapView from \"./MemoryMapTab/MemoryMapView.js\";\nimport RaptorTreeView from \"./MemoryMapTab/RaptorTreeView.js\";\nimport { Toggle } from \"../components/ui/toggle\";\n\ntype MemoryMapSubTab = \"map\" | \"raptor\";\n\nconst MemoryMapTab: React.FC = () => {\n\tconst [subTab, setSubTab] = useState<MemoryMapSubTab>(\"map\");\n\n\treturn (\n\t\t<div className=\"flex flex-col gap-4\">\n\t\t\t<nav\n\t\t\t\tclassName=\"flex gap-2 border-b border-border pb-2 pt-2\"\n\t\t\t\taria-label=\"Memory map sections\"\n\t\t\t>\n\t\t\t\t<Toggle\n\t\t\t\t\tpressed={subTab === \"map\"}\n\t\t\t\t\tonClick={() => setSubTab(\"map\")}\n\t\t\t\t\taria-label=\"Memory Map view\"\n\t\t\t\t>\n\t\t\t\t\tMemory Map\n\t\t\t\t</Toggle>\n\t\t\t\t<Toggle\n\t\t\t\t\tpressed={subTab === \"raptor\"}\n\t\t\t\t\tonClick={() => setSubTab(\"raptor\")}\n\t\t\t\t\taria-label=\"RAPTOR Tree view\"\n\t\t\t\t>\n\t\t\t\t\tRAPTOR Tree\n\t\t\t\t</Toggle>\n\t\t\t</nav>\n\t\t\t{subTab === \"map\" && <MemoryMapView />}\n\t\t\t{subTab === \"raptor\" && <RaptorTreeView />}\n\t\t</div>\n\t);\n};\n\nexport default MemoryMapTab;\n"],"names":["NODE_COLORS","NODE_TYPE_LABELS","diamondPath","hw","hh","nodeOpacity","dedupStatus","renderNodeShape","cx","cy","radius","nodeType","isSelected","isFiltered","fill","strokeColor","opacity","jsx","REPULSION","ATTRACTION","CENTER_GRAVITY","DAMPING","MIN_VELOCITY","SPEED_LIMIT","buildLayout","data","nodes","i","angle","nodeIndex","edges","e","si","ti","applyForces","layout","n","fx","fy","j","dx","dy","distSq","force","dist","other","speed","MAX_ITERATIONS","EDGE_ALPHA","SVG_WIDTH","SVG_HEIGHT","PADDING","edgeColor","type","Swatch","color","shape","label","base","swatch","jsxs","Fragment","MemoryMapView","setData","useState","loading","setLoading","error","setError","selectedNode","setSelectedNode","searchQuery","setSearchQuery","filterSession","frame","setFrame","layoutRef","useRef","animRef","useEffect","cancelled","params","r","d","iter","tick","handleNodeClick","useCallback","node","index","prev","s","filteredSet","useMemo","q","graphHealth","v","healthColor","countBadge","parts","sourceAvail","allSourcesEmpty","src","tgt","strokeW","nodeLabel","levelColor","level","formatDate","ts","NodeCard","border","childrenLabel","RaptorTreeView","history","setHistory","fetchRaptorTree","fetchRaptorBuildHistory","h","latestBuild","coherencePct","b","MemoryMapTab","subTab","setSubTab","Toggle"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MemoryMapTab-Oq-iqvUq.js","sources":["../../src/memory-map-shapes.tsx","../../src/memory-map-layout.ts","../../src/tabs/MemoryMapTab/MemoryMapView.tsx","../../src/tabs/MemoryMapTab/RaptorTreeView.tsx","../../src/tabs/MemoryMapTab.tsx"],"sourcesContent":["/**\n * memory-map-shapes.tsx — Node shape rendering utilities for MemoryMapTab (D3).\n *\n * Node shape encodes nodeType: checkpoint = filled circle, turn = hollow circle,\n * turn-content = hollow+ring, memory = diamond.\n * Delegate-shell pattern: thin rendering helpers, no state, no side effects.\n */\nimport type React from \"react\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type NodeType = \"checkpoint\" | \"turn\" | \"turn-content\" | \"memory\";\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nexport const NODE_COLORS: Record<NodeType, string> = {\n checkpoint: \"#6366f1\",\n turn: \"#58a6ff\",\n \"turn-content\": \"#22c55e\",\n memory: \"#f59e0b\",\n};\n\nexport const NODE_TYPE_LABELS: Record<NodeType, string> = {\n checkpoint: \"Checkpoint\",\n turn: \"Turn\",\n \"turn-content\": \"Turn Content\",\n memory: \"Memory\",\n};\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** SVG path for a diamond centered at (0,0) with given half-width/height. */\nfunction diamondPath(hw: number, hh: number): string {\n return `M 0,-${hh} L ${hw},0 L 0,${hh} L -${hw},0 Z`;\n}\n\nfunction nodeOpacity(dedupStatus: string | undefined): number {\n if (!dedupStatus || dedupStatus === \"active\") return 1;\n return 0.5;\n}\n\n// ---------------------------------------------------------------------------\n// Render function\n// ---------------------------------------------------------------------------\n\n/** Render an SVG shape for a node based on its nodeType. */\nexport function renderNodeShape(\n cx: number,\n cy: number,\n radius: number,\n nodeType: NodeType,\n isSelected: boolean,\n isFiltered: boolean,\n dedupStatus: string | undefined,\n): React.ReactElement {\n const fill = isFiltered ? NODE_COLORS[nodeType] ?? \"#6366f1\" : \"#d1d5db\";\n const strokeColor = isSelected ? \"#ef4444\" : \"none\";\n const opacity = nodeOpacity(dedupStatus);\n\n switch (nodeType) {\n case \"checkpoint\":\n return (\n <circle\n cx={cx}\n cy={cy}\n r={isSelected ? radius + 3 : radius}\n fill={fill}\n opacity={opacity}\n stroke={strokeColor}\n strokeWidth={isSelected ? 2 : 0}\n />\n );\n case \"turn\":\n return (\n <circle\n cx={cx}\n cy={cy}\n r={isSelected ? radius + 3 : radius}\n fill=\"none\"\n stroke={fill}\n strokeWidth={2.5}\n opacity={opacity}\n />\n );\n case \"turn-content\":\n return (\n <g>\n <circle\n cx={cx}\n cy={cy}\n r={isSelected ? radius + 3 : radius}\n fill=\"none\"\n stroke={fill}\n strokeWidth={2.5}\n opacity={opacity}\n />\n <circle\n cx={cx}\n cy={cy}\n r={Math.max(3, radius * 0.3)}\n fill={fill}\n opacity={opacity}\n />\n </g>\n );\n case \"memory\":\n const hw = radius * 0.85;\n const hh = radius * 0.85;\n return (\n <path\n d={diamondPath(hw, hh)}\n transform={`translate(${cx}, ${cy})`}\n fill={fill}\n opacity={opacity}\n stroke={strokeColor}\n strokeWidth={isSelected ? 2 : 0}\n />\n );\n }\n}\n","/**\n * memory-map-layout.ts — Force-directed layout engine for MemoryMapTab (D3).\n *\n * Uses Coulomb repulsion + Hooke attraction + center gravity to arrange nodes.\n * No external graph library. Mutates layout in place.\n * Self-contained types: only needs id + edges from graph data.\n */\n\n// ---------------------------------------------------------------------------\n// Types (self-contained — mirrors the subset used by the layout engine)\n// ---------------------------------------------------------------------------\n\ninterface GraphNodeMin {\n readonly id: string;\n readonly nodeType: string;\n readonly label: string;\n readonly summaryTruncated: string;\n readonly tokenEstimate: number;\n readonly timestamp: number;\n readonly dedupStatus: string | undefined;\n readonly raptorLevel: number;\n readonly topicSummary: string | undefined;\n readonly decisionCount: number;\n readonly textSnippet: string;\n readonly sessionId: string;\n}\n\ninterface GraphEdgeMin {\n readonly source: string;\n readonly target: string;\n readonly weight: number;\n readonly type: \"temporal\" | \"semantic\" | \"raptor_parent\";\n}\n\nexport interface Position {\n x: number;\n y: number;\n}\n\nexport interface LayoutNode extends GraphNodeMin {\n pos: Position;\n vx: number;\n vy: number;\n pinned: boolean;\n}\n\nexport interface LayoutEdge {\n source: number;\n target: number;\n weight: number;\n type: GraphEdgeMin[\"type\"];\n}\n\nexport interface Layout {\n nodes: LayoutNode[];\n edges: LayoutEdge[];\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst REPULSION = 5_000;\nconst ATTRACTION = 0.005;\nconst CENTER_GRAVITY = 0.01;\nconst DAMPING = 0.9;\nconst MIN_VELOCITY = 0.1;\nconst SPEED_LIMIT = 50;\n\n// ---------------------------------------------------------------------------\n// Build\n// ---------------------------------------------------------------------------\n\n/** Build initial layout from graph data. */\nexport function buildLayout(data: { nodes: GraphNodeMin[]; edges: GraphEdgeMin[] }): Layout {\n const nodes: LayoutNode[] = data.nodes.map((n, i) => {\n const angle = (2 * Math.PI * i) / Math.max(data.nodes.length, 1);\n const radius = 200;\n return {\n ...n,\n pos: { x: Math.cos(angle) * radius + 300, y: Math.sin(angle) * radius + 200 },\n vx: 0,\n vy: 0,\n pinned: false,\n };\n });\n\n const nodeIndex = new Map<string, number>();\n nodes.forEach((n, i) => nodeIndex.set(n.id, i));\n\n const edges: LayoutEdge[] = data.edges\n .map((e) => {\n const si = nodeIndex.get(e.source);\n const ti = nodeIndex.get(e.target);\n if (si === undefined || ti === undefined || si === ti) return null;\n return { source: si, target: ti, weight: e.weight, type: e.type };\n })\n .filter((e): e is LayoutEdge => e !== null);\n\n return { nodes, edges };\n}\n\n// ---------------------------------------------------------------------------\n// Apply forces\n// ---------------------------------------------------------------------------\n\n/** Apply one iteration of the force simulation. Mutates layout in place. */\nexport function applyForces(layout: Layout): void {\n const { nodes, edges } = layout;\n const n = nodes.length;\n if (n === 0) return;\n\n for (let i = 0; i < n; i++) {\n if (nodes[i].pinned) continue;\n let fx = 0;\n let fy = 0;\n\n // Coulomb repulsion\n for (let j = 0; j < n; j++) {\n if (i === j) continue;\n const dx = nodes[i].pos.x - nodes[j].pos.x;\n const dy = nodes[i].pos.y - nodes[j].pos.y;\n const distSq = dx * dx + dy * dy || 1;\n const force = REPULSION / distSq;\n const dist = Math.sqrt(distSq);\n fx += (dx / dist) * force;\n fy += (dy / dist) * force;\n }\n\n // Hooke attraction along edges\n for (const e of edges) {\n let other: number;\n if (e.source === i) other = e.target;\n else if (e.target === i) other = e.source;\n else continue;\n const dx = nodes[other].pos.x - nodes[i].pos.x;\n const dy = nodes[other].pos.y - nodes[i].pos.y;\n fx += dx * ATTRACTION * e.weight;\n fy += dy * ATTRACTION * e.weight;\n }\n\n // Center gravity\n fx -= nodes[i].pos.x * CENTER_GRAVITY;\n fy -= nodes[i].pos.y * CENTER_GRAVITY;\n\n nodes[i].vx = (nodes[i].vx + fx) * DAMPING;\n nodes[i].vy = (nodes[i].vy + fy) * DAMPING;\n\n const speed = Math.sqrt(nodes[i].vx * nodes[i].vx + nodes[i].vy * nodes[i].vy);\n if (speed > SPEED_LIMIT) {\n nodes[i].vx = (nodes[i].vx / speed) * SPEED_LIMIT;\n nodes[i].vy = (nodes[i].vy / speed) * SPEED_LIMIT;\n }\n\n if (speed > MIN_VELOCITY) {\n nodes[i].pos.x += nodes[i].vx;\n nodes[i].pos.y += nodes[i].vy;\n }\n }\n}\n","/**\n * MemoryMapTab/MemoryMapView.tsx — D3 memory map with force-directed graph.\n * Node shape encodes nodeType: checkpoint=filled circle, turn=hollow circle,\n * turn-content=hollow+ring, memory=diamond.\n * Fetches from /api/memory-map, renders SVG force layout.\n */\nimport type React from \"react\";\nimport { useEffect, useRef, useState, useCallback, useMemo } from \"react\";\nimport { renderNodeShape, NODE_COLORS, NODE_TYPE_LABELS } from \"../../memory-map-shapes.js\";\nimport type { NodeType } from \"../../memory-map-shapes.js\";\nimport { buildLayout, applyForces } from \"../../memory-map-layout.js\";\nimport type { LayoutNode, LayoutEdge } from \"../../memory-map-layout.js\";\n\n// Types (mirror of api-contracts/memory-map.ts — client-side only)\n\ninterface GraphNode {\n id: string;\n sessionId: string;\n label: string;\n summaryTruncated: string;\n tokenEstimate: number;\n timestamp: number;\n dedupStatus: string | undefined;\n raptorLevel: number;\n topicSummary: string | undefined;\n decisionCount: number;\n textSnippet: string;\n /** Source type discriminator for UI node-shape encoding. */\n nodeType: \"checkpoint\" | \"turn\" | \"turn-content\" | \"memory\";\n}\n\ninterface GraphEdge {\n source: string;\n target: string;\n weight: number;\n type: \"temporal\" | \"semantic\" | \"raptor_parent\";\n}\n\ninterface GraphValidationReport {\n readonly gatesRun: number;\n readonly gatesPassed: number;\n readonly dropped: { nodes: number; edges: number };\n readonly warnings: Array<{ gate: string; code: string; count: number }>;\n readonly sources: {\n checkpoint: number;\n turn: number;\n turnContent: number;\n memory: number;\n };\n readonly builtAt: number;\n}\n\ninterface GraphMetadata {\n totalNodes: number;\n totalEdges: number;\n avgWeight: number;\n nodeTypeBreakdown: Record<string, number>;\n edgeTypeBreakdown: Record<string, number>;\n}\n\ninterface MemoryMapResponse {\n nodes: GraphNode[];\n edges: GraphEdge[];\n metadata: GraphMetadata;\n /** Validation report from the 9-gate pipeline. Optional for backward compat. */\n validation?: GraphValidationReport;\n}\n\n// Simulation rendering constants (layout math is in memory-map-layout.ts)\n\nconst MAX_ITERATIONS = 300;\nconst EDGE_ALPHA = 0.3;\nconst SVG_WIDTH = 900;\nconst SVG_HEIGHT = 600;\nconst PADDING = 40;\n\n// Helpers\n\nfunction edgeColor(type: GraphEdge[\"type\"]): string {\n switch (type) {\n case \"temporal\":\n return \"#6366f1\"; // indigo\n case \"semantic\":\n return \"#22c55e\"; // green\n case \"raptor_parent\":\n return \"#f59e0b\"; // amber\n }\n}\n\n// Minimal legend swatch component\ninterface SwatchProps {\n type: \"node\" | \"edge\";\n color: string;\n shape: \"filled-circle\" | \"hollow-circle\" | \"hollow-ring\" | \"diamond\" | \"line\";\n label: string;\n}\nconst Swatch: React.FC<SwatchProps> = ({ color, shape, label }) => {\n const base: React.CSSProperties = {\n display: \"inline-block\",\n width: \"10px\",\n height: \"10px\",\n verticalAlign: \"middle\",\n marginRight: \"3px\",\n borderRadius: shape.startsWith(\"hollow\") || shape === \"filled-circle\" ? \"50%\" : undefined,\n };\n let swatch: JSX.Element;\n if (shape === \"line\") {\n return <span style={{ color, marginRight: \"6px\" }}>{label}</span>;\n } else if (shape === \"filled-circle\") {\n swatch = <span style={{ ...base, backgroundColor: color }} />;\n } else if (shape === \"hollow-circle\") {\n swatch = <span style={{ ...base, border: `2px solid ${color}`, backgroundColor: \"transparent\" }} />;\n } else if (shape === \"hollow-ring\") {\n swatch = (\n <span style={{ ...base, border: `2px solid ${color}`, backgroundColor: \"transparent\", position: \"relative\" }}>\n <span style={{ display: \"block\", width: \"4px\", height: \"4px\", borderRadius: \"50%\", backgroundColor: color, margin: \"2px auto\" }} />\n </span>\n );\n } else {\n swatch = <span style={{ ...base, clipPath: \"polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%)\", backgroundColor: color }} />;\n }\n return <><span className=\"memory-map-legend-item\">{swatch}{label}</span> </>;\n};\n\n// Force simulation engine (delegated to memory-map-layout.ts)\nconst MemoryMapView: React.FC = () => {\n const [data, setData] = useState<MemoryMapResponse | null>(null);\n const [loading, setLoading] = useState<boolean>(true);\n const [error, setError] = useState<string | null>(null);\n const [selectedNode, setSelectedNode] = useState<GraphNode | null>(null);\n const [searchQuery, setSearchQuery] = useState<string>(\"\");\n const [filterSession] = useState<string>(\"\");\n const [frame, setFrame] = useState<number>(0);\n\n const layoutRef = useRef<{ nodes: LayoutNode[]; edges: LayoutEdge[] } | null>(null);\n const animRef = useRef<number>(0);\n\n // Fetch graph data when filterSession changes\n useEffect(() => {\n let cancelled = false;\n const params = new URLSearchParams();\n if (filterSession) params.set(\"sessionId\", filterSession);\n params.set(\"threshold\", \"0.7\");\n params.set(\"maxEdgesPerNode\", \"4\");\n\n setLoading(true);\n setError(null);\n\n fetch(`/api/memory-map?${params.toString()}`)\n .then((r) => {\n if (!r.ok) throw new Error(`HTTP ${r.status}`);\n return r.json() as Promise<MemoryMapResponse>;\n })\n .then((d) => {\n if (!cancelled) {\n setData(d);\n layoutRef.current = buildLayout(d);\n setFrame(1);\n setLoading(false);\n }\n })\n .catch((e: unknown) => {\n if (!cancelled) {\n setError(e instanceof Error ? e.message : \"Unknown error\");\n setLoading(false);\n }\n });\n\n return () => {\n cancelled = true;\n cancelAnimationFrame(animRef.current);\n };\n }, [filterSession]);\n\n // Run force simulation via requestAnimationFrame\n useEffect(() => {\n if (!layoutRef.current || frame === 0) return;\n\n const layout = layoutRef.current;\n let iter = 0;\n\n const tick = () => {\n if (iter >= MAX_ITERATIONS) return;\n applyForces(layout);\n iter++;\n setFrame(iter);\n animRef.current = requestAnimationFrame(tick);\n };\n\n animRef.current = requestAnimationFrame(tick);\n return () => cancelAnimationFrame(animRef.current);\n }, [frame]);\n\n // Toggle pin / select a node\n const handleNodeClick = useCallback((node: LayoutNode, index: number) => {\n const layout = layoutRef.current;\n if (!layout) return;\n layout.nodes[index].pinned = !layout.nodes[index].pinned;\n if (!layout.nodes[index].pinned) {\n layout.nodes[index].vx = 0;\n layout.nodes[index].vy = 0;\n }\n setSelectedNode((prev) => (prev?.id === node.id ? null : (node as unknown as GraphNode)));\n setFrame((s) => s + 1);\n }, []);\n\n // Filtered node indices for search\n const filteredSet = useMemo<Set<number> | null>(() => {\n const layout = layoutRef.current;\n if (!layout || !searchQuery) return null;\n const q = searchQuery.toLowerCase();\n return new Set(\n layout.nodes\n .map((n, i) =>\n n.summaryTruncated.toLowerCase().includes(q) || n.label.toLowerCase().includes(q) ? i : -1,\n )\n .filter((i) => i >= 0),\n );\n }, [searchQuery]);\n\n // Health indicator helpers (D3)\n\n /**\n * Derive graph health from validation report:\n * green = all gates passed + no warnings\n * yellow = warnings present but no critical gate failed\n * red = a critical gate (gatesRun > gatesPassed) failed\n */\n const graphHealth = useMemo<{ level: \"green\" | \"yellow\" | \"red\"; label: string }>(() => {\n const v = data?.validation;\n if (!v) return { level: \"yellow\", label: \"No validation\" };\n if (v.gatesPassed < v.gatesRun) return { level: \"red\", label: \"Gate failure\" };\n if (v.warnings.length > 0) return { level: \"yellow\", label: `${v.warnings.length} warning(s)` };\n return { level: \"green\", label: \"Healthy\" };\n }, [data?.validation]);\n\n const healthColor: Record<string, string> = {\n green: \"#22c55e\",\n yellow: \"#eab308\",\n red: \"#ef4444\",\n };\n\n // Source availability indicators (D3)\n\n /** Count badge fragments from validation.sources. */\n const countBadge = useMemo<string>(() => {\n const v = data?.validation;\n if (!v) {\n const totalNodes = data?.metadata.totalNodes ?? 0;\n return `${totalNodes} nodes`;\n }\n const parts: string[] = [];\n if (v.sources.checkpoint > 0) parts.push(`${v.sources.checkpoint} checkpoints`);\n if (v.sources.turn > 0) parts.push(`${v.sources.turn} turns`);\n if (v.sources.turnContent > 0) parts.push(`${v.sources.turnContent} turn-content`);\n if (v.sources.memory > 0) parts.push(`${v.sources.memory} memories`);\n if (parts.length === 0) {\n parts.push(`${data?.metadata.totalNodes ?? 0} nodes`);\n }\n return parts.join(\" · \");\n }, [data?.validation, data?.metadata.totalNodes]);\n\n /** Per-source availability: ✓ for available sources, ✗ for empty ones. */\n const sourceAvail = useMemo<string>(() => {\n const v = data?.validation;\n if (!v) return \"\";\n const parts: string[] = [];\n parts.push(v.sources.checkpoint > 0 ? \"✓ checkpoints\" : \"✗ checkpoints\");\n parts.push(v.sources.turn > 0 ? \"✓ turns\" : \"✗ turns\");\n parts.push(v.sources.turnContent > 0 ? \"✓ turn-content\" : \"✗ turn-content\");\n parts.push(v.sources.memory > 0 ? \"✓ memories\" : \"✗ memories\");\n return parts.join(\" | \");\n }, [data?.validation]);\n\n /** Whether all four sources are empty (true empty state). */\n const allSourcesEmpty = useMemo<boolean>(() => {\n const v = data?.validation;\n if (!v) return data?.metadata.totalNodes === 0;\n return (\n v.sources.checkpoint === 0 &&\n v.sources.turn === 0 &&\n v.sources.turnContent === 0 &&\n v.sources.memory === 0\n );\n }, [data?.validation, data?.metadata.totalNodes]);\n\n // Loading state\n\n if (loading) {\n return (\n <div className=\"rounded-lg border border-border bg-bg-card p-6 text-center text-sm text-muted-foreground\">\n Loading memory graph...\n </div>\n );\n }\n\n // Error state\n\n if (error) {\n return (\n <div className=\"rounded-lg border border-border bg-bg-card p-6 text-center text-sm\">\n <p className=\"text-red-400\">Failed to load memory map: {error}</p>\n <button\n className=\"mt-3 rounded-md border border-border px-3 py-1.5 text-sm transition-colors hover:bg-bg-elevated hover:text-foreground\"\n onClick={() => setFrame((s) => s + 1)}\n >\n Retry\n </button>\n </div>\n );\n }\n\n // Empty state (D2)\n\n if (!data || !layoutRef.current || allSourcesEmpty) {\n return (\n <div className=\"rounded-lg border border-border bg-bg-card p-6 text-sm text-muted-foreground\">\n <p>Memories appear after your first compaction. The graph shows checkpoints (compaction summaries) linked by semantic similarity and time. Run a longer session or lower the compaction tier to see it sooner.</p>\n </div>\n );\n }\n\n const layout = layoutRef.current;\n\n // Render\n\n return (\n <div className=\"flex flex-col gap-3\">\n {/* Toolbar */}\n <div className=\"flex flex-wrap items-center gap-3\">\n <input\n type=\"text\"\n placeholder=\"Search memories...\"\n value={searchQuery}\n onInput={(e: React.FormEvent<HTMLInputElement>) =>\n setSearchQuery((e.target as HTMLInputElement).value)\n }\n className=\"w-56 rounded-md border border-border bg-bg-elevated/50 px-3 py-2 text-sm outline-none transition-colors focus:border-primary\"\n />\n <span className=\"text-xs text-muted-foreground\">\n <span>{countBadge}</span>\n {\" · \"}\n <span>{data.edges.length} edges</span>\n </span>\n {/* Graph-health indicator */}\n <span\n className=\"ml-auto rounded-full px-2 py-1 text-[11px] font-semibold text-white\"\n style={{ backgroundColor: healthColor[graphHealth.level] ?? \"#6b7280\" }}\n title={`Validation: ${graphHealth.label}`}\n >\n {graphHealth.level === \"green\" ? \"Healthy\" : graphHealth.level === \"yellow\" ? \"Warnings\" : \"Critical\"}\n </span>\n </div>\n\n {/* Source availability indicators */}\n {sourceAvail ? (\n <div className=\"text-[11px] text-muted-foreground\">{sourceAvail}</div>\n ) : null}\n\n {/* Legend — node types + edge types */}\n <div className=\"flex flex-wrap items-center gap-x-4 gap-y-1 rounded-lg border border-border/60 bg-bg-card px-3 py-2 text-xs\">\n <span className=\"font-semibold text-muted-foreground\">Nodes:</span>\n <Swatch type=\"node\" color={NODE_COLORS.checkpoint} shape=\"filled-circle\" label=\"Checkpoint\" />\n <Swatch type=\"node\" color={NODE_COLORS.turn} shape=\"hollow-circle\" label=\"Turn\" />\n <Swatch type=\"node\" color={NODE_COLORS[\"turn-content\"]} shape=\"hollow-ring\" label=\"Turn Content\" />\n <Swatch type=\"node\" color={NODE_COLORS.memory} shape=\"diamond\" label=\"Memory\" />\n <span className=\"font-semibold text-muted-foreground\">Edges:</span>\n <Swatch type=\"edge\" color={edgeColor(\"semantic\")} shape=\"line\" label=\"Semantic\" />\n <Swatch type=\"edge\" color={edgeColor(\"temporal\")} shape=\"line\" label=\"Temporal\" />\n <Swatch type=\"edge\" color={edgeColor(\"raptor_parent\")} shape=\"line\" label=\"Raptor\" />\n </div>\n\n {/* SVG graph */}\n <svg\n width={SVG_WIDTH}\n height={SVG_HEIGHT}\n viewBox={`0 0 ${SVG_WIDTH} ${SVG_HEIGHT}`}\n className=\"memory-map-svg\"\n >\n {/* Edges */}\n {layout.edges.map((e, i) => {\n const src = layout.nodes[e.source];\n const tgt = layout.nodes[e.target];\n const color = edgeColor(e.type);\n const strokeW = Math.max(1, e.weight * 2.5);\n return (\n <line\n key={`edge-${i}`}\n x1={PADDING + (src.pos.x / (layout.nodes.length || 1)) * (SVG_WIDTH - 2 * PADDING)}\n y1={PADDING + (src.pos.y / (layout.nodes.length || 1)) * (SVG_HEIGHT - 2 * PADDING)}\n x2={PADDING + (tgt.pos.x / (layout.nodes.length || 1)) * (SVG_WIDTH - 2 * PADDING)}\n y2={PADDING + (tgt.pos.y / (layout.nodes.length || 1)) * (SVG_HEIGHT - 2 * PADDING)}\n stroke={color}\n strokeWidth={strokeW}\n opacity={EDGE_ALPHA}\n />\n );\n })}\n\n {/* Nodes — shape encodes nodeType */}\n {layout.nodes.map((n, i) => {\n const cx =\n PADDING + (n.pos.x / (layout.nodes.length || 1)) * (SVG_WIDTH - 2 * PADDING);\n const cy =\n PADDING + (n.pos.y / (layout.nodes.length || 1)) * (SVG_HEIGHT - 2 * PADDING);\n const radius = Math.min(20, 8 + n.tokenEstimate / 500);\n const isFiltered = filteredSet ? filteredSet.has(i) : true;\n const isSelected = selectedNode?.id === n.id;\n const nodeLabel = n.label.length > 20 ? n.label.slice(0, 18) + \"...\" : n.label;\n\n return (\n <g\n key={`node-${i}`}\n className=\"memory-map-node-group\"\n onClick={() => handleNodeClick(n, i)}\n style={{ cursor: \"pointer\" }}\n >\n {renderNodeShape(cx, cy, radius, n.nodeType as NodeType, isSelected, isFiltered, n.dedupStatus)}\n <text\n x={cx}\n y={cy + radius + 12}\n textAnchor=\"middle\"\n fontSize=\"9px\"\n fill=\"#374151\"\n className=\"memory-map-label\"\n >\n {nodeLabel}\n </text>\n </g>\n );\n })}\n </svg>\n\n {/* Node detail panel */}\n {selectedNode ? (\n <div className=\"rounded-lg border border-border/60 bg-bg-card p-4 text-sm\">\n <h3 className=\"font-heading text-base font-semibold\">\n <span className=\"mr-1.5 text-xs font-normal text-muted-foreground\">\n {NODE_TYPE_LABELS[selectedNode.nodeType]}\n </span>\n {selectedNode.label}\n </h3>\n <p className=\"mt-1\">{selectedNode.summaryTruncated}</p>\n {selectedNode.topicSummary ? (\n <p className=\"mt-1\">Topic: {selectedNode.topicSummary}</p>\n ) : null}\n <p className=\"mt-1\">\n Tokens: {selectedNode.tokenEstimate} | Decisions: {selectedNode.decisionCount}\n </p>\n <p>Session: {selectedNode.sessionId}</p>\n <p>Raptor Level: {selectedNode.raptorLevel}</p>\n <p className=\"mt-1 text-muted-foreground\">{selectedNode.textSnippet}</p>\n </div>\n ) : null}\n </div>\n );\n};\n\nexport default MemoryMapView;\n","/**\n * MemoryMapTab/RaptorTreeView.tsx — RAPTOR tree sub-tab (Part B).\n *\n * Fetches the hierarchical RAPTOR tree from /api/raptor-tree (defaults to the\n * most recent session with nodes) and renders it as level-indented summary\n * cards. No D3 needed — CSS indentation encodes hierarchy.\n */\nimport type React from \"react\";\nimport { useEffect, useState } from \"react\";\nimport { fetchRaptorTree, fetchRaptorBuildHistory } from \"../../api/client\";\nimport type {\n\tRaptorTreeResponse,\n\tRaptorNodeDTO,\n\tRaptorBuildHistoryResponse,\n} from \"@contracts\";\n\n/** Per-level border color for node cards. */\nfunction levelColor(level: number): string {\n\tif (level === 0) return \"#d4a017\"; // gold — root\n\tif (level === 1) return \"#3b82f6\"; // blue\n\treturn \"#14b8a6\"; // teal — level 2+\n}\n\nfunction formatDate(ts: number): string {\n\tif (!ts) return \"—\";\n\treturn new Date(ts).toLocaleString();\n}\n\nfunction NodeCard({ node }: { node: RaptorNodeDTO }): React.ReactElement {\n\tconst border = levelColor(node.level);\n\tconst childrenLabel =\n\t\tnode.children.length > 0\n\t\t\t? `${node.children.length} child${node.children.length === 1 ? \"\" : \"ren\"}`\n\t\t\t: \"leaf\";\n\treturn (\n\t\t<div\n\t\t\tstyle={{\n\t\t\t\tbackground: \"#14142b\",\n\t\t\t\tborder: `1px solid ${border}`,\n\t\t\t\tborderRadius: \"8px\",\n\t\t\t\tpadding: \"0.75rem 1rem\",\n\t\t\t\tmarginBottom: \"0.6rem\",\n\t\t\t\tmarginLeft: node.level * 24,\n\t\t\t\tmaxWidth: \"90%\",\n\t\t\t}}\n\t\t>\n\t\t\t<div style={{ display: \"flex\", gap: \"0.75rem\", alignItems: \"center\", marginBottom: \"0.35rem\" }}>\n\t\t\t\t<span\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tdisplay: \"inline-block\",\n\t\t\t\t\t\tbackground: border,\n\t\t\t\t\t\tcolor: \"#fff\",\n\t\t\t\t\t\tborderRadius: \"10px\",\n\t\t\t\t\t\tpadding: \"1px 8px\",\n\t\t\t\t\t\tfontSize: \"11px\",\n\t\t\t\t\t\tfontWeight: 600,\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\tL{node.level}\n\t\t\t\t</span>\n\t\t\t\t<span style={{ fontSize: \"12px\", color: \"#6b7280\" }}>\n\t\t\t\t\t{childrenLabel} · {node.tokenEstimate} tok · {node.qualityMarker}\n\t\t\t\t</span>\n\t\t\t\t<span style={{ fontSize: \"12px\", color: \"#6b7280\", marginLeft: \"auto\" }}>\n\t\t\t\t\t{formatDate(node.builtAt)}\n\t\t\t\t</span>\n\t\t\t</div>\n\t\t\t<div style={{ fontSize: \"0.92rem\", color: \"#e5e7eb\" }}>{node.summary}</div>\n\t\t</div>\n\t);\n}\n\nexport default function RaptorTreeView(): React.ReactElement {\n\tconst [data, setData] = useState<RaptorTreeResponse | null>(null);\n\tconst [history, setHistory] = useState<RaptorBuildHistoryResponse | null>(null);\n\tconst [loading, setLoading] = useState<boolean>(true);\n\tconst [error, setError] = useState<string | null>(null);\n\n\tuseEffect(() => {\n\t\tlet cancelled = false;\n\t\tsetLoading(true);\n\t\tsetError(null);\n\t\tPromise.all([fetchRaptorTree(), fetchRaptorBuildHistory()])\n\t\t\t.then(([d, h]) => {\n\t\t\t\tif (!cancelled) {\n\t\t\t\t\tsetData(d);\n\t\t\t\t\tsetHistory(h);\n\t\t\t\t\tsetLoading(false);\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch((e: unknown) => {\n\t\t\t\tif (!cancelled) {\n\t\t\t\t\tsetError(e instanceof Error ? e.message : \"Unknown error\");\n\t\t\t\t\tsetLoading(false);\n\t\t\t\t}\n\t\t\t});\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, []);\n\n\tif (loading) {\n\t\treturn (\n\t\t\t<div className=\"rounded-lg border border-border bg-bg-card p-6 text-center text-sm text-muted-foreground\">\n\t\t\t\tLoading RAPTOR tree...\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (error) {\n\t\treturn (\n\t\t\t<div className=\"rounded-lg border border-dashed border-border bg-bg-card p-8 text-center text-sm\">\n\t\t\t\t<p className=\"text-red-400\">Failed to load RAPTOR tree: {error}</p>\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (!data || data.empty || data.nodes.length === 0) {\n\t\treturn (\n\t\t\t<div className=\"rounded-lg border border-dashed border-border bg-bg-card p-8 text-center text-sm text-muted-foreground\">\n\t\t\t\t<p>\n\t\t\t\t\tNo RAPTOR tree built yet — run a compaction (the tree builds during\n\t\t\t\t\tcompaction).\n\t\t\t\t</p>\n\t\t\t</div>\n\t\t);\n\t}\n\n\tconst latestBuild = history && !history.empty ? history.builds[0] : null;\n\tconst coherencePct = latestBuild?.coherenceScore != null\n\t\t? Math.round(latestBuild.coherenceScore * 100)\n\t\t: null;\n\n\treturn (\n\t\t<div className=\"w-full p-4\">\n\t\t\t<div className=\"mb-4 flex items-center gap-6 text-sm text-muted-foreground\">\n\t\t\t\t<span>\n\t\t\t\t\t<strong>{data.nodes.length}</strong> nodes\n\t\t\t\t</span>\n\t\t\t\t<span>\n\t\t\t\t\t<strong>{data.levels + 1}</strong> levels\n\t\t\t\t</span>\n\t\t\t\t<span>Built {formatDate(data.builtAt ?? 0)}</span>\n\t\t\t\t{latestBuild && (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\tCoherence:{\" \"}\n\t\t\t\t\t\t\t<strong style={{ color: coherencePct != null && coherencePct >= 70 ? \"#22c55e\" : \"#f59e0b\" }}>\n\t\t\t\t\t\t\t\t{coherencePct != null ? `${coherencePct}%` : \"—\"}\n\t\t\t\t\t\t\t</strong>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\tLeaves: <strong>{latestBuild.leafCount}</strong>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\tDepth: <strong>{latestBuild.depth}</strong>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t\t{latestBuild.timedOut && (\n\t\t\t\t\t\t\t<span style={{ color: \"#ef4444\" }}>budget timeout</span>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t\t{history && !history.empty && history.builds.length > 1 && (\n\t\t\t\t<details className=\"mb-4\">\n\t\t\t\t\t<summary className=\"cursor-pointer text-xs text-muted-foreground\">\n\t\t\t\t\t\tBuild history ({history.builds.length} builds)\n\t\t\t\t\t</summary>\n\t\t\t\t\t<div className=\"mt-2 space-y-1\">\n\t\t\t\t\t\t{history.builds.slice(0, 10).map((b) => (\n\t\t\t\t\t\t\t<div key={b.buildId} className=\"flex items-center gap-4 text-xs text-muted-foreground\">\n\t\t\t\t\t\t\t\t<span>{formatDate(b.completedAt)}</span>\n\t\t\t\t\t\t\t\t<span>{b.nodeCount} nodes</span>\n\t\t\t\t\t\t\t\t<span>{b.leafCount} leaves</span>\n\t\t\t\t\t\t\t\t<span>depth {b.depth}</span>\n\t\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t\tcoherence{\" \"}\n\t\t\t\t\t\t\t\t\t{b.coherenceScore != null\n\t\t\t\t\t\t\t\t\t\t? `${Math.round(b.coherenceScore * 100)}%`\n\t\t\t\t\t\t\t\t\t\t: \"—\"}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t{b.timedOut && <span style={{ color: \"#ef4444\" }}>timeout</span>}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</div>\n\t\t\t\t</details>\n\t\t\t)}\n\t\t\t{data.nodes.map((node) => (\n\t\t\t\t<NodeCard key={node.id} node={node} />\n\t\t\t))}\n\t\t</div>\n\t);\n}\n","/**\n * MemoryMapTab.tsx — Sub-tab shell under Memory Map (Part B).\n *\n * Hosts two sub-tabs: the D3 force-directed Memory Map (MemoryMapView) and\n * the hierarchical RAPTOR tree (RaptorTreeView). The heavy rendering logic\n * lives in ./MemoryMapTab/* to keep every file under the extensions limit.\n */\nimport type React from \"react\";\nimport { useState } from \"react\";\nimport MemoryMapView from \"./MemoryMapTab/MemoryMapView.js\";\nimport RaptorTreeView from \"./MemoryMapTab/RaptorTreeView.js\";\nimport { Toggle } from \"../components/ui/toggle\";\n\ntype MemoryMapSubTab = \"map\" | \"raptor\";\n\nconst MemoryMapTab: React.FC = () => {\n\tconst [subTab, setSubTab] = useState<MemoryMapSubTab>(\"map\");\n\n\treturn (\n\t\t<div className=\"flex flex-col gap-4\">\n\t\t\t<nav\n\t\t\t\tclassName=\"flex gap-2 border-b border-border pb-2 pt-2\"\n\t\t\t\taria-label=\"Memory map sections\"\n\t\t\t>\n\t\t\t\t<Toggle\n\t\t\t\t\tpressed={subTab === \"map\"}\n\t\t\t\t\tonClick={() => setSubTab(\"map\")}\n\t\t\t\t\taria-label=\"Memory Map view\"\n\t\t\t\t>\n\t\t\t\t\tMemory Map\n\t\t\t\t</Toggle>\n\t\t\t\t<Toggle\n\t\t\t\t\tpressed={subTab === \"raptor\"}\n\t\t\t\t\tonClick={() => setSubTab(\"raptor\")}\n\t\t\t\t\taria-label=\"RAPTOR Tree view\"\n\t\t\t\t>\n\t\t\t\t\tRAPTOR Tree\n\t\t\t\t</Toggle>\n\t\t\t</nav>\n\t\t\t{subTab === \"map\" && <MemoryMapView />}\n\t\t\t{subTab === \"raptor\" && <RaptorTreeView />}\n\t\t</div>\n\t);\n};\n\nexport default MemoryMapTab;\n"],"names":["NODE_COLORS","NODE_TYPE_LABELS","diamondPath","hw","hh","nodeOpacity","dedupStatus","renderNodeShape","cx","cy","radius","nodeType","isSelected","isFiltered","fill","strokeColor","opacity","jsx","REPULSION","ATTRACTION","CENTER_GRAVITY","DAMPING","MIN_VELOCITY","SPEED_LIMIT","buildLayout","data","nodes","i","angle","nodeIndex","edges","e","si","ti","applyForces","layout","n","fx","fy","j","dx","dy","distSq","force","dist","other","speed","MAX_ITERATIONS","EDGE_ALPHA","SVG_WIDTH","SVG_HEIGHT","PADDING","edgeColor","type","Swatch","color","shape","label","base","swatch","jsxs","Fragment","MemoryMapView","setData","useState","loading","setLoading","error","setError","selectedNode","setSelectedNode","searchQuery","setSearchQuery","filterSession","frame","setFrame","layoutRef","useRef","animRef","useEffect","cancelled","params","r","d","iter","tick","handleNodeClick","useCallback","node","index","prev","s","filteredSet","useMemo","q","graphHealth","v","healthColor","countBadge","parts","sourceAvail","allSourcesEmpty","src","tgt","strokeW","nodeLabel","levelColor","level","formatDate","ts","NodeCard","border","childrenLabel","RaptorTreeView","history","setHistory","fetchRaptorTree","fetchRaptorBuildHistory","h","latestBuild","coherencePct","b","MemoryMapTab","subTab","setSubTab","Toggle"],"mappings":"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"}
|