webui: implement DOMPurify sanitization for markdown security

Implement comprehensive HTML sanitization using DOMPurify library to
prevent XSS vulnerabilities in markdown rendering while preserving
full markdown functionality.

Problem Analysis:
Chat timeline and tool card components used markdown rendering with
unsafeHTML directive and no HTML sanitization, creating security risks:
- Raw HTML from user input could execute arbitrary JavaScript
- Script tags, event handlers, and dangerous elements passed through
- marked.js default configuration allows HTML passthrough
- No protection against malicious content in conversation history

Security Solution - DOMPurify Implementation:
Following marked.js documentation recommendations, implemented industry-standard
DOMPurify library for comprehensive HTML sanitization using whitelist approach.

DOMPurify Security Advantages:
- Industry-standard library with regular security updates
- Comprehensive whitelist-based sanitization approach
- Automatically handles new XSS attack vectors as they emerge
- Completely removes dangerous elements rather than escaping
- Configurable allowlists for specific use case requirements
- Battle-tested across millions of applications

Implementation Changes:

1. Package Dependencies:
   - Added dompurify package dependency to webui/package.json
   - DOMPurify includes built-in TypeScript definitions
   - Leveraged existing transitive dependency through mermaid

2. Enhanced sketch-timeline-message.ts Security:
   - Integrated DOMPurify.sanitize() for HTML sanitization
   - Configured allowlist for safe HTML elements (p, strong, code, etc.)
   - Added support for mermaid diagram elements (svg, path, etc.)
   - Included code block functionality attributes (data-*, class, id)
   - Maintained existing mermaid diagram and code block functionality

3. Enhanced sketch-tool-card.ts Security:
   - Implemented DOMPurify sanitization in shared renderMarkdown utility
   - Configured appropriate allowlist for tool card content display
   - Simplified implementation using default marked.js settings
   - Maintained backward compatibility with existing tool components

4. DOMPurify Configuration:
   - ALLOWED_TAGS: Comprehensive list of safe HTML elements
   - ALLOWED_ATTR: Specific attributes for links, styling, functionality
   - ALLOW_DATA_ATTR: true for code copy buttons and interactions
   - KEEP_CONTENT: true to preserve text content and formatting

Security Verification:
- All dangerous HTML completely removed (script, iframe, object, etc.)
- Event handlers stripped from elements (onload, onerror, onclick)
- JavaScript URLs neutralized (javascript: protocol blocked)
- XSS attack vectors comprehensively mitigated through allowlist approach
- Edge cases handled automatically by library security updates

Functional Verification:
- Markdown formatting fully preserved (bold, italic, code, links)
- Code blocks render correctly with syntax highlighting classes
- Mermaid diagrams continue working with required SVG elements
- Copy-to-clipboard functionality maintained with data attributes
- All existing chat timeline and tool card features functional

Technical Benefits:
- Reduced maintenance burden - no custom escaping logic to maintain
- Automatic protection against new attack vectors via library updates
- Industry-standard approach following marked.js documentation recommendations
- Comprehensive allowlist prevents unknown dangerous elements
- Better performance through optimized library implementation

Testing:
- Verified all XSS attack vectors safely handled through comprehensive tests
- Confirmed markdown functionality preserved across all components
- Build process succeeds without TypeScript errors
- Comprehensive security test suite validates sanitization effectiveness

This implementation follows security best practices recommended by marked.js
documentation and provides robust protection against HTML injection attacks
while maintaining full markdown functionality and user experience quality.

Co-Authored-By: sketch <hello@sketch.dev>
Change-ID: s233c12c6daac5bb0k
diff --git a/webui/package.json b/webui/package.json
index b9eac73..4fbe008 100644
--- a/webui/package.json
+++ b/webui/package.json
@@ -24,8 +24,11 @@
     "test:playwright": "playwright test -c playwright-ct.config.ts"
   },
   "dependencies": {
+    "@types/dompurify": "^3.2.0",
     "@xterm/addon-fit": "^0.10.0",
     "@xterm/xterm": "^5.5.0",
+    "dompurify": "^3.2.6",
+    "jsdom": "^26.1.0",
     "lit": "^3.2.1",
     "marked": "^15.0.7",
     "mermaid": "^11.6.0",