Skip to content

Commit 7c0bbe2

Browse files
committed
Consolidate ChatTheme properties to semantic essentials
Reduced theme properties from 35 → 24 by removing redundant properties: Removed and replaced with semantics: - aiText, userText → foreground (unified text color) - aiTimestamp, userTimestamp → muted (timestamps are subdued) - agentPrefix, agentName → success (green elements) - agentContent, agentToggleHeaderText → foreground (default text) - logo → foreground - inputPlaceholder → muted - cursor → primary - link → info - linkActive → success - shimmer → info - accentBg, accentText → removed (redundant with primary) Kept essential context colors: - aiLine, userLine (visual differentiation) - Agent backgrounds (specific UI states) - Input bg/fg (component-specific) - Mode toggles (distinct UI elements) Benefits: - Easier to create custom themes (fewer properties to set) - More intuitive (use semantic colors for most things) - Cleaner theme definitions (less duplication) - Better alignment with design system best practices All typechecks pass, all 50 tests pass.
1 parent 09f0bef commit 7c0bbe2

17 files changed

+68
-161
lines changed

cli/src/chat.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ export const App = ({
227227
{
228228
type: 'text',
229229
content: '\n\n' + logoBlock,
230-
color: theme.logo,
230+
color: theme.foreground,
231231
},
232232
]
233233

@@ -1163,7 +1163,7 @@ export const App = ({
11631163
return output
11641164
}
11651165

1166-
const messageAiTextColor = theme.aiText
1166+
const messageAiTextColor = theme.foreground
11671167
const statusSecondaryColor = theme.secondary
11681168

11691169
return (

cli/src/components/__tests__/message-block.completion.test.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ const basePalette = createMarkdownPalette(theme)
1414

1515
const palette: MarkdownPalette = {
1616
...basePalette,
17-
inlineCodeFg: theme.aiText,
18-
codeTextFg: theme.aiText,
17+
inlineCodeFg: theme.foreground,
18+
codeTextFg: theme.foreground,
1919
}
2020

2121
const baseProps = {
@@ -35,8 +35,8 @@ const baseProps = {
3535
elapsedSeconds: 0,
3636
startTime: null,
3737
},
38-
textColor: theme.aiText,
39-
timestampColor: theme.aiTimestamp,
38+
textColor: theme.foreground,
39+
timestampColor: theme.muted,
4040
markdownOptions: {
4141
codeBlockWidth: 72,
4242
palette,

cli/src/components/__tests__/message-block.streaming.test.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ const basePalette = createMarkdownPalette(theme)
1414

1515
const palette: MarkdownPalette = {
1616
...basePalette,
17-
inlineCodeFg: theme.aiText,
18-
codeTextFg: theme.aiText,
17+
inlineCodeFg: theme.foreground,
18+
codeTextFg: theme.foreground,
1919
}
2020

2121
const baseProps = {
@@ -28,8 +28,8 @@ const baseProps = {
2828
timestamp: '12:00',
2929
completionTime: undefined,
3030
credits: undefined,
31-
textColor: theme.aiText,
32-
timestampColor: theme.aiTimestamp,
31+
textColor: theme.foreground,
32+
timestampColor: theme.muted,
3333
markdownOptions: {
3434
codeBlockWidth: 72,
3535
palette,

cli/src/components/agent-branch-item.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ export const AgentBranchItem = ({
124124
if (isTextRenderable(value)) {
125125
return (
126126
<text
127-
fg={theme.agentContent}
127+
fg={theme.foreground}
128128
key="expanded-text"
129129
attributes={getAttributes()}
130130
>
@@ -205,9 +205,9 @@ export const AgentBranchItem = ({
205205
width: '100%',
206206
}}
207207
>
208-
<text fg={theme.agentToggleHeaderText}>Prompt</text>
208+
<text fg={theme.foreground}>Prompt</text>
209209
<text
210-
fg={theme.agentContent}
210+
fg={theme.foreground}
211211
style={{ wrapMode: 'word' }}
212212
attributes={getAttributes()}
213213
>
@@ -267,7 +267,7 @@ export const AgentBranchItem = ({
267267
}}
268268
>
269269
<text
270-
fg={isStreaming ? theme.agentContent : theme.muted}
270+
fg={isStreaming ? theme.foreground : theme.muted}
271271
attributes={getAttributes(TextAttributes.ITALIC)}
272272
>
273273
{isStreaming ? streamingPreview : finishedPreview}
@@ -293,19 +293,19 @@ export const AgentBranchItem = ({
293293
marginBottom: content ? 1 : 0,
294294
}}
295295
>
296-
<text fg={theme.agentToggleHeaderText}>
296+
<text fg={theme.foreground}>
297297
Prompt
298298
</text>
299299
<text
300-
fg={theme.agentContent}
300+
fg={theme.foreground}
301301
style={{ wrapMode: 'word' }}
302302
attributes={getAttributes()}
303303
>
304304
{prompt}
305305
</text>
306306
{content && (
307307
<text
308-
fg={theme.agentToggleHeaderText}
308+
fg={theme.foreground}
309309
style={{ marginTop: 1 }}
310310
>
311311
Response

cli/src/components/login-modal.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ export const LoginModal = ({
249249

250250
// Use custom hook for sheen animation
251251
const { applySheenToChar } = useSheenAnimation({
252-
logoColor: theme.logo,
252+
logoColor: theme.foreground,
253253
terminalWidth: renderer?.width,
254254
sheenPosition,
255255
setSheenPosition,
@@ -432,8 +432,8 @@ export const LoginModal = ({
432432
text={loginUrl}
433433
maxWidth={maxUrlWidth}
434434
formatLines={formatLoginUrlLines}
435-
color={hasClickedLink ? theme.linkActive : theme.link}
436-
activeColor={theme.linkActive}
435+
color={hasClickedLink ? theme.success : theme.info}
436+
activeColor={theme.success}
437437
underlineOnHover={true}
438438
isActive={justCopied}
439439
onActivate={handleActivateLoginUrl}

cli/src/components/message-block.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ export const MessageBlock = ({
7272
registerAgentRef,
7373
}: MessageBlockProps): ReactNode => {
7474
const theme = useTheme()
75-
const resolvedTextColor = textColor ?? theme.aiText
75+
const resolvedTextColor = textColor ?? theme.foreground
7676

7777
// Get elapsed time from timer for streaming AI messages
7878
const elapsedSeconds = timer.elapsedSeconds
@@ -140,8 +140,8 @@ export const MessageBlock = ({
140140
codeBlockWidth: Math.max(10, availableWidth - 12 - indentationOffset),
141141
palette: {
142142
...markdownPalette,
143-
inlineCodeFg: theme.agentContent,
144-
codeTextFg: theme.agentContent,
143+
inlineCodeFg: theme.foreground,
144+
codeTextFg: theme.foreground,
145145
},
146146
}
147147
}
@@ -235,7 +235,7 @@ export const MessageBlock = ({
235235
? null
236236
: (
237237
<text
238-
fg={theme.agentContent}
238+
fg={theme.foreground}
239239
style={{ wrapMode: 'word' }}
240240
attributes={
241241
theme.messageTextAttributes && theme.messageTextAttributes !== 0
@@ -399,7 +399,7 @@ export const MessageBlock = ({
399399
) => {
400400
const identifier = formatIdentifier(agent)
401401
return (
402-
<text key={`agent-${idx}`} style={{ wrapMode: 'word', fg: theme.agentContent }}>
402+
<text key={`agent-${idx}`} style={{ wrapMode: 'word', fg: theme.foreground }}>
403403
{` • ${identifier}`}
404404
</text>
405405
)
@@ -481,7 +481,7 @@ export const MessageBlock = ({
481481
typeof (nestedBlock as any).color === 'string'
482482
? ((nestedBlock as any).color as string)
483483
: undefined
484-
const nestedTextColor = explicitColor ?? theme.agentContent
484+
const nestedTextColor = explicitColor ?? theme.foreground
485485
nodes.push(
486486
<text
487487
key={renderKey}
@@ -513,7 +513,7 @@ export const MessageBlock = ({
513513
}}
514514
>
515515
{nestedBlock.render({
516-
textColor: theme.agentContent,
516+
textColor: theme.foreground,
517517
theme,
518518
})}
519519
</box>,

cli/src/components/multiline-input.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -575,7 +575,7 @@ export const MultilineInput = forwardRef<
575575
])
576576

577577
const inputColor = isPlaceholder
578-
? theme.inputPlaceholder
578+
? theme.muted
579579
: focused
580580
? theme.inputFocusedFg
581581
: theme.inputFg
@@ -591,7 +591,7 @@ export const MultilineInput = forwardRef<
591591
textStyle.attributes = textAttributes
592592
}
593593

594-
const cursorFg = theme.cursor
594+
const cursorFg = theme.primary
595595

596596
return (
597597
<scrollbox

cli/src/components/shimmer-text.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,8 @@ export const ShimmerText = ({
182182
}
183183
// Use theme shimmer color as default
184184
const paletteSize = Math.max(8, Math.min(20, Math.ceil(numChars * 1.5)))
185-
return generatePaletteFromPrimary(theme.shimmer, paletteSize, theme.muted)
186-
}, [colors, primaryColor, numChars, theme.shimmer, theme.muted])
185+
return generatePaletteFromPrimary(theme.info, paletteSize, theme.muted)
186+
}, [colors, primaryColor, numChars, theme.info, theme.muted])
187187

188188
const generateAttributes = (length: number): number[] => {
189189
const attributes: number[] = []

cli/src/components/suggestion-menu.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ export const SuggestionMenu = ({
7575
const textColor = isSelected ? theme.primary : theme.inputFg
7676
const descriptionColor = isSelected
7777
? theme.primary
78-
: theme.userTimestamp
78+
: theme.muted
7979
return (
8080
<box
8181
key={item.id}
@@ -97,7 +97,7 @@ export const SuggestionMenu = ({
9797
wrapMode: 'none',
9898
}}
9999
>
100-
<span fg={theme.agentPrefix}>{effectivePrefix}</span>
100+
<span fg={theme.success}>{effectivePrefix}</span>
101101
<span>{item.label}</span>
102102
<span>{padding}</span>
103103
<span fg={descriptionColor}>

cli/src/components/terminal-link.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ export const TerminalLink: React.FC<TerminalLinkProps> = ({
3636
const theme = useTheme()
3737

3838
// Use theme colors as defaults if not provided
39-
const linkColor = color ?? theme.link
40-
const linkActiveColor = activeColor ?? theme.linkActive
39+
const linkColor = color ?? theme.info
40+
const linkActiveColor = activeColor ?? theme.success
4141
const [isHovered, setIsHovered] = useState(false)
4242

4343
const displayLines = useMemo(() => {

0 commit comments

Comments
 (0)