feat(frontend): v2 artifact viewers for cte_plan/cte_result/phase

Add CtePlanViewer, CteResultViewer, and PhaseSummaryViewer to render the
structured v2 payloads (schema_version: 2) the harness now emits for
artifact-gate widgets, per contracts.md. Extract PreviewGrid from
ResultsPanel as a reusable AG Grid component shared by CteResultViewer.
ArtifactView dispatches to the new viewers on a schema_version/shape
guard, falling back to the existing legacy renderers unchanged for
older sessions and replay fixtures.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-07 00:57:20 +02:00
co-authored by Claude Fable 5
parent 3ad93cd02f
commit 1c97289ed8
12 changed files with 937 additions and 26 deletions
+31
View File
@@ -0,0 +1,31 @@
import { AgGridReact } from "ag-grid-react";
import { AllCommunityModule, ModuleRegistry } from "ag-grid-community";
// Register AG Grid modules once at module load time
ModuleRegistry.registerModules([AllCommunityModule]);
interface Props {
columns: string[];
rows: unknown[][];
}
/** Reusable read-only preview grid: columns + row tuples → AG Grid. */
export function PreviewGrid({ columns, rows }: Props) {
const columnDefs = columns.map((col) => ({ field: col, headerName: col }));
const rowData = rows.map((row) => {
const obj: Record<string, unknown> = {};
columns.forEach((col, i) => {
obj[col] = row[i];
});
return obj;
});
return (
<div className="overflow-hidden rounded-xl border border-border/70 shadow-xs">
<div className="ag-theme-alpine" style={{ height: 400, width: "100%" }}>
<AgGridReact columnDefs={columnDefs} rowData={rowData} />
</div>
</div>
);
}