- 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.
- X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy
- Prevent caching index.html so SPA updates are always picked up
- Add engines field (node >=18) and lint:fix script to package.json
- Add split view button (columns icon) in sidebar session actions
- Click to open any session in a secondary pane alongside the primary
- Resizable divider between panes (drag to resize, persisted in localStorage)
- Secondary pane supports full chat: history, streaming, send, abort
- Close split view via X button or clicking the split icon again
- Each pane has independent scroll, search, and tool collapse
- Keyboard shortcut and i18n support (EN/FR)
- Drag sessions to reorder within pinned/unpinned groups
- Custom order persists in localStorage
- Visual feedback: dragged item fades, drop target highlights
- Disabled during search filtering
- Works alongside existing pin feature (pinned group stays on top)
Add a {} button (visible on hover) that toggles a collapsible panel
showing the full raw gateway JSON payload for any message.
Includes copy-to-clipboard, word-wrap, and i18n (EN/FR).
Useful for debugging and understanding the gateway protocol.
Closes feedback #52
Messages from /hooks/agent containing SECURITY NOTICE blocks and
<<<EXTERNAL_UNTRUSTED_CONTENT>>> delimiters are now cleaned up.
Only the actual user content is displayed, with a small webhook
badge indicator showing the message originated from a webhook.
Closes feedback #54
Extract thinking blocks from delta events and render them inline
using the existing ThinkingBlock component. Previously, thinking
content was only visible after the stream finished (via history
reload). Now it appears in real-time as the agent reasons.
Closes feedback #57.
Replace ~150 hardcoded Tailwind color classes (bg-zinc-*, text-zinc-*,
border-white/*, text-cyan-*, bg-cyan-*) with CSS custom properties
(--pc-*) across all 17 components.
Add @theme block in index.css for Tailwind v4 theme-aware utility
classes (bg-pc-elevated, text-pc-text, border-pc-border, etc.).
Add --pc-hover, --pc-hover-strong, --pc-separator variables per theme
(white/alpha for dark/OLED, black/alpha for light).
Theme switcher (dark/light/OLED) now actually works — all UI elements
respond to theme changes in real-time.
Fixes#55
- Extract ThemeContext and ToolCollapseContext definitions into separate
files to satisfy react-refresh/only-export-components rule
- Move useTheme and useToolCollapse hooks to dedicated hook files
- Fix empty catch block in ThemeContext (add comment)
- Replace Date.now() ref in ThinkingIndicator with useState initializer
- Update all imports across components
Closes feedback #58