>
)}
>
)
}
/**
* The gutter glyph, with a tooltip naming the change type it stands for. The glyph stays
* `aria-hidden` — the row's `aria-label` already carries the same word — so the tooltip is a
* pointer affordance rather than a second announcement.
*/
const ChangeGlyph = ({ marker }: { marker: ChangeMarker }) => {
const className = cn('w-3 shrink-0 text-center font-mono text-xs leading-none', marker.className)
// An unchanged cell has no glyph, so there is nothing to explain — render the spacer alone.
if (!marker.glyph) return
return (
{marker.glyph}
{marker.changeLabel}
)
}
/** Same icons the notebook tab uses for query vs markdown cells. */
const CellTypeIcon = ({ cell }: { cell: CellWire | AgentCell }) => {
const Icon = cell._tag === 'markdown_cell' ? FileText : SquareCode
return
}
const CellBody = ({ entry }: { entry: NotebookCellDiffEntry }) =>
entry._tag === 'replaced' ? (
) : (
)
const ReplacedCellBody = ({ before, after }: { before: CellWire; after: AgentCell }) => (
)
/**
* The cell's source, always rendered as literal text via `CodeBlock` — agent-authored markdown
* must never be interpreted into real DOM nodes.
*/
const CellSource = ({ cell }: { cell: CellWire | AgentCell }) => (
)