/**
* @fileoverview Chat panel markdown renderer for Assistant bubbles.
*
* Task #2975 (parent: Task #2953) — user feedback 2026-08-13:
* The terminal `roy-agent act` renders long Assistant output with line
* breaks / table cells / bullet lists, but the task-show web chat
* panel collapses everything into one text blob. The user wants the
* same markdown rendering the terminal uses.
*
* Strategy (v2.5.x REQ-4 + Task #2975):
* - Reuse `marked` (already a devDependency) and let it do the heavy
* lifting (`gfm: true` for tables, `breaks: true` for `\n` → `
`).
* - Pre-process the input to normalize our terminal-friendly
* separators (em-dash, four-dash rule, bullet-plus-dash rule)
* into markers marked can render.
* - Pre-process `•` bullets to `-` bullets so marked sees a valid
* list.
* - Sanitize the final HTML via DOMPurify (jsdom in tests, real
* DOMPurify in the browser via the existing vendored copy).
*
* Why a separate module instead of patching `public/markdown-renderer.js`:
* `public/markdown-renderer.js` is loaded as an ES module in the
* browser *and* required from bun tests with a happy-dom window.
* Adding the jsdom-aware DOMPurify factory there doubled its size
* and made the SANITIZE path differ between environments. We isolate
* the pre-process + sanitize here so the existing
* `public/markdown-renderer.js` is unchanged (no regression risk for
* the v2.5.x chat panel that already works for plain markdown).
*
* Public API:
* - renderAssistantMarkdown(text) → sanitized HTML string
* - normalizeAssistantText(text) → pre-processed string (helper,
* primarily for tests; renderAssistantMarkdown applies it internally)
*/
/**
* Pre-process Assistant text into a form that `marked` can render
* properly. Runs three transformations:
*
* 1. Inline `——` (em-dash repetition) on the SAME line becomes
* `