**Goal:** Add reliable LaTeX/math rendering to Hermes Web UI chat Markdown messages so formulas render visually instead of appearing as raw TeX, including explicit fenced math blocks like ```latex.
**Architecture:** Keep the existing `markdown-it` renderer in `MarkdownRenderer.vue` and add a KaTeX-backed math plugin there, plus a small fence override for explicit LaTeX code fences. Load KaTeX styles globally once, cover inline, display, and fenced math in component tests, then verify with a production build and a local Web UI smoke test.
## Task 2: Add TypeScript module declaration if needed
**Objective:** Keep TypeScript strict and avoid `any` leaking into the renderer setup.
**Files:**
- Create if needed: `packages/client/src/types/markdown-it-katex.d.ts`
**Step 1: Run typecheck to discover whether declaration is needed**
```bash
npm run build
```
**Expected before implementation:** build may still fail later because code is not changed yet. For this task, only check whether TypeScript knows the `markdown-it-katex` module after it is imported in Task 3.
**Step 2: If TS2307/TS7016 appears, create declaration**
systemctl --user status hermes-web-ui.service --no-pager --lines=20
```
**Step 4: Smoke test HTTP response**
```bash
curl -sS -I --max-time 5 http://127.0.0.1:8648/ | head -20
```
**Expected:** HTTP 200/304 or another successful static response, not connection refused.
**Step 5: Browser smoke test**
Open the chat panel and send/render a message containing:
```md
Inline: $x^2 + y^2 = z^2$
Block:
$$
\\int_0^1 x^2 dx = \\frac{1}{3}
$$
Code fence should stay literal:
```md
$x^2 + y^2 = z^2$
```
```
**Expected:** first two formulas render visually; fenced formula stays literal.
---
## Task 8: Prepare upstream PR
**Objective:** Make the contribution easy for upstream maintainers to review.
**Files:**
- No code changes required unless PR polish finds an issue.
**Step 1: Push branch**
```bash
git push origin feat/latex-rendering
```
**Step 2: Create PR draft**
```bash
gh pr create \
--repo EKKOLearnAI/hermes-web-ui \
--head kira-project-lab:feat/latex-rendering \
--base main \
--title "feat(chat): render LaTeX math in Markdown messages" \
--body "$(cat <<'EOF'
## Summary
- Adds KaTeX-backed LaTeX rendering to chat Markdown messages.
- Supports inline `$...$` and display `$$...$$` math.
- Keeps math inside fenced code blocks literal.
## Test Plan
- [ ] npm run test -- tests/client/markdown-rendering.test.ts
- [ ] npm run test -- tests/client/markdown-rendering-mermaid-import-timeout.test.ts
- [ ] npm run build
- [ ] Manual browser smoke test with inline, block, and fenced math
## Notes
This uses the existing markdown-it rendering path and keeps HTML disabled.
EOF
)" \
--draft
```
**Step 3: Attach visual proof**
Add before/after screenshots in the PR body or a PR comment:
- Before: raw `$...$` / `$$...$$` text.
- After: rendered KaTeX inline and display equations.
---
## Risks and Guardrails
- **Delimiter ambiguity:** `$` is common in shell snippets and prices. The fenced-code test protects code blocks, but inline text like `cost is $5 and $6` may be parsed depending on plugin behavior. If this is noisy, switch to `markdown-it-texmath` with explicit delimiter options or configure delimiters to prioritize `\(...\)` / `\[...\]`.
- **Security:** keep `html: false` in `markdown-it`; do not enable arbitrary HTML. KaTeX should run with `trust: false` unless a clear need appears.
- **Bundle size:** KaTeX adds client bundle weight. Acceptable for this feature, but mention it in PR if maintainers ask.
- **CSS scope:** KaTeX CSS is global. Import once in `main.ts`; avoid duplicating it inside component styles.
- **Invalid math:** `throwOnError: false` should prevent chat crashes. Regression test required.