Redesign HTML exporter with dark theme, timestamps, and performance fixes

Visual overhaul of exported HTML to match the new client dark design:
- Replace category-specific CSS classes with inline border/dot/text styles
  from a CATEGORY_STYLES map matching client-side colors
- Add message header layout with category dot, label, and timestamp
- Add Inter font family, refined prose typography, and proper code styling
- Add print-friendly media query
- Redesign redacted divider with SVG eye-slash icon and red accent
- Add SVG icons to session header metadata (project, date, message count)
- Fix singular/plural for '1 message' vs 'N messages'

Performance: Skip markdown parsing for hook_progress, tool_result, and
file_snapshot categories (structured data). Render as preformatted text
instead, avoiding expensive marked.parse() on large JSON blobs (~300ms each).

Replace local escapeHtml with shared/escape-html module. Add formatTimestamp
helper. Add cast safety comment for marked.parse() sync usage.

Update test to verify singular message count ('1 message' not '1 messages').

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-30 01:10:35 -05:00
parent 9716091ecc
commit 0e89924685
2 changed files with 277 additions and 64 deletions

View File

@@ -114,6 +114,8 @@ describe("html-exporter", () => {
const html = await generateExportHtml(makeExportRequest([msg]));
expect(html).toContain("test-project");
expect(html).toContain("Session Export");
expect(html).toContain("1 messages");
expect(html).toContain("1 message");
// Verify singular — should NOT contain "1 messages"
expect(html).not.toMatch(/\b1 messages\b/);
});
});