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('');