fix(ui): preserve assistant output after raw HTML (#646)

## Summary
- sanitize raw HTML tokens in assistant Markdown with the existing
allowlist
- prevent dropped tags such as `<style>` from consuming or altering the
rest of a response
- add a focused regression for the malformed inline-code sequence
reported in #645

## Validation
- `node --conditions=browser --import tsx --test --test-force-exit
packages/ui/src/lib/markdown.test.ts`
- `npm run typecheck --workspace @codenomad/ui`
- `npm run build --workspace @codenomad/ui`
- `git diff --check`

Closes #645
This commit is contained in:
Pascal André 2026-08-13 10:21:00 +02:00 committed by GitHub
parent 7f16057ffb
commit 31390cb259
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 16 additions and 1 deletions

View file

@ -238,7 +238,7 @@ export default function MessagePart(props: MessagePartProps) {
sessionId={props.sessionId}
isDark={isDark()}
size={isAssistantMessage() ? "tight" : "base"}
escapeRawHtml={props.messageType === "user"}
escapeRawHtml
onRendered={props.onRendered}
/>
</Show>

View file

@ -112,3 +112,18 @@ describe("renderMarkdown bracket math delimiters", () => {
}
})
})
describe("renderMarkdown raw HTML", () => {
it("preserves text after style tags inside malformed inline code", async () => {
const content = [
"- evidence: [source] `return ",
'`<!DOCTYPE html><html><head><meta charset="utf-8"><style>${options.styles.join(";")}</style></head>',
'<body>${options.html}</body></html>`;` - and the test remains visible',
].join("")
const html = await renderMarkdown(content, { suppressHighlight: true, escapeRawHtml: true })
assert.doesNotMatch(html, /<style>/)
assert.match(html, /and the test remains visible/)
})
})