Skip to content

Commit cff6819

Browse files
committed
Revamp CLI toggle theming and raised pill buttons
1 parent 80a0325 commit cff6819

14 files changed

+606
-959
lines changed

cli/src/chat.tsx

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import { useMessageRenderer } from './hooks/use-message-renderer'
2222
import { useChatScrollbox } from './hooks/use-scroll-management'
2323
import { useSendMessage } from './hooks/use-send-message'
2424
import { useSuggestionEngine } from './hooks/use-suggestion-engine'
25-
import { useSystemThemeDetector } from './hooks/use-system-theme-detector'
2625
import { useChatStore } from './state/chat-store'
2726
import { flushAnalytics } from './utils/analytics'
2827
import { getUserCredentials } from './utils/auth'
@@ -32,7 +31,7 @@ import { formatQueuedPreview } from './utils/helpers'
3231
import { loadLocalAgents } from './utils/local-agent-registry'
3332
import { logger } from './utils/logger'
3433
import { buildMessageTree } from './utils/message-tree-utils'
35-
import { chatThemes, createMarkdownPalette } from './utils/theme-system'
34+
import { chatTheme, createMarkdownPalette } from './utils/theme-system'
3635

3736
import type { User } from './utils/auth'
3837
import type { ToolName } from '@codebuff/sdk'
@@ -55,7 +54,7 @@ type AgentMessage = {
5554
}
5655

5756
export type ContentBlock =
58-
| { type: 'text'; content: string }
57+
| { type: 'text'; content: string; color?: string }
5958
| {
6059
type: 'tool'
6160
toolCallId: string
@@ -127,8 +126,7 @@ export const App = ({
127126
const terminalWidth = resolvedTerminalWidth
128127
const separatorWidth = Math.max(1, Math.floor(terminalWidth) - 2)
129128

130-
const themeName = useSystemThemeDetector()
131-
const theme = chatThemes[themeName]
129+
const theme = chatTheme
132130
const markdownPalette = useMemo(() => createMarkdownPalette(theme), [theme])
133131

134132
const [exitWarning, setExitWarning] = useState<string | null>(null)
@@ -205,13 +203,15 @@ export const App = ({
205203
{
206204
type: 'text',
207205
content: '\n\n' + LOGO_BLOCK,
206+
color: theme.agentToggleExpandedBg,
208207
},
209208
]
210209

211210
if (greeting) {
212211
blocks.push({
213212
type: 'text',
214213
content: greeting,
214+
color: theme.agentResponseCount,
215215
})
216216
}
217217

@@ -220,6 +220,7 @@ export const App = ({
220220
type: 'text',
221221
content:
222222
'Codebuff can read and write files in this repository, and run terminal commands to help you build.',
223+
color: theme.agentResponseCount,
223224
},
224225
{
225226
type: 'agent-list',
@@ -241,7 +242,7 @@ export const App = ({
241242
setCollapsedAgents((prev) => new Set([...prev, agentListId]))
242243
setMessages([initialMessage])
243244
}
244-
}, [loadedAgentsData]) // Only run when loadedAgentsData changes
245+
}, [loadedAgentsData, theme]) // Only run when loadedAgentsData changes
245246

246247
const {
247248
inputValue,
@@ -373,10 +374,6 @@ export const App = ({
373374
activeSubagentsRef.current = activeSubagents
374375
}, [activeSubagents])
375376

376-
useEffect(() => {
377-
renderer?.setBackgroundColor(theme.background)
378-
}, [renderer, theme.background])
379-
380377
useEffect(() => {
381378
if (exitArmedRef.current && inputValue.length > 0) {
382379
exitArmedRef.current = false
@@ -872,7 +869,10 @@ export const App = ({
872869

873870
const virtualizationNotice =
874871
shouldVirtualize && hiddenTopLevelCount > 0 ? (
875-
<text key="virtualization-notice" wrap={false} style={{ width: '100%' }}>
872+
<text
873+
key="virtualization-notice"
874+
style={{ width: '100%', wrapMode: 'none' }}
875+
>
876876
<span fg={theme.statusSecondary}>
877877
Showing latest {virtualTopLevelMessages.length} of{' '}
878878
{topLevelMessages.length} messages. Scroll up to load more.
@@ -910,7 +910,7 @@ export const App = ({
910910
paddingRight: 0,
911911
paddingTop: 0,
912912
paddingBottom: 0,
913-
backgroundColor: theme.panelBg,
913+
backgroundColor: 'transparent',
914914
}}
915915
>
916916
<scrollbox
@@ -928,20 +928,20 @@ export const App = ({
928928
gap: 0,
929929
flexDirection: 'column',
930930
shouldFill: true,
931-
backgroundColor: theme.panelBg,
931+
backgroundColor: 'transparent',
932932
},
933933
wrapperOptions: {
934934
flexGrow: 1,
935935
border: false,
936936
shouldFill: true,
937-
backgroundColor: theme.panelBg,
937+
backgroundColor: 'transparent',
938938
},
939939
contentOptions: {
940940
flexDirection: 'column',
941941
gap: 0,
942942
shouldFill: true,
943943
justifyContent: 'flex-end',
944-
backgroundColor: theme.panelBg,
944+
backgroundColor: 'transparent',
945945
},
946946
}}
947947
>
@@ -955,7 +955,7 @@ export const App = ({
955955
flexShrink: 0,
956956
paddingLeft: 0,
957957
paddingRight: 0,
958-
backgroundColor: theme.panelBg,
958+
backgroundColor: 'transparent',
959959
}}
960960
>
961961
{shouldShowStatusLine && (
@@ -966,15 +966,15 @@ export const App = ({
966966
width: '100%',
967967
}}
968968
>
969-
<text wrap={false}>
969+
<text style={{ wrapMode: 'none' }}>
970970
{hasStatus ? statusIndicatorNode : null}
971971
{hasStatus && (exitWarning || shouldShowQueuePreview) ? ' ' : ''}
972972
{exitWarning ? (
973973
<span fg={theme.statusSecondary}>{exitWarning}</span>
974974
) : null}
975975
{exitWarning && shouldShowQueuePreview ? ' ' : ''}
976976
{shouldShowQueuePreview ? (
977-
<span fg={theme.statusSecondary} bg={theme.inputFocusedBg}>
977+
<span fg={theme.statusSecondary}>
978978
{' '}
979979
{formatQueuedPreview(
980980
queuedMessages,
Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { ChatTheme } from '../utils/theme-system'
2+
import { RaisedPill } from './raised-pill'
23

34
export const AgentModeToggle = ({
45
mode,
@@ -10,25 +11,18 @@ export const AgentModeToggle = ({
1011
onToggle: () => void
1112
}) => {
1213
const isFast = mode === 'FAST'
13-
14-
const bgColor = isFast ? '#0a6515' : '#ac1626'
15-
const textColor = '#ffffff'
14+
const frameColor = isFast
15+
? theme.agentToggleHeaderBg
16+
: theme.agentToggleExpandedBg
17+
const textColor = frameColor
1618
const label = isFast ? 'FAST' : '💪 MAX'
1719

1820
return (
19-
<box
20-
style={{
21-
flexDirection: 'row',
22-
alignItems: 'center',
23-
backgroundColor: bgColor,
24-
paddingLeft: isFast ? 2 : 1,
25-
paddingRight: isFast ? 2 : 1,
26-
}}
27-
onMouseDown={onToggle}
28-
>
29-
<text wrap={false}>
30-
<span fg={textColor}>{label}</span>
31-
</text>
32-
</box>
21+
<RaisedPill
22+
segments={[{ text: label, fg: textColor }]}
23+
frameColor={frameColor}
24+
textColor={textColor}
25+
onPress={onToggle}
26+
/>
3327
)
3428
}

cli/src/components/branch-item.tsx

Lines changed: 36 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ const borderCharsWithoutVertical: BorderCharacters = {
1616
}
1717

1818
import type { ChatTheme } from '../utils/theme-system'
19+
import { RaisedPill } from './raised-pill'
1920

2021
interface BranchItemProps {
2122
name: string
@@ -45,16 +46,17 @@ export const BranchItem = ({
4546
onToggle,
4647
}: BranchItemProps) => {
4748
const cornerColor = theme.agentPrefix
48-
49-
const toggleBackground = isStreaming
50-
? theme.agentToggleHeaderBg
51-
: isCollapsed
52-
? theme.agentResponseCount
53-
: theme.agentPrefix
54-
const toggleTextColor =
55-
(isStreaming ? theme.agentToggleHeaderText : theme.agentToggleText) ??
56-
theme.agentToggleText
49+
const isExpanded = !isCollapsed
50+
const toggleFrameColor = isExpanded
51+
? theme.agentToggleExpandedBg
52+
: theme.agentToggleHeaderBg
53+
const toggleIconColor = isStreaming
54+
? theme.statusAccent
55+
: toggleFrameColor
56+
const toggleLabelColor = toggleFrameColor
5757
const toggleLabel = `${isCollapsed ? '▸' : '▾'} `
58+
const collapseButtonFrame = theme.agentToggleExpandedBg
59+
const collapseButtonText = collapseButtonFrame
5860

5961
const isTextRenderable = (value: ReactNode): boolean => {
6062
if (value === null || value === undefined || typeof value === 'boolean') {
@@ -102,7 +104,7 @@ export const BranchItem = ({
102104

103105
if (isTextRenderable(value)) {
104106
return (
105-
<text wrap fg={theme.agentText} key="expanded-text">
107+
<text fg={theme.agentText} key="expanded-text">
106108
{value}
107109
</text>
108110
)
@@ -152,28 +154,24 @@ export const BranchItem = ({
152154
}}
153155
>
154156
<box style={{ flexDirection: 'column', gap: 0 }}>
155-
<box
156-
style={{
157-
flexDirection: 'row',
158-
alignSelf: 'flex-start',
159-
backgroundColor: toggleBackground,
160-
paddingLeft: 1,
161-
paddingRight: 1,
162-
}}
163-
onMouseDown={onToggle}
164-
>
165-
<text wrap>
166-
<span fg={toggleTextColor}>{toggleLabel}</span>
167-
<span fg={toggleTextColor} attributes={TextAttributes.BOLD}>
168-
{name}
169-
</span>
170-
</text>
171-
</box>
157+
<RaisedPill
158+
segments={[
159+
{ text: toggleLabel, fg: toggleIconColor },
160+
{
161+
text: name,
162+
fg: toggleLabelColor,
163+
attr: isExpanded ? TextAttributes.BOLD : undefined,
164+
},
165+
]}
166+
frameColor={toggleFrameColor}
167+
textColor={toggleLabelColor}
168+
onPress={onToggle}
169+
style={{ alignSelf: 'flex-start' }}
170+
/>
172171
<box style={{ flexShrink: 1, marginBottom: 0 }}>
173172
{isStreaming && isCollapsed && streamingPreview && (
174173
<text
175174
key="streaming-preview"
176-
wrap
177175
fg={theme.agentText}
178176
attributes={TextAttributes.ITALIC}
179177
>
@@ -183,7 +181,6 @@ export const BranchItem = ({
183181
{!isStreaming && isCollapsed && finishedPreview && (
184182
<text
185183
key="finished-preview"
186-
wrap
187184
fg={theme.agentResponseCount}
188185
attributes={TextAttributes.ITALIC}
189186
>
@@ -209,38 +206,22 @@ export const BranchItem = ({
209206
>
210207
{prompt && (
211208
<box style={{ flexDirection: 'column', gap: 0 }}>
212-
<text wrap fg={theme.agentToggleHeaderText}>
213-
Prompt
214-
</text>
215-
<text wrap fg={theme.agentText}>
216-
{prompt}
217-
</text>
209+
<text fg={theme.agentToggleHeaderText}>Prompt</text>
210+
<text fg={theme.agentText}>{prompt}</text>
218211
<text> </text>
219-
<text wrap fg={theme.agentToggleHeaderText}>
220-
Response
221-
</text>
212+
<text fg={theme.agentToggleHeaderText}>Response</text>
222213
</box>
223214
)}
224215
{renderExpandedContent(content)}
225216
</box>
226217
)}
227-
<box
228-
style={{
229-
alignSelf: 'flex-end',
230-
backgroundColor: theme.agentFocusedBg,
231-
paddingLeft: 1,
232-
paddingRight: 1,
233-
paddingTop: 0,
234-
paddingBottom: 0,
235-
}}
236-
onMouseDown={onToggle}
237-
>
238-
<text wrap={false}>
239-
<span fg={toggleTextColor} attributes={TextAttributes.BOLD}>
240-
Collapse
241-
</span>
242-
</text>
243-
</box>
218+
<RaisedPill
219+
segments={[{ text: 'Collapse', fg: collapseButtonText }]}
220+
frameColor={collapseButtonFrame}
221+
textColor={collapseButtonText}
222+
onPress={onToggle}
223+
style={{ alignSelf: 'flex-end', marginTop: 1 }}
224+
/>
244225
</box>
245226
)}
246227
</box>

0 commit comments

Comments
 (0)