fix: complete theme token system with WCAG-compliant color tokens#370
fix: complete theme token system with WCAG-compliant color tokens#370openasocket wants to merge 23 commits intoRunMaestro:mainfrom
Conversation
Replace hardcoded #fff, #000, and 'white' color values with theme tokens (accentForeground, bgMain) across 15 component files. This ensures proper contrast ratios on accent-colored backgrounds for all themes, including high-contrast and vibe themes like dre-synth. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add info, status foregrounds (successForeground, warningForeground, errorForeground), dimmed status backgrounds (successDim, warningDim, errorDim, infoDim), git diff colors (diffAddition, diffAdditionBg, diffDeletion, diffDeletionBg), overlay/interactive states (overlay, overlayHeavy, hoverBg, activeBg), and shadow tokens to ThemeColors. All 17 theme definitions populated with palette-appropriate values. Light themes use black hover overlays and lighter shadows; dark/vibe themes use white hover overlays with heavier shadows. CSS custom property mappings, fallback themes, and tests updated accordingly. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…g components - CustomThemeBuilder now displays all 30 tokens organized in 8 semantic sections - Fix remaining hardcoded colors in AgentSessionsModal chat bubbles, PlaygroundPanel button, and AgentSelectionScreen detection indicators - Update tests to assert against theme tokens instead of hardcoded color values Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Dre Synth theme has bright teal border color (#00d4aa) which made textDim (#60e0d0) invisible when used as disabled button text on border background. Switch disabled Send button from border to bgActivity background to ensure text contrast across all themes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Separate success/warning from accent/error colors so each status is visually distinct: success (#33ff99 green), warning (#ff9944 orange), error (#ff2a6d pink). Previously success shared accent teal and warning shared error pink. Also slightly brighten bgActivity for better contrast. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
pedramamini
left a comment
There was a problem hiding this comment.
Theme Token System Review
Solid direction — eliminating hardcoded colors in favor of semantic tokens is the right call. The new token taxonomy is well-organized and the section grouping in CustomThemeBuilder is a nice touch. A few things I noticed while going through it:
1. Missing Custom Theme Migration (Critical)
Users with saved custom themes have 13 tokens stored in electron-store. After this PR, ThemeColors requires 30. When useSettings.ts loads the saved theme, it directly assigns the incomplete object. Every component referencing the new tokens (info, successDim, overlay, etc.) will get undefined.
Fix in useSettings.ts where savedCustomThemeColors is loaded — merge with defaults:
if (savedCustomThemeColors !== undefined) {
setCustomThemeColorsState({
...DEFAULT_CUSTOM_THEME_COLORS,
...(savedCustomThemeColors as Partial<ThemeColors>),
});
}2. accentForeground Used on Non-Accent Backgrounds
Several replacements use accentForeground (text ON accent bg) on success and error backgrounds:
LeaderboardRegistrationModal.tsx:1256— Delete button:errorbg +accentForeground→ should beerrorForegroundAICommandsPanel.tsx:320,368— Save buttons:successbg +accentForeground→ should besuccessForegroundSpecKitCommandsPanel.tsx:270— Same pattern → should besuccessForeground
The whole point of adding successForeground/errorForeground is to use them on their respective backgrounds.
3. TerminalOutput.tsx — bgMain as Foreground Color
color: theme.colors.bgMain, // search highlight textUsing bgMain as text color on a warning background is semantically wrong — it only works if bgMain happens to contrast with warning. Should be warningForeground.
4. themes.test.ts REQUIRED_COLORS Not Updated
The REQUIRED_COLORS array in src/__tests__/renderer/constants/themes.test.ts:14 still only lists the original 13 tokens. Won't catch themes missing the new 17 tokens.
5. Remaining Hardcoded Colors (~40+ instances)
The PR addresses ~17 components but there are still hardcoded colors in AutoRun.tsx (4), DeleteAgentConfirmModal.tsx (2), DeleteWorktreeModal.tsx (3), ProcessMonitor.tsx (3), QueuedItemsList.tsx (1), InlineWizard/*.tsx (4), MergeProgressModal.tsx (2), NotificationsPanel.tsx (1), GroupChatInput.tsx:456 (1), SessionList.tsx (3), MainPanel.tsx (1), LogViewer.tsx (2), MarketplaceModal.tsx (3), SettingsModal.tsx (4) — mostly the same color: 'white' / color: '#fff' on accent/status backgrounds pattern.
6. New Tokens Not Yet Consumed
overlay, overlayHeavy, hoverBg, activeBg, shadow, diffAddition/Deletion/Bg, info, infoDim are defined but not used anywhere in this PR. Not blocking, just noting.
That said — don't stress about addressing all of this. I'm going to pull this into a local branch and give it a polish pass myself. If you've got the patience and want to work through the items above, that's hugely appreciated, but no pressure at all. The foundation here is good. 👍
The border token (#00d4aa) was a bright teal identical to the accent color, causing invisible text on 100+ components that use border as a disabled button/badge background with textDim text. Changed to #1a3a4a (dark muted teal) which maintains the synth aesthetic while functioning correctly as a border/surface color. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…sume Add configurable auto-scroll behavior for AI mode output that automatically scrolls to bottom when new content arrives, with smart pause when user scrolls up to read content and automatic resume when they scroll back to bottom. - Add autoScrollAiMode setting persisted via electron-store (default: off) - Add inline floating toggle button (bottom-left) with visual state feedback - Add keyboard shortcut (Alt+Cmd+S) registered as system utility shortcut - Add Settings Modal checkbox in General tab - Thread setting through App → MainPanel → TerminalOutput via props - Use instant scroll (behavior: 'auto') to prevent jitter during streaming - Pause auto-scroll when user scrolls up, resume on scroll-to-bottom - Toggle button reflects paused state (dim icon when paused) - New message indicator shown when paused (user scrolled away from bottom) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Pass autoScrollAiMode/setAutoScrollAiMode as props from App to SettingsModal so toggling takes immediate effect (was using independent useSettings() instance that didn't propagate to App's render tree) - Disable browser native scroll anchoring (overflow-anchor: none) on the AI output scroll container when auto-scroll is off or paused, preventing the browser from pinning viewport to bottom on new content - Add programmaticScrollRef guard and autoScrollPaused state to properly distinguish user scrolls from effect-driven scrolls Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When loading saved custom themes from electron-store, merge with DEFAULT_CUSTOM_THEME_COLORS so that themes saved with the old 13-token structure get sensible defaults for the 17 new tokens (info, successDim, overlay, hoverBg, shadow, diff*, etc.) instead of undefined values. Follows the same spread-defaults pattern already used for globalStats, autoRunStats, onboardingStats, and other settings in loadSettings(). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace accentForeground with the correct semantic foreground token when paired with success, error, or warning backgrounds: - LeaderboardRegistrationModal: error bg → errorForeground - AICommandsPanel: success bg → successForeground (2 locations) - SpecKitCommandsPanel: success bg → successForeground - AutoRunDocumentSelector: success bg → successForeground (3 locations) - GroupChatInput: warning bg (busy state) → warningForeground Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace theme.colors.bgMain with theme.colors.warningForeground for search highlight text in TerminalOutput.tsx. bgMain as a text color on warning backgrounds only works by accident when bgMain happens to contrast with warning — breaks on themes with different luminance. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…s tokens Previously only checked 13 of 30 tokens, meaning themes missing the new 17 tokens (status foregrounds, dim variants, diff colors, overlays, etc.) would pass tests silently. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ss 15 components
Replace hardcoded color values ('white', '#fff', '#ffffff', '#000', hex colors)
with semantic theme tokens (errorForeground, successForeground, warningForeground,
accentForeground, overlay, info, infoDim, successDim, warningDim, errorDim, etc.)
in AutoRun, DeleteAgentConfirmModal, DeleteWorktreeModal, GroupChatInput, LogViewer,
MainPanel, MarketplaceModal, MergeProgressModal, NotificationsPanel, ProcessMonitor,
QueuedItemsList, SessionList, SettingsModal, ConversationScreen, and DocumentEditor.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…verBg, activeBg) across 37 components Replace hardcoded rgba/hex colors with semantic theme tokens: - overlay/overlayHeavy: 15 modal backdrops (SymphonyModal, MarketplaceModal, MaestroWizard, etc.) - shadow: 11 boxShadow/textShadow instances (AchievementCard, DocumentsPanel, App.tsx, etc.) - diffAddition/diffDeletion/diffAdditionBg/diffDeletionBg: diff viewers (markdownConfig, ImageDiffViewer, GitDiffViewer, GitLogViewer) - info/infoDim: LogViewer level colors, DocumentNode large file indicator - hoverBg/activeBg: TabBar hover computation, TabSwitcherModal selected states - errorDim/warningDim: ContextWarningSash status backgrounds Updated 7 test files to assert theme token values instead of hardcoded colors. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…theme tokens across 11 components Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
All review items addressed + additional fixesThanks for the thorough review! Every item has been addressed across 6 commits: Review Item #1 — Custom Theme Migration (Critical) ✅Commit: Saved custom themes (13 tokens) are now merged with if (savedCustomThemeColors !== undefined) {
setCustomThemeColorsState({
...DEFAULT_CUSTOM_THEME_COLORS,
...(savedCustomThemeColors as Partial<ThemeColors>),
});
}Review Item #2 —
|
| File | Old | New | Context |
|---|---|---|---|
HistoryPanel.tsx |
#ffffff |
successForeground |
Validated task icon |
HistoryDetailModal.tsx |
#ffffff |
successForeground |
Validated task icon |
OpenSpecCommandsPanel.tsx |
#000000 |
successForeground |
Save button on success bg |
QuitConfirmModal.tsx |
#ffffff |
errorForeground |
"Quit Anyway" button |
TerminalOutput.tsx |
#fff (×2) |
errorForeground |
STDERR label + delete confirm |
MergeProgressOverlay.tsx |
#fff |
errorForeground |
Cancel button |
SummarizeProgressOverlay.tsx |
#fff |
errorForeground |
"Yes" button |
SummarizeProgressModal.tsx |
#fff |
successForeground |
Check icon on success bg |
TransferProgressModal.tsx |
#fff (×2) |
errorForeground + successForeground |
Cancel button + check icon |
PlaygroundPanel.tsx |
#fff (×2) |
successForeground |
Copy-success buttons |
FilePreview.tsx |
accentForeground ?? '#000' |
accentForeground |
Removed unnecessary fallback |
All 19,184 tests pass, lint and build clean.
Remove unused programmaticScrollRef declaration that was left over from an earlier iteration. It was declared but never read or written. Addresses PR RunMaestro#390 review feedback (Task 1). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace inline IIFE that computed isActive within JSX with a pre-computed isAutoScrollActive variable before the return statement. Eliminates unnecessary function creation per render and improves readability. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…new content When auto-scroll is paused and the user clicks resume, immediately scroll to the bottom using behavior: 'auto' (instant snap) rather than leaving the viewport at the old scroll position until new content arrives. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ffect deps filteredLogs is derived from shellLogs via activeLogs → collapsedLogs → filteredLogs, so having both in the dependency array caused the effect to double-fire on every new log message. Keep only filteredLogs.length which correctly covers both AI and terminal modes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…button rendering, and props threading Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…and palette Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
# Conflicts: # src/renderer/components/TerminalOutput.tsx # src/renderer/hooks/settings/useSettings.ts
Resolve merge conflicts in useSettings.ts (accept zustand store refactor), HistoryPanel.tsx (use imported HistoryEntryItem from History/), and TabSwitcherModal.tsx (keep theme-aware activeBg color). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Branch synced with latest main (8708e73)Merged
All conflicts resolved cleanly. Lint and 19,697 tests pass. |
|
@CodeRabbit review |
✅ Actions performedReview triggered.
|
📝 WalkthroughWalkthroughThis PR expands the theme color system with 19 new color tokens (info, success/warning/error foreground and dim variants, diff visualization colors, overlay states, interaction feedback colors, and shadows), systematically replaces hardcoded color values across 60+ component files with theme-based tokens, introduces an AI output auto-scroll feature with keyboard shortcut integration and UI controls, and updates test files to validate the new theme-driven color assignments. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes 🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Warning Review ran into problems🔥 ProblemsGit: Failed to clone repository. Please run the Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/renderer/components/ContextWarningSash.tsx (1)
128-131:⚠️ Potential issue | 🟡 MinorHardcoded
#000contradicts the PR's theming goal.The button text uses a hardcoded black color, which won't adapt to themes and contradicts this PR's objective of replacing hardcoded colors with theme tokens. Consider using a semantic foreground token (e.g.,
theme.colors.bgMainor a dedicated button-text token) to ensure proper contrast across all themes.Suggested fix
style={{ backgroundColor: buttonBgColor, - color: '#000', + color: theme.colors.bgMain, }}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/renderer/components/ContextWarningSash.tsx` around lines 128 - 131, The inline style in the ContextWarningSash component hardcodes color: '#000'; replace this with a semantic theme token instead (e.g., use the injected theme.colors.buttonText or theme.colors.text via the component's theme prop or a useTheme() hook) and remove the literal '#000'; update the style object that references buttonBgColor so the text color derives from the theme (or a dedicated button-text token) to ensure correct contrast across themes.src/renderer/components/FilePreview.tsx (1)
1313-1331:⚠️ Potential issue | 🟡 MinorAdd
accentForegroundto the effect dependencies.
The effect now readstheme.colors.accentForeground, but it isn’t in the dependency array, so theme changes that only affect the foreground won’t refresh highlights.🔧 Suggested fix
- }, [searchQuery, file?.content, isMarkdown, isImage, isCsv, theme.colors.accent]); + }, [ + searchQuery, + file?.content, + isMarkdown, + isImage, + isCsv, + theme.colors.accent, + theme.colors.accentForeground, + ]);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/renderer/components/FilePreview.tsx` around lines 1313 - 1331, The useEffect in FilePreview that highlights search matches depends on theme.colors.accentForeground but the dependency array only includes theme.colors.accent, so changes to accentForeground won't retrigger the effect; update the dependency array (the effect surrounding the match highlighting and cleanup where matchElementsRef is used) to include theme.colors.accentForeground alongside theme.colors.accent so theme foreground changes correctly refresh highlights.
🧹 Nitpick comments (8)
src/renderer/components/ContextWarningSash.tsx (3)
123-127: Missingoutline-noneclass on focusable buttons.The buttons have
tabIndex={0}but are missing theoutline-noneclass. As per coding guidelines, focusable elements should include both to ensure focus works correctly.Suggested fix
<button onClick={onSummarizeClick} onKeyDown={(e) => e.key === 'Enter' && onSummarizeClick()} tabIndex={0} - className="px-1.5 py-0.5 text-[10px] font-medium rounded transition-colors hover:opacity-90" + className="px-1.5 py-0.5 text-[10px] font-medium rounded transition-colors hover:opacity-90 outline-none"<button onClick={handleDismiss} onKeyDown={(e) => e.key === 'Enter' && handleDismiss()} tabIndex={0} - className="p-0.5 rounded hover:bg-white/10 transition-colors" + className="p-0.5 rounded hover:bg-white/10 transition-colors outline-none"Also applies to: 137-141
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/renderer/components/ContextWarningSash.tsx` around lines 123 - 127, The focusable button elements in the ContextWarningSash component (the button using onSummarizeClick and the other button around lines 137-141) are missing the required outline-none Tailwind class; update those button JSX elements to include "outline-none" in their className strings so they have tabIndex={0} and the outline-none utility applied for consistent focus styling.
151-161: UnusedslideDownanimation is dead code.The
slideDownkeyframe animation is defined but never applied to any element in this component. Consider removing it or applying it to the root div if the slide-down effect is intended.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/renderer/components/ContextWarningSash.tsx` around lines 151 - 161, The CSS keyframes named slideDown in the ContextWarningSash component are defined but never used; either remove the unused `@keyframes` slideDown block from the styled string in ContextWarningSash.tsx, or apply it to the component root (e.g., add animation: slideDown 200ms ease-out; to the root div/class used in ContextWarningSash) so the animation is actually applied; update the styled string where `@keyframes` slideDown is declared and adjust the root element styling (in the React component render for ContextWarningSash) accordingly.
141-141: Hardcoded hover color doesn't respect theme.
hover:bg-white/10is a hardcoded color that won't adapt to themes. Consider using the theme'shoverBgtoken that was added in this PR.Suggested approach
-className="p-0.5 rounded hover:bg-white/10 transition-colors" +className="p-0.5 rounded transition-colors" style={{ color: textColor }}Then add hover style via inline or use
theme.colors.hoverBgin a hover state handler.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/renderer/components/ContextWarningSash.tsx` at line 141, The hover background is hardcoded as "hover:bg-white/10" in the ContextWarningSash component; replace it with the theme token (e.g. theme.colors.hoverBg) so the hover color follows the active theme — update the className to remove "hover:bg-white/10" and instead apply the hover style using the theme token (either via inline style using useTheme() or via your existing hover state handler that reads theme.colors.hoverBg) in the ContextWarningSash render path so the hover background adapts to light/dark themes.src/renderer/components/MergeProgressModal.tsx (1)
149-159: Consider usinghoverBgtoken for hover states.The hardcoded
hover:bg-white/5won't adapt to light themes where a white overlay would be invisible. Since this PR introduces anhoverBgtoken, consider using it for consistency.Same applies to line 310 (
hover:bg-white/10).♻️ Suggested change
<button type="button" onClick={onCancel} - className="px-3 py-1.5 rounded text-xs border hover:bg-white/5 transition-colors" + className="px-3 py-1.5 rounded text-xs border transition-colors" style={{ borderColor: theme.colors.border, color: theme.colors.textMain, }} + onMouseEnter={(e) => e.currentTarget.style.backgroundColor = theme.colors.hoverBg} + onMouseLeave={(e) => e.currentTarget.style.backgroundColor = 'transparent'} >Alternatively, if keeping Tailwind hover classes is preferred for simplicity, this can be deferred to a future cleanup pass.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/renderer/components/MergeProgressModal.tsx` around lines 149 - 159, Replace the hardcoded Tailwind hover classes on the "Continue Merge" button (the JSX button using onClick={onCancel} in MergeProgressModal.tsx) with the new hoverBg token so hover styles adapt to light/dark themes; specifically, remove or replace the "hover:bg-white/5" (and similarly the "hover:bg-white/10" usage noted elsewhere) and apply the component/theme hoverBg token via inline style or class composition that references theme.colors.hoverBg to ensure consistent hover appearance across themes.src/renderer/components/PlaygroundPanel.tsx (1)
636-648: Consider usingaccentForegroundfor remaining selected-state buttons.This PR updated several buttons to use
theme.colors.accentForegroundfor text on accent backgrounds (lines 761, 832, 1184, 1358), but similar patterns still use hardcoded#fff:
- Line 641: Badge level buttons
- Line 873: Origin grid buttons
- Line 997: Shape toggle buttons
- Line 1482: Easing option buttons
For consistency and full WCAG compliance across all themes, consider updating these as well.
♻️ Example fix for badge level buttons
style={{ backgroundColor: mockAutoRunStats.currentBadgeLevel === level ? theme.colors.accent : theme.colors.bgMain, color: mockAutoRunStats.currentBadgeLevel === level - ? '#fff' + ? theme.colors.accentForeground : theme.colors.textMain, }}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/renderer/components/PlaygroundPanel.tsx` around lines 636 - 648, Selected-state button text uses a hardcoded '#fff' in several places (e.g., badge level buttons using mockAutoRunStats.currentBadgeLevel) which breaks consistency with the newer theme usage; replace those hardcoded values with theme.colors.accentForeground so selected buttons use the theme-provided foreground color. Update the badge level buttons (where mockAutoRunStats.currentBadgeLevel is compared to level) and the other similar button groups mentioned (origin grid buttons, shape toggle buttons, easing option buttons) to use theme.colors.accentForeground for the color when in the selected state instead of '#fff'. Ensure each conditional that sets color for the selected state mirrors the pattern used elsewhere (using theme.colors.accentForeground).src/renderer/components/TerminalOutput.tsx (1)
1747-1772: Add tabIndex for keyboard accessibility on auto-scroll button.The auto-scroll toggle button is missing
tabIndexattribute. Per coding guidelines, interactive elements should have explicit tabIndex to ensure focus works correctly.♿ Proposed fix for accessibility
{session.inputMode === 'ai' && setAutoScrollAiMode && ( <button onClick={() => { if (autoScrollPaused) { // Resume: clear pause and snap to bottom immediately setAutoScrollPaused(false); if (scrollContainerRef.current) { scrollContainerRef.current.scrollTo({ top: scrollContainerRef.current.scrollHeight, behavior: 'auto', }); } } else { setAutoScrollAiMode(!autoScrollAiMode); } }} className="absolute bottom-4 left-4 p-2 rounded-full shadow-lg transition-all hover:scale-105 z-20" + tabIndex={0} style={{As per coding guidelines: "Add tabIndex={0} or tabIndex={-1} and outline-none class to ensure focus works correctly."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/renderer/components/TerminalOutput.tsx` around lines 1747 - 1772, The auto-scroll toggle <button> lacks an explicit tabIndex which breaks keyboard focus; update the button (the element that uses setAutoScrollAiMode, autoScrollPaused, autoScrollAiMode, isAutoScrollActive, and scrollContainerRef) to include tabIndex={0} and add the 'outline-none' CSS class (or the project-equivalent focus style) to its className so it is keyboard-focusable and matches the coding guideline for interactive elements.src/renderer/components/AutoRunExpandedModal.tsx (1)
366-381: Consider usingtheme.colors.errorForegroundfor the Stop button text.The Stop button (line 369) still uses hardcoded
'white'for text color when not stopping, while other components in this PR usetheme.colors.errorForegroundontheme.colors.errorbackgrounds for consistency. This may be intentional for visual distinction, but consider aligning with the semantic token pattern.♻️ Suggested change
style={{ backgroundColor: isStopping ? theme.colors.warning : theme.colors.error, - color: isStopping ? theme.colors.bgMain : 'white', + color: isStopping ? theme.colors.warningForeground : theme.colors.errorForeground, border: `1px solid ${isStopping ? theme.colors.warning : theme.colors.error}`,🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/renderer/components/AutoRunExpandedModal.tsx` around lines 366 - 381, The Stop button in AutoRunExpandedModal still uses hardcoded 'white' for its text color; change the inline style on the button (the object where color is set) to use theme.colors.errorForeground when not stopping (i.e., color: isStopping ? theme.colors.bgMain : theme.colors.errorForeground) so the text uses the semantic foreground token consistently with theme.colors.error; update the same ternary usage near the title/pointerEvents/Loader render context if any related hardcoded color is present.src/renderer/components/QueuedItemsList.tsx (1)
234-273: Theme token updates look good, but modal should register with layer stack.The theme changes are correct:
theme.colors.overlayfor the backdroptheme.colors.errorForegroundpaired withtheme.colors.errorfor the Remove buttonHowever, this confirmation modal handles Escape locally (lines 74-77) instead of registering with the layer stack. Based on learnings: "Register modals with layer stack instead of handling Escape locally. Check that modal priority is set correctly in constants/modalPriorities.ts."
,
♻️ Suggested refactor to use layer stack
+import { useLayerStack } from '../contexts/LayerStackContext'; +import { MODAL_PRIORITIES } from '../constants/modalPriorities'; export const QueuedItemsList = memo( ({ executionQueue, theme, onRemoveQueuedItem, onReorderItems, activeTabId, }: QueuedItemsListProps) => { + const { registerLayer, unregisterLayer } = useLayerStack(); + const layerIdRef = useRef<string>(); + + // Register with layer stack when confirmation modal is open + useEffect(() => { + if (queueRemoveConfirmId) { + const id = registerLayer({ + type: 'modal', + priority: MODAL_PRIORITIES.CONFIRMATION, // Add to modalPriorities.ts if needed + blocksLowerLayers: true, + capturesFocus: true, + onEscape: () => setQueueRemoveConfirmId(null), + }); + layerIdRef.current = id; + return () => { + if (layerIdRef.current) { + unregisterLayer(layerIdRef.current); + } + }; + } + }, [queueRemoveConfirmId, registerLayer, unregisterLayer]);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/renderer/components/QueuedItemsList.tsx` around lines 234 - 273, The modal currently handles Escape locally via handleModalKeyDown and uses queueRemoveConfirmId/state to close itself; instead register this confirmation modal with the app's layer stack so Escape and stacking are managed centrally. Replace the local onKeyDown handling/logic by calling the layer stack registration API (use the same pattern as other components that register modals), provide the correct priority from constants/modalPriorities.ts, and ensure unregistering calls setQueueRemoveConfirmId(null) (or invokes handleConfirmRemove when appropriate) on layer pop; keep existing visual changes (theme.colors.overlay, theme.colors.errorForeground) but remove local Escape handling in QueuedItemsList and rely on the layer stack callbacks to close the modal.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/__tests__/renderer/components/auto-scroll.test.tsx`:
- Around line 67-86: defaultTheme used in the tests is missing the new color
tokens referenced by TerminalOutput (warningForeground and errorForeground),
causing undefined styles; update the defaultTheme constant in the test to
include warningForeground and errorForeground within the colors object (matching
existing token naming like success/warning/error) so tests that render
TerminalOutput have those values available.
---
Outside diff comments:
In `@src/renderer/components/ContextWarningSash.tsx`:
- Around line 128-131: The inline style in the ContextWarningSash component
hardcodes color: '#000'; replace this with a semantic theme token instead (e.g.,
use the injected theme.colors.buttonText or theme.colors.text via the
component's theme prop or a useTheme() hook) and remove the literal '#000';
update the style object that references buttonBgColor so the text color derives
from the theme (or a dedicated button-text token) to ensure correct contrast
across themes.
In `@src/renderer/components/FilePreview.tsx`:
- Around line 1313-1331: The useEffect in FilePreview that highlights search
matches depends on theme.colors.accentForeground but the dependency array only
includes theme.colors.accent, so changes to accentForeground won't retrigger the
effect; update the dependency array (the effect surrounding the match
highlighting and cleanup where matchElementsRef is used) to include
theme.colors.accentForeground alongside theme.colors.accent so theme foreground
changes correctly refresh highlights.
---
Nitpick comments:
In `@src/renderer/components/AutoRunExpandedModal.tsx`:
- Around line 366-381: The Stop button in AutoRunExpandedModal still uses
hardcoded 'white' for its text color; change the inline style on the button (the
object where color is set) to use theme.colors.errorForeground when not stopping
(i.e., color: isStopping ? theme.colors.bgMain : theme.colors.errorForeground)
so the text uses the semantic foreground token consistently with
theme.colors.error; update the same ternary usage near the
title/pointerEvents/Loader render context if any related hardcoded color is
present.
In `@src/renderer/components/ContextWarningSash.tsx`:
- Around line 123-127: The focusable button elements in the ContextWarningSash
component (the button using onSummarizeClick and the other button around lines
137-141) are missing the required outline-none Tailwind class; update those
button JSX elements to include "outline-none" in their className strings so they
have tabIndex={0} and the outline-none utility applied for consistent focus
styling.
- Around line 151-161: The CSS keyframes named slideDown in the
ContextWarningSash component are defined but never used; either remove the
unused `@keyframes` slideDown block from the styled string in
ContextWarningSash.tsx, or apply it to the component root (e.g., add animation:
slideDown 200ms ease-out; to the root div/class used in ContextWarningSash) so
the animation is actually applied; update the styled string where `@keyframes`
slideDown is declared and adjust the root element styling (in the React
component render for ContextWarningSash) accordingly.
- Line 141: The hover background is hardcoded as "hover:bg-white/10" in the
ContextWarningSash component; replace it with the theme token (e.g.
theme.colors.hoverBg) so the hover color follows the active theme — update the
className to remove "hover:bg-white/10" and instead apply the hover style using
the theme token (either via inline style using useTheme() or via your existing
hover state handler that reads theme.colors.hoverBg) in the ContextWarningSash
render path so the hover background adapts to light/dark themes.
In `@src/renderer/components/MergeProgressModal.tsx`:
- Around line 149-159: Replace the hardcoded Tailwind hover classes on the
"Continue Merge" button (the JSX button using onClick={onCancel} in
MergeProgressModal.tsx) with the new hoverBg token so hover styles adapt to
light/dark themes; specifically, remove or replace the "hover:bg-white/5" (and
similarly the "hover:bg-white/10" usage noted elsewhere) and apply the
component/theme hoverBg token via inline style or class composition that
references theme.colors.hoverBg to ensure consistent hover appearance across
themes.
In `@src/renderer/components/PlaygroundPanel.tsx`:
- Around line 636-648: Selected-state button text uses a hardcoded '#fff' in
several places (e.g., badge level buttons using
mockAutoRunStats.currentBadgeLevel) which breaks consistency with the newer
theme usage; replace those hardcoded values with theme.colors.accentForeground
so selected buttons use the theme-provided foreground color. Update the badge
level buttons (where mockAutoRunStats.currentBadgeLevel is compared to level)
and the other similar button groups mentioned (origin grid buttons, shape toggle
buttons, easing option buttons) to use theme.colors.accentForeground for the
color when in the selected state instead of '#fff'. Ensure each conditional that
sets color for the selected state mirrors the pattern used elsewhere (using
theme.colors.accentForeground).
In `@src/renderer/components/QueuedItemsList.tsx`:
- Around line 234-273: The modal currently handles Escape locally via
handleModalKeyDown and uses queueRemoveConfirmId/state to close itself; instead
register this confirmation modal with the app's layer stack so Escape and
stacking are managed centrally. Replace the local onKeyDown handling/logic by
calling the layer stack registration API (use the same pattern as other
components that register modals), provide the correct priority from
constants/modalPriorities.ts, and ensure unregistering calls
setQueueRemoveConfirmId(null) (or invokes handleConfirmRemove when appropriate)
on layer pop; keep existing visual changes (theme.colors.overlay,
theme.colors.errorForeground) but remove local Escape handling in
QueuedItemsList and rely on the layer stack callbacks to close the modal.
In `@src/renderer/components/TerminalOutput.tsx`:
- Around line 1747-1772: The auto-scroll toggle <button> lacks an explicit
tabIndex which breaks keyboard focus; update the button (the element that uses
setAutoScrollAiMode, autoScrollPaused, autoScrollAiMode, isAutoScrollActive, and
scrollContainerRef) to include tabIndex={0} and add the 'outline-none' CSS class
(or the project-equivalent focus style) to its className so it is
keyboard-focusable and matches the coding guideline for interactive elements.
| // Default theme for testing | ||
| const defaultTheme: Theme = { | ||
| id: 'test-theme' as any, | ||
| name: 'Test Theme', | ||
| mode: 'dark', | ||
| colors: { | ||
| bgMain: '#1a1a2e', | ||
| bgSidebar: '#16213e', | ||
| bgActivity: '#0f3460', | ||
| textMain: '#e94560', | ||
| textDim: '#a0a0a0', | ||
| accent: '#e94560', | ||
| accentDim: '#b83b5e', | ||
| accentForeground: '#ffffff', | ||
| border: '#2a2a4e', | ||
| success: '#00ff88', | ||
| warning: '#ffcc00', | ||
| error: '#ff4444', | ||
| }, | ||
| }; |
There was a problem hiding this comment.
Test theme is missing new color tokens.
The defaultTheme only includes 13 color tokens, but TerminalOutput now uses warningForeground and errorForeground (Lines 190, 225, 424, 849 in TerminalOutput.tsx). This could cause runtime errors or undefined style values in tests that exercise those code paths.
🛠️ Proposed fix to add missing tokens
const defaultTheme: Theme = {
id: 'test-theme' as any,
name: 'Test Theme',
mode: 'dark',
colors: {
bgMain: '#1a1a2e',
bgSidebar: '#16213e',
bgActivity: '#0f3460',
textMain: '#e94560',
textDim: '#a0a0a0',
accent: '#e94560',
accentDim: '#b83b5e',
accentForeground: '#ffffff',
border: '#2a2a4e',
success: '#00ff88',
warning: '#ffcc00',
error: '#ff4444',
+ successForeground: '#000000',
+ warningForeground: '#000000',
+ errorForeground: '#ffffff',
+ shadow: 'rgba(0,0,0,0.3)',
},
};📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // Default theme for testing | |
| const defaultTheme: Theme = { | |
| id: 'test-theme' as any, | |
| name: 'Test Theme', | |
| mode: 'dark', | |
| colors: { | |
| bgMain: '#1a1a2e', | |
| bgSidebar: '#16213e', | |
| bgActivity: '#0f3460', | |
| textMain: '#e94560', | |
| textDim: '#a0a0a0', | |
| accent: '#e94560', | |
| accentDim: '#b83b5e', | |
| accentForeground: '#ffffff', | |
| border: '#2a2a4e', | |
| success: '#00ff88', | |
| warning: '#ffcc00', | |
| error: '#ff4444', | |
| }, | |
| }; | |
| // Default theme for testing | |
| const defaultTheme: Theme = { | |
| id: 'test-theme' as any, | |
| name: 'Test Theme', | |
| mode: 'dark', | |
| colors: { | |
| bgMain: '#1a1a2e', | |
| bgSidebar: '#16213e', | |
| bgActivity: '#0f3460', | |
| textMain: '#e94560', | |
| textDim: '#a0a0a0', | |
| accent: '#e94560', | |
| accentDim: '#b83b5e', | |
| accentForeground: '#ffffff', | |
| border: '#2a2a4e', | |
| success: '#00ff88', | |
| warning: '#ffcc00', | |
| error: '#ff4444', | |
| successForeground: '#000000', | |
| warningForeground: '#000000', | |
| errorForeground: '#ffffff', | |
| shadow: 'rgba(0,0,0,0.3)', | |
| }, | |
| }; |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/__tests__/renderer/components/auto-scroll.test.tsx` around lines 67 - 86,
defaultTheme used in the tests is missing the new color tokens referenced by
TerminalOutput (warningForeground and errorForeground), causing undefined
styles; update the defaultTheme constant in the test to include
warningForeground and errorForeground within the colors object (matching
existing token naming like success/warning/error) so tests that render
TerminalOutput have those values available.
Summary
New tokens added to
ThemeColors:successForeground,warningForeground,errorForegroundsuccessDim,warningDim,errorDim,infoDiminfodiffAddition,diffAdditionBg,diffDeletion,diffDeletionBgoverlay,overlayHeavyhoverBg,activeBgshadowDre Synth color fixes:
bgActivity#150530#1a0838success#00ffcc(same as accent)#33ff99(green)warning#ff2a6d(same as error)#ff9944(orange)Files changed: 27 files, 5 commits
Test plan
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Improvements