import { useState } from 'react'; import type { AgentRecord, WireEntry } from '../../types'; import { CopyButton } from '../shared/CopyButton'; import { JsonViewer } from '../shared/JsonViewer'; import { GenericDetail } from './parts'; import { rendererFor } from './renderers'; interface WireRowDetailProps { entry: WireEntry; /** Scroll to + expand a given line. */ onJumpTo?: (lineNo: number) => void; } type JsonView = 'none' | 'raw' | 'projected'; export function WireRowDetail({ entry }: WireRowDetailProps) { const [view, setView] = useState('none'); // Only offer the dual view when migration actually changed something. // For records on the current protocol, `raw` and `data` are identical // and the toggle would just be visual noise. const migrated = !sameJson(entry.raw, entry.data); return (
{renderFriendly(entry.data)}
{migrated ? ( ) : null} {migrated ? ( ) : null}
{view !== 'none' ? (
{view === 'raw' ? 'as written on disk' : 'after vis migration'} {migrated && view === 'raw' ? ( — differs from projected ) : null}
) : null}
); } function sameJson(a: unknown, b: unknown): boolean { try { return JSON.stringify(a) === JSON.stringify(b); } catch { return false; } } /** Render the expanded detail for a wire record. Thin dispatch to the per-kind * registry's `detail`; kinds without one fall back to a structured JSON dump. */ function renderFriendly(record: AgentRecord) { const renderer = rendererFor(record.type); if (renderer?.detail !== undefined) return renderer.detail(record); return ; }