Skip to content

Commit 44a778c

Browse files
committed
refactor: update agent builder and UI components for improved styling and functionality
- Removed deprecated header configuration from next.config.ts for cleaner setup. - Replaced emoji representation with color indicators in AgentBuilder and related components for a more modern UI. - Enhanced ChatInputBar with improved button interactions and event handling for file selection. - Updated various views to reflect color changes for persona presets, ensuring consistency across the application.
1 parent e08fc3b commit 44a778c

10 files changed

Lines changed: 197 additions & 100 deletions

File tree

app/page.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,10 @@ export default function EditorLayout() {
481481
</div>
482482

483483
<div className="flex items-center gap-2">
484-
<div className="flex items-center gap-0.5 rounded-md border border-[var(--border)] bg-[var(--bg)] p-0.5">
484+
<div
485+
className="flex items-center gap-0.5 border border-[var(--border)] bg-[var(--bg)] p-0.5"
486+
style={{ borderRadius: 'var(--radius-md)' }}
487+
>
485488
{MODE_BUTTONS.map((modeButton) => {
486489
const active = mode === modeButton.id
487490
return (

components/agent-builder.tsx

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ function extractTraits(prompt: string): string[] {
8585
export interface AgentBuilderState {
8686
persona: string
8787
presetName: string
88-
presetEmoji: string
88+
presetColor: string
8989
presetDescription: string
9090
systemPrompt: string
9191
behaviors: Record<string, boolean>
@@ -154,7 +154,7 @@ export function AgentBuilder({ onComplete, onSkip, compact, onStateChange }: Pro
154154
onStateChange?.({
155155
persona: selectedPersona,
156156
presetName: selectedPreset.name,
157-
presetEmoji: selectedPreset.emoji,
157+
presetColor: selectedPreset.color,
158158
presetDescription: selectedPreset.description,
159159
systemPrompt,
160160
behaviors,
@@ -163,7 +163,17 @@ export function AgentBuilder({ onComplete, onSkip, compact, onStateChange }: Pro
163163
step,
164164
isModified: isPromptModified,
165165
})
166-
}, [selectedPersona, selectedPreset, systemPrompt, behaviors, modelPreference, traits, step, isPromptModified, onStateChange])
166+
}, [
167+
selectedPersona,
168+
selectedPreset,
169+
systemPrompt,
170+
behaviors,
171+
modelPreference,
172+
traits,
173+
step,
174+
isPromptModified,
175+
onStateChange,
176+
])
167177

168178
// Scroll step into view on change
169179
useEffect(() => {
@@ -218,7 +228,9 @@ export function AgentBuilder({ onComplete, onSkip, compact, onStateChange }: Pro
218228
Pick a starting point — you can customize everything in the next step.
219229
</p>
220230
</div>
221-
<div className={`grid gap-3 ${compact ? 'grid-cols-1' : 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-3'}`}>
231+
<div
232+
className={`grid gap-3 ${compact ? 'grid-cols-1' : 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-3'}`}
233+
>
222234
{PERSONA_PRESETS.map((preset) => (
223235
<button
224236
key={preset.id}
@@ -229,7 +241,10 @@ export function AgentBuilder({ onComplete, onSkip, compact, onStateChange }: Pro
229241
: 'border-[var(--border)] bg-[var(--bg)] hover:border-[var(--border-hover,var(--text-disabled))] hover:shadow-sm'
230242
}`}
231243
>
232-
<span className="text-2xl leading-none mt-0.5">{preset.emoji}</span>
244+
<span
245+
className="w-3 h-3 rounded-full shrink-0 mt-1"
246+
style={{ backgroundColor: preset.color }}
247+
/>
233248
<div className="min-w-0 flex-1">
234249
<div className="text-[13px] font-semibold text-[var(--text-primary)]">
235250
{preset.name}
@@ -297,7 +312,10 @@ export function AgentBuilder({ onComplete, onSkip, compact, onStateChange }: Pro
297312
<div className="w-full lg:w-[240px] shrink-0">
298313
<div className="rounded-xl border border-[var(--border)] bg-[var(--bg)] p-4 space-y-3 lg:sticky lg:top-4">
299314
<div className="flex items-center gap-2.5">
300-
<span className="text-xl">{selectedPreset.emoji}</span>
315+
<span
316+
className="w-3 h-3 rounded-full shrink-0"
317+
style={{ backgroundColor: selectedPreset.color }}
318+
/>
301319
<div>
302320
<div className="text-[12px] font-semibold text-[var(--text-primary)]">
303321
{selectedPreset.name}
@@ -399,7 +417,10 @@ export function AgentBuilder({ onComplete, onSkip, compact, onStateChange }: Pro
399417
<div className="rounded-xl border border-[var(--border)] bg-[var(--bg)] overflow-hidden">
400418
<div className="px-5 py-4 border-b border-[var(--border)] bg-[color-mix(in_srgb,var(--brand)_4%,transparent)]">
401419
<div className="flex items-center gap-3">
402-
<span className="text-2xl">{selectedPreset.emoji}</span>
420+
<span
421+
className="w-3.5 h-3.5 rounded-full shrink-0"
422+
style={{ backgroundColor: selectedPreset.color }}
423+
/>
403424
<div>
404425
<div className="text-[14px] font-semibold text-[var(--text-primary)]">
405426
{selectedPreset.name}
@@ -535,7 +556,10 @@ export function AgentSummary({ config, onReconfigure, onReset }: AgentSummaryPro
535556
<div className="space-y-4">
536557
<div className="rounded-xl border border-[var(--border)] bg-[var(--bg)] overflow-hidden">
537558
<div className="px-5 py-4 flex items-center gap-3">
538-
<span className="text-2xl">{preset.emoji}</span>
559+
<span
560+
className="w-3.5 h-3.5 rounded-full shrink-0"
561+
style={{ backgroundColor: preset.color }}
562+
/>
539563
<div className="flex-1 min-w-0">
540564
<div className="text-[14px] font-semibold text-[var(--text-primary)]">
541565
{preset.name}

components/chat/chat-input-bar.tsx

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import type { AgentMode } from '@/components/mode-selector'
1616
import { ProviderSelector } from '@/components/provider-selector'
1717
import { formatShortcut } from '@/lib/platform'
1818
import { InlinePicker, type PickerItem } from '@/components/chat/inline-picker'
19+
import { emit } from '@/lib/events'
1920

2021
export interface Suggestion {
2122
cmd: string
@@ -472,32 +473,52 @@ export function ChatInputBar({
472473
key={i}
473474
className="group/chip flex items-center gap-1.5 rounded-lg border border-[var(--border)] bg-[var(--bg-subtle)] px-2 py-1 hover:border-[color-mix(in_srgb,var(--brand)_30%,var(--border))] transition-colors"
474475
>
475-
<div className="flex h-5 w-5 shrink-0 items-center justify-center rounded-md bg-[var(--bg)]">
476-
<Icon
477-
icon={
478-
isSelection ? 'lucide:text-cursor-input' : getFileTypeIcon(att.path)
476+
<button
477+
onClick={() => {
478+
emit('file-select', { path: att.path })
479+
if (isSelection && att.startLine != null) {
480+
const sl = att.startLine
481+
const el = att.endLine
482+
setTimeout(() => {
483+
emit('editor-navigate', {
484+
startLine: sl,
485+
endLine: el,
486+
})
487+
}, 200)
479488
}
480-
width={10}
481-
height={10}
482-
className="text-[var(--text-tertiary)]"
483-
/>
484-
</div>
485-
<div className="min-w-0 flex flex-col">
486-
<span className="max-w-[150px] truncate text-[11px] font-mono leading-tight text-[var(--text-secondary)]">
487-
{fileName}
488-
{lineRange && (
489-
<span className="text-[var(--text-disabled)]">:{lineRange}</span>
490-
)}
491-
</span>
492-
<span className="text-[9px] leading-tight text-[var(--text-disabled)]">
493-
{lineCount} line{lineCount !== 1 ? 's' : ''}
494-
{isSelection ? ' selected' : ''}
495-
</span>
496-
</div>
489+
}}
490+
className="flex items-center gap-1.5 min-w-0 cursor-pointer"
491+
>
492+
<div className="flex h-5 w-5 shrink-0 items-center justify-center rounded-md bg-[var(--bg)]">
493+
<Icon
494+
icon={
495+
isSelection
496+
? 'lucide:text-cursor-input'
497+
: getFileTypeIcon(att.path)
498+
}
499+
width={10}
500+
height={10}
501+
className="text-[var(--text-tertiary)]"
502+
/>
503+
</div>
504+
<div className="min-w-0 flex flex-col text-left">
505+
<span className="max-w-[150px] truncate text-[11px] font-mono leading-tight text-[var(--text-secondary)]">
506+
{fileName}
507+
{lineRange && (
508+
<span className="text-[var(--text-disabled)]">:{lineRange}</span>
509+
)}
510+
</span>
511+
<span className="text-[9px] leading-tight text-[var(--text-disabled)]">
512+
{lineCount} line{lineCount !== 1 ? 's' : ''}
513+
{isSelection ? ' selected' : ''}
514+
</span>
515+
</div>
516+
</button>
497517
<button
498-
onClick={() =>
518+
onClick={(e) => {
519+
e.stopPropagation()
499520
setContextAttachments((prev) => prev.filter((_, j) => j !== i))
500-
}
521+
}}
501522
className="w-4 h-4 rounded-full text-[var(--text-disabled)] hover:text-[var(--color-deletions)] hover:bg-[color-mix(in_srgb,var(--color-deletions)_10%,transparent)] flex items-center justify-center shrink-0 cursor-pointer transition-colors"
502523
>
503524
<Icon icon="lucide:x" width={8} height={8} />

components/views/agent-builder-view.tsx

Lines changed: 65 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@
33
import { useState, useCallback, useRef, useEffect, useMemo } from 'react'
44
import { Icon } from '@iconify/react'
55
import { motion, AnimatePresence } from 'framer-motion'
6-
import { AgentBuilder, AgentSummary, BEHAVIOR_DEFS, type AgentBuilderState } from '@/components/agent-builder'
6+
import {
7+
AgentBuilder,
8+
AgentSummary,
9+
BEHAVIOR_DEFS,
10+
type AgentBuilderState,
11+
} from '@/components/agent-builder'
712
import { getAgentConfig, clearAgentConfig, type AgentConfig } from '@/lib/agent-session'
813
import { useView } from '@/context/view-context'
914

@@ -21,20 +26,19 @@ function AgentBuilderPreview({ state }: { state: AgentBuilderState | null }) {
2126
}
2227

2328
const tokenEstimate = Math.ceil(state.systemPrompt.length / 4)
24-
const activeBehaviors = BEHAVIOR_DEFS.filter(
25-
(b) => state.behaviors[b.key] ?? b.defaultValue,
26-
)
27-
const inactiveBehaviors = BEHAVIOR_DEFS.filter(
28-
(b) => !(state.behaviors[b.key] ?? b.defaultValue),
29-
)
29+
const activeBehaviors = BEHAVIOR_DEFS.filter((b) => state.behaviors[b.key] ?? b.defaultValue)
30+
const inactiveBehaviors = BEHAVIOR_DEFS.filter((b) => !(state.behaviors[b.key] ?? b.defaultValue))
3031

3132
return (
3233
<div className="flex-1 flex flex-col min-h-0 overflow-y-auto">
3334
<div className="p-4 space-y-4">
3435
{/* Agent identity card */}
3536
<div className="rounded-xl border border-[var(--border)] bg-[var(--bg)] p-4">
3637
<div className="flex items-center gap-3 mb-3">
37-
<span className="text-2xl">{state.presetEmoji}</span>
38+
<span
39+
className="w-3.5 h-3.5 rounded-full shrink-0"
40+
style={{ backgroundColor: state.presetColor }}
41+
/>
3842
<div className="min-w-0 flex-1">
3943
<div className="text-sm font-semibold text-[var(--text-primary)]">
4044
{state.presetName}
@@ -81,14 +85,30 @@ function AgentBuilderPreview({ state }: { state: AgentBuilderState | null }) {
8185
</div>
8286
<div className="space-y-1 rounded-xl border border-[var(--border)] bg-[var(--bg)] p-3">
8387
{activeBehaviors.map((b) => (
84-
<div key={b.key} className="flex items-center gap-2 px-2 py-1.5 rounded-lg text-[11px]">
85-
<Icon icon="lucide:check" width={10} height={10} className="text-[var(--success)] shrink-0" />
88+
<div
89+
key={b.key}
90+
className="flex items-center gap-2 px-2 py-1.5 rounded-lg text-[11px]"
91+
>
92+
<Icon
93+
icon="lucide:check"
94+
width={10}
95+
height={10}
96+
className="text-[var(--success)] shrink-0"
97+
/>
8698
<span className="text-[var(--text-secondary)]">{b.label.split('(')[0].trim()}</span>
8799
</div>
88100
))}
89101
{inactiveBehaviors.map((b) => (
90-
<div key={b.key} className="flex items-center gap-2 px-2 py-1.5 rounded-lg text-[11px] opacity-50">
91-
<Icon icon="lucide:x" width={10} height={10} className="text-[var(--text-disabled)] shrink-0" />
102+
<div
103+
key={b.key}
104+
className="flex items-center gap-2 px-2 py-1.5 rounded-lg text-[11px] opacity-50"
105+
>
106+
<Icon
107+
icon="lucide:x"
108+
width={10}
109+
height={10}
110+
className="text-[var(--text-disabled)] shrink-0"
111+
/>
92112
<span className="text-[var(--text-disabled)]">{b.label.split('(')[0].trim()}</span>
93113
</div>
94114
))}
@@ -124,9 +144,11 @@ function AgentBuilderPreview({ state }: { state: AgentBuilderState | null }) {
124144
: 'bg-[var(--border)]'
125145
}`}
126146
/>
127-
<span className={`text-[10px] ${
128-
i <= state.step ? 'text-[var(--text-secondary)]' : 'text-[var(--text-disabled)]'
129-
}`}>
147+
<span
148+
className={`text-[10px] ${
149+
i <= state.step ? 'text-[var(--text-secondary)]' : 'text-[var(--text-disabled)]'
150+
}`}
151+
>
130152
{label}
131153
</span>
132154
{i < 3 && <div className="w-3 h-px bg-[var(--border)]" />}
@@ -218,16 +240,19 @@ export function AgentBuilderView() {
218240
}
219241
}, [isDragging])
220242

221-
const previewToggle = useMemo(() => (
222-
<button
223-
onClick={() => setPreviewOpen((v) => !v)}
224-
className="flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-[11px] font-medium text-[var(--text-tertiary)] hover:text-[var(--text-secondary)] hover:bg-[var(--bg-subtle)] transition-colors cursor-pointer"
225-
title={previewOpen ? 'Close preview' : 'Open preview'}
226-
>
227-
<Icon icon="lucide:eye" width={13} height={13} />
228-
Preview
229-
</button>
230-
), [previewOpen])
243+
const previewToggle = useMemo(
244+
() => (
245+
<button
246+
onClick={() => setPreviewOpen((v) => !v)}
247+
className="flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-[11px] font-medium text-[var(--text-tertiary)] hover:text-[var(--text-secondary)] hover:bg-[var(--bg-subtle)] transition-colors cursor-pointer"
248+
title={previewOpen ? 'Close preview' : 'Open preview'}
249+
>
250+
<Icon icon="lucide:eye" width={13} height={13} />
251+
Preview
252+
</button>
253+
),
254+
[previewOpen],
255+
)
231256

232257
return (
233258
<div ref={containerRef} className="flex-1 flex min-h-0 overflow-hidden bg-[var(--sidebar-bg)]">
@@ -243,7 +268,9 @@ export function AgentBuilderView() {
243268
<Icon icon="lucide:arrow-left" width={16} height={16} />
244269
</button>
245270
<div>
246-
<h2 className="text-[15px] font-semibold text-[var(--text-primary)]">Agent Builder</h2>
271+
<h2 className="text-[15px] font-semibold text-[var(--text-primary)]">
272+
Agent Builder
273+
</h2>
247274
<p className="text-[11px] text-[var(--text-tertiary)]">
248275
Configure your AI coding assistant
249276
</p>
@@ -279,7 +306,11 @@ export function AgentBuilderView() {
279306
onStateChange={handleBuilderStateChange}
280307
/>
281308
) : config ? (
282-
<AgentSummary config={config} onReconfigure={handleReconfigure} onReset={handleReset} />
309+
<AgentSummary
310+
config={config}
311+
onReconfigure={handleReconfigure}
312+
onReset={handleReset}
313+
/>
283314
) : null}
284315
</div>
285316
</div>
@@ -298,7 +329,10 @@ export function AgentBuilderView() {
298329
title="Open preview panel"
299330
>
300331
<Icon icon="lucide:eye" width={18} height={18} />
301-
<span className="text-[10px] font-medium tracking-wide" style={{ writingMode: 'vertical-rl' }}>
332+
<span
333+
className="text-[10px] font-medium tracking-wide"
334+
style={{ writingMode: 'vertical-rl' }}
335+
>
302336
Preview
303337
</span>
304338
</motion.button>
@@ -336,7 +370,9 @@ export function AgentBuilderView() {
336370
<div className="shrink-0 flex items-center justify-between px-4 py-3 border-b border-[var(--border)]">
337371
<div className="flex items-center gap-2">
338372
<Icon icon="lucide:eye" width={16} height={16} className="text-[var(--brand)]" />
339-
<h3 className="text-[13px] font-semibold text-[var(--text-primary)]">Live Preview</h3>
373+
<h3 className="text-[13px] font-semibold text-[var(--text-primary)]">
374+
Live Preview
375+
</h3>
340376
</div>
341377
<div className="flex items-center gap-1">
342378
<button

components/views/playground-view.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,9 +170,10 @@ function AgentLoadoutCard({
170170
return (
171171
<section className="rounded-2xl border border-[var(--border)] bg-[var(--bg-elevated)] p-5">
172172
<div className="mb-4 flex items-center gap-3">
173-
<div className="flex h-10 w-10 items-center justify-center rounded-xl bg-[color-mix(in_srgb,var(--brand)_12%,transparent)] text-lg">
174-
{selectedPersona?.emoji ?? '\u{2728}'}
175-
</div>
173+
<span
174+
className="w-3.5 h-3.5 rounded-full shrink-0"
175+
style={{ backgroundColor: selectedPersona?.color ?? '#6B7280' }}
176+
/>
176177
<div>
177178
<h3 className="text-sm font-semibold text-[var(--text-primary)]">{title}</h3>
178179
<p className="text-xs text-[var(--text-tertiary)]">

0 commit comments

Comments
 (0)