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)
- Add sw.js with stale-while-revalidate caching for static assets
- Network-first for HTML navigation, skip API/WS requests
- Register service worker in main.tsx on page load
- Enhanced manifest.json with orientation, categories, and all icon sizes
- App is now installable as a standalone PWA on mobile and desktop
- Show a pulsing placeholder while images load
- Display a graceful error state with ImageOff icon when images fail to load
- Prevents broken image icons from cluttering the chat
Markdown links pointing to external URLs (http/https) now open in a
new tab with target=_blank and rel='noopener noreferrer' for security.
Internal/relative links are unaffected.
Adds a 'System' option to the theme switcher that automatically uses
light or dark theme based on the OS prefers-color-scheme setting.
Dynamically updates when the OS preference changes (e.g. scheduled
dark mode). i18n labels added for EN/FR.
Suppress 3 react-hooks/set-state-in-effect warnings with targeted
eslint-disable comments. These are intentional patterns:
- ChatInput: restore draft text on session switch
- MessageSearch: reset active index on query change
- ToolCall: sync open state with global collapse/expand toggle
Lint now passes with 0 errors and 0 warnings.