* feat(frontend): add citation sources evidence panel
Inline [citation:Title](URL) links render as badges, but with many
citations the reader has no consolidated, deduplicated list of what a
message or report actually drew on. Add a collapsible "sources" panel
that extracts citation links from AI messages and markdown artifacts,
dedupes by URL, counts occurrences, and offers per-source copy of a
reusable markdown reference.
- extractCitationSources: parse [citation:...](url) links, skip images
and fenced code, dedupe by normalized URL, fall back to domain for
generic labels
- CitationSourcesPanel: collapsible list with per-source cite counts,
internal scroll for long lists, and copy-to-clipboard reference button
- Wire panel into AI message content and markdown artifact preview
- Add en-US/zh-CN citation strings and types
- Unit tests for extraction and panel rendering
* fix(frontend): preserve default link styling in message content override
MessageContent_ passes a custom `a` renderer to MarkdownContent, whose
default `a` (primary underline + external target/rel) is overridden
because MarkdownContent spreads props components last. Restore that
styling/external behavior in the fallback branch so normal links in
messages aren't regressed, while keeping citation: and /mnt/ handling.
* fix(frontend): harden citation source extraction and dedupe link renderer
Address review findings on the citation sources panel:
- Use a non-consuming lookbehind so back-to-back citations no longer drop
every other source.
- Match balanced parenthetical groups in URLs so disambiguation links like
.../Foo_(a)_(b) are no longer truncated.
- Mask inline code (and unclosed streaming fences) so example citations in
code aren't scraped as real sources; masking preserves indices.
- Extract a shared createMarkdownLinkComponent factory used by both message
content and markdown content, removing the duplicated `a` renderer.