diff --git a/packages/cli/src/ui/utils/MarkdownDisplay.test.tsx b/packages/cli/src/ui/utils/MarkdownDisplay.test.tsx
index 7f2e8f1d9a..877d642f8c 100644
--- a/packages/cli/src/ui/utils/MarkdownDisplay.test.tsx
+++ b/packages/cli/src/ui/utils/MarkdownDisplay.test.tsx
@@ -155,6 +155,21 @@ Some text before.
expect(lastFrame()).toMatchSnapshot();
});
+ it('renders escaped pipe characters inside table cells', () => {
+ const text = `
+| Type | Example |
+|------|---------|
+| Union | A\\|B |
+| Plain | Hello |
+`.replace(/\n/g, eol);
+ const { lastFrame } = renderWithProviders(
+ ,
+ );
+ const frame = lastFrame()!;
+ expect(frame).toContain('A|B');
+ expect(frame).not.toContain('A\\|B');
+ });
+
it('inserts a single space between paragraphs', () => {
const text = `Paragraph 1.
diff --git a/packages/cli/src/ui/utils/MarkdownDisplay.tsx b/packages/cli/src/ui/utils/MarkdownDisplay.tsx
index b67b8fd61b..9954824d66 100644
--- a/packages/cli/src/ui/utils/MarkdownDisplay.tsx
+++ b/packages/cli/src/ui/utils/MarkdownDisplay.tsx
@@ -27,6 +27,16 @@ const CODE_BLOCK_PREFIX_PADDING = 1;
const LIST_ITEM_PREFIX_PADDING = 1;
const LIST_ITEM_TEXT_FLEX_GROW = 1;
+/**
+ * Splits a markdown table row on unescaped `|` delimiters,
+ * then un-escapes any `\|` sequences within each cell.
+ */
+function splitTableCells(row: string): string[] {
+ return row
+ .split(/(? cell.replace(/\\\|/g, '|').trim());
+}
+
const MarkdownDisplayInternal: React.FC = ({
text,
isPending,
@@ -111,7 +121,7 @@ const MarkdownDisplayInternal: React.FC = ({
lines[index + 1].match(tableSeparatorRegex)
) {
inTable = true;
- tableHeaders = tableRowMatch[1].split('|').map((cell) => cell.trim());
+ tableHeaders = splitTableCells(tableRowMatch[1]);
tableRows = [];
} else {
// Not a table, treat as regular text
@@ -127,7 +137,7 @@ const MarkdownDisplayInternal: React.FC = ({
// Skip separator line - already handled
} else if (inTable && tableRowMatch) {
// Add table row
- const cells = tableRowMatch[1].split('|').map((cell) => cell.trim());
+ const cells = splitTableCells(tableRowMatch[1]);
// Ensure row has same column count as headers
while (cells.length < tableHeaders.length) {
cells.push('');