(null);
const html = renderMarkdown(text);
useEffect(() => {
// marked autolinks URLs but leaves them same-tab — open externally
// so a click never navigates the terminal away.
ref.current?.querySelectorAll("a[href]").forEach((a) => {
a.setAttribute("target", "_blank");
a.setAttribute("rel", "noopener noreferrer");
});
}, [html]);
// eslint-disable-next-line react/no-danger -- sanitized by DOMPurify in renderMarkdown
return (
);
}
function DiffBody({ text }: { text: string }) {
const lines = String(text).split("\n");
return (
{lines.map((line, i) => {
const cls = line.startsWith("+ ")
? "diff-add"
: line.startsWith("- ")
? "diff-del"
: "diff-ctx";
return (
{line}
{"\n"}
);
})}
);
}
export function Row({ row }: { row: TermRow }) {
const cssClass = "level-" + row.level;
const icon = row.icon != null && row.icon !== "" && (
{row.icon}
);
if (row.body == null) {
return (
{icon}
{linkifyToNodes(row.summary)}
);
}
// Empty summary + markdown body → the body itself is the whole row
// (assistant text), no summary prefix line, never collapsible.
if (row.body_format === "markdown" && row.summary === "") {
return (
{icon}
);
}
return (
{icon}
{row.summary}
{row.body_format === "diff" && }
{row.body_format === "markdown" && }
{row.body_format == null && (
{linkifyToNodes(row.body)}
)}
);
}