Move react-markdown, remark-gfm, remark-breaks, and rehype-highlight
imports from eager to dynamic via a LazyMarkdown wrapper component.
The ~336KB markdown bundle is now loaded on-demand after initial paint
instead of blocking the critical rendering path.
- Create LazyMarkdown component with Suspense fallback
- Pre-load plugins in parallel on module init
- Replace all ReactMarkdown usage in ChatMessage with LazyMarkdown
- Hide sidebar, header, chat input, and scroll button when printing
- Reset backgrounds to white, text to black for readability
- Code blocks get light background with borders
- Tool calls styled for print (compact, bordered)
- External links show their URL in parentheses
- Chat scroll area becomes fully visible (no overflow)
- Messages avoid page-break-inside for clean pagination
- Remove shadows and backdrop filters in print
- Replace div with <main> for primary chat pane (screen reader landmark)
- Replace div with <section> for split pane
- Add skip-to-content link for keyboard navigation (Tab → jump to chat input)
- Add aria-expanded and aria-label to tool call badge buttons
- Add id='chat-input' to textarea for skip link target
- Add i18n keys for new ARIA labels (EN + FR)
Show a CSS-only spinner while JS bundles load, improving perceived
performance on slow connections. Add noscript message for users with
JavaScript disabled.
The SW cache name was hardcoded to 'pinchchat-v1', meaning PWA users
would get stale cached assets forever. Now the cache name includes
the package version and build timestamp, so each build creates a new
cache and old ones are cleaned up on activation.
Also adds:
- Periodic SW update check (every 30 min)
- Auto-reload when new SW version is detected
Remove 5 unused production dependencies:
- @radix-ui/react-collapsible
- @radix-ui/react-scroll-area
- @radix-ui/react-separator
- @radix-ui/react-tooltip
- class-variance-authority
These were leftover from initial scaffolding and never imported.
Reduces install footprint and dependency count.
Add c, cpp, and java to the highlight.js language bundle for code block
rendering. These are among the most commonly used languages in AI coding
conversations and were previously unsupported, falling back to plain text.
Also adds aliases: h (C headers), cc/cxx/c++/hpp/hxx (C++ variants).
- Add HEALTHCHECK instruction to Dockerfile (wget localhost:80, 30s interval)
- Add healthcheck config to docker-compose.yml
- Enables Docker/orchestrator health monitoring and auto-restart on failure
- Wrap ChatMessageComponent with React.memo to skip re-renders when props unchanged
- Hoist remarkPlugins and rehypePlugins arrays to module scope to avoid
creating new array references on every render (prevents unnecessary
ReactMarkdown re-processing)
- Use proper PluggableList type from unified instead of any
- ThemeSwitcher: aria-expanded, aria-haspopup, aria-pressed on theme/accent buttons, Escape to close, dialog role
- ThinkingBlock: aria-expanded on toggle, region role on content
- ThinkingIndicator: role=status, aria-label, decorative icon aria-hidden
- ErrorBoundary: role=alert on error state
- SessionIcon: aria-hidden on decorative SVG brand icons
Tailwind's preflight resets list-style to none on ul/ol elements.
Add explicit list-style-type rules for markdown-body: disc for ul,
decimal for ol, with circle/square for nested levels.
Also add li margin for spacing.
Closes feedback #61
- Expose resolvedTheme in ThemeContext for theme-aware rendering
- Tool call badges: darker text colors and higher bg opacity in light theme
- User message bubbles: increased bg opacity and border strength in light theme
- Progress bars and send button already use accent CSS variables (no change needed)
Closes feedback #60
- User messages appear instantly with 'sending' state (dimmed, clock icon)
- Transitions to 'sent' (checkmark) when server acknowledges
- Shows error state (alert icon, retry visible) if send fails
- Applied to both primary and secondary sessions
- Set up Vitest with 27 tests across 3 test suites
- relativeTime: edge cases, time buckets, future timestamps
- sessionDisplayName: labels, kinds, channels, UUID truncation
- messagesToMarkdown: roles, blocks, tool calls, system events
- Add test and test:watch npm scripts
- Add test step to CI workflow
WebSocket debug logs are now silent by default. Enable with:
localStorage.setItem('pinchchat:debug', '1')
Reduces console noise in production while keeping full debug
visibility available for developers.
Replace highlight.js/lib/common (36 languages) with a curated subset
of 16 languages relevant for coding-assistant chat UIs. Both ToolCall
(direct hljs) and ChatMessage (rehype-highlight) now share the same
custom bundle from src/lib/highlight.ts.
Languages included: bash, css, diff, dockerfile, go, ini, javascript,
json, markdown, python, rust, shell, sql, typescript, xml, yaml.
Markdown chunk: 477KB → 336KB (-30%, -45KB gzipped)