UX improvements: message viewer, analytics, and sync performance - #10
Conversation
Switch to Manrope (body) and JetBrains Mono (code) from Google Fonts for proper typographic hierarchy. Body text uses proportional font at 14px instead of monospace at 13px. Add role icon circles for instant user/assistant identification. Update color palette to cooler tones with real purple (#7c3aed) for assistant accent. Code blocks use dedicated dark background (--code-bg) for strong visual contrast. Messages constrained to 880px max-width rail for comfortable reading. Increase spacing throughout: message padding, segment gaps, header margins. Refine tool blocks and thinking blocks with subtler borders and cleaner hover states. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When the user selects a project in the top bar, the dashboard now updates to show only that project's analytics data. Previously the sessions store and analytics store had independent project filters with no synchronization. The sync is one-directional: header → dashboard. Local drill-downs (clicking a project bar in ProjectBreakdown) still work independently without being overridden by the header filter. Uses untrack() to avoid the $effect re-triggering on analytics-internal project changes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace Manrope with the same system font stack GitHub uses for prose (-apple-system, BlinkMacSystemFont, Segoe UI, Noto Sans, Helvetica, Arial). Keep JetBrains Mono for code blocks. Remove the 880px max-width centering rail from MessageList that was causing excessive whitespace on the sides. Messages now fill the available content area with 12px horizontal padding. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When clicking a bar in the activity timeline (day granularity), the chart now highlights the selected bar and dims the others, matching the behavior of the project breakdown horizontal bar chart. Previously, clicking a bar re-fetched activity data narrowed to that single date, causing the chart to re-render with only one bar visible. The selectDate and clearDate methods no longer call fetchActivity, keeping the full timeline visible as context. Other panels (summary, projects, tools, etc.) still update with filtered data for the selected date. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The file watcher's onChange callback was running SyncAll on every change, which discovers all session files and computes SHA-256 hashes for each. This caused excessive CPU usage with many sessions. SyncPaths classifies changed paths by agent type, then processes only those files. Paths that don't match session file patterns (directories, non-JSONL files, agent-* files) are filtered out. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ness Remove fetchAll from onMount and let the $effect handle both initial load and header project sync, eliminating a double-fetch on page load. Change fetchActivity to use baseParams() instead of filterParams() so the timeline always shows the full date range when a date is selected (matching fetchHeatmap/fetchHourOfWeek). Prevents stale narrow data when other filters trigger fetchAll while a date is active. Add clearDate and activity-uses-full-range tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Use filepath.Clean + filepath.Rel for path containment checks instead of strings.HasPrefix, fixing trailing-slash dir configs - Tighten Codex classification to require year/month/day structure matching DiscoverCodexSessions rules - Tighten Gemini classification to require tmp/<hash>/chats structure matching DiscoverGeminiSessions rules - Update lastSyncStats in SyncPaths (was only setting lastSync) - Add tests for trailing-slash dirs, Gemini SyncPaths, flat Codex rejection, wrong Gemini structure rejection, and stats update Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
roborev: Combined Review (
|
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
roborev: Combined Review (
|
- Wrap analytics.fetchAll() in untrack() inside the $effect so that reactive reads in filterParams/baseParams don't become tracked dependencies (which caused duplicate fetches on unrelated state changes like date selection or granularity) - Change SplitN to Split for Claude path classification so that nested paths like proj/subdir/file.jsonl are rejected (discovery only walks one level deep) - Add test for nested Claude path rejection Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
roborev: Combined Review (
|
## Summary - Overhaul session message viewer for readability: system font stack, role icon circles, proportional body text at 14px, darker code blocks, refined tool/thinking blocks - Sync header project filter to analytics dashboard so selecting a project in the top bar filters the dashboard - Highlight selected activity timeline bar instead of re-rendering the chart with a single bar - Fix excessive CPU usage by making the file watcher sync only changed files instead of running full SyncAll with SHA-256 hashing of every file - Fix duplicate fetchAll on analytics page mount and activity timeline staleness ## Test plan - [x] All 304 frontend vitest tests pass (including new analytics tests) - [x] All Go tests pass across all packages (including 5 new SyncPaths tests) - [ ] Manual: verify message viewer readability in light/dark themes - [ ] Manual: verify selecting a project in header updates the analytics dashboard - [ ] Manual: verify clicking a timeline bar highlights it and dims others - [ ] Manual: verify CPU usage is reduced during active file watching 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Summary
Test plan
🤖 Generated with Claude Code