From 59153cc1c528e5b393cad0bf13f69d59aa9daa0c Mon Sep 17 00:00:00 2001 From: Taylor Mullen Date: Mon, 6 Apr 2026 12:03:36 -0700 Subject: [PATCH] fix(cli): refine team creation UI with consistent provider markers and non-persistent selection - Removed persistent team selection from settings and config - Added ProviderTag component for brand-consistent provider labels (Claude Code, Gemma, etc.) - Refined agent roster UI in TeamCreatorWizard (removed extra borders, fixed overflow, updated footer) - Updated Step 3 and Step 4 to show provider markers next to agent names - Simplified UI by removing redundant collective provider summary lines - Standardized visual language to match primary status indicators --- packages/cli/src/config/config.ts | 1 - packages/cli/src/config/settingsSchema.ts | 9 - packages/cli/src/ui/AppContainer.tsx | 3 +- .../src/ui/components/TeamCreatorWizard.tsx | 270 ++++++++++++------ 4 files changed, 181 insertions(+), 102 deletions(-) diff --git a/packages/cli/src/config/config.ts b/packages/cli/src/config/config.ts index 657b7f3259..27953c60a9 100755 --- a/packages/cli/src/config/config.ts +++ b/packages/cli/src/config/config.ts @@ -894,7 +894,6 @@ export async function loadCliConfig( targetDir: cwd, includeDirectoryTree, includeDirectories, - activeTeam: settings.general?.activeTeam, loadMemoryFromIncludeDirectories: settings.context?.loadMemoryFromIncludeDirectories || false, discoveryMaxDirs: settings.context?.discoveryMaxDirs, diff --git a/packages/cli/src/config/settingsSchema.ts b/packages/cli/src/config/settingsSchema.ts index f7025c3baa..1578b920ef 100644 --- a/packages/cli/src/config/settingsSchema.ts +++ b/packages/cli/src/config/settingsSchema.ts @@ -199,15 +199,6 @@ const SETTINGS_SCHEMA = { description: 'The preferred editor to open files in.', showInDialog: false, }, - activeTeam: { - type: 'string', - label: 'Active Team', - category: 'General', - requiresRestart: false, - default: undefined as string | undefined, - description: 'The currently active agent team slug.', - showInDialog: false, - }, vimMode: { type: 'boolean', label: 'Vim Mode', diff --git a/packages/cli/src/ui/AppContainer.tsx b/packages/cli/src/ui/AppContainer.tsx index ca7b0726f4..02ed67b230 100644 --- a/packages/cli/src/ui/AppContainer.tsx +++ b/packages/cli/src/ui/AppContainer.tsx @@ -1426,11 +1426,10 @@ Logging in with Google... Restarting Gemini CLI to continue. const handleTeamSelect = useCallback( async (teamName: string | undefined) => { await config.setActiveTeam(teamName); - settings.setValue(SettingScope.Workspace, 'general.activeTeam', teamName); setIsTeamSelectionActive(false); refreshStatic(); }, - [config, refreshStatic, settings], + [config, refreshStatic], ); /** * Determines if the input prompt should be active and accept user input. diff --git a/packages/cli/src/ui/components/TeamCreatorWizard.tsx b/packages/cli/src/ui/components/TeamCreatorWizard.tsx index f7fc38ee48..4c34b6da35 100644 --- a/packages/cli/src/ui/components/TeamCreatorWizard.tsx +++ b/packages/cli/src/ui/components/TeamCreatorWizard.tsx @@ -38,38 +38,42 @@ type WizardStep = | 'confirmation' | 'success'; +const PROVIDER_COLORS: Record = { + 'claude-code': '#C15F3C', // Claude Orange (Exact) + codex: '#FFFFFF', // Codex White + gemini: '#A855F7', // Gemini Purple + antigravity: '#93C5FD', // Antigravity Light Blue + gemma: '#60A5FA', // Gemma Blue +}; + const EXTERNAL_TEMPLATES: RosterListItem[] = [ { name: 'claude-coder', kind: 'external', provider: 'claude-code', description: 'Expert Claude coder focused on direct action.', - logo: '󰈙', - logoColor: '#D7AFFF', // Purple + logoColor: PROVIDER_COLORS['claude-code'], }, { name: 'codex-architect', kind: 'external', provider: 'codex', description: 'Specialized code generation and architectural patterns.', - logo: '󰘦', - logoColor: '#87D7D7', // Cyan + logoColor: PROVIDER_COLORS['codex'], }, { name: 'antigravity-creative', kind: 'external', provider: 'antigravity', description: 'Creative problem solving and unconventional solutions.', - logo: '󱜙', - logoColor: '#FFFFAF', // Yellow + logoColor: PROVIDER_COLORS['antigravity'], }, { name: 'gemma-helper', kind: 'external', provider: 'gemma', description: 'Lightweight and efficient general purpose assistant.', - logo: '󱜚', - logoColor: '#87AFFF', // Blue + logoColor: PROVIDER_COLORS['gemma'], }, ]; @@ -83,6 +87,25 @@ interface RosterListItem { logoColor?: string; } +function ProviderTag({ provider }: { provider: string }) { + const label = + provider === 'claude-code' + ? 'Claude Code' + : provider === 'codex' + ? 'Codex' + : provider === 'antigravity' + ? 'Antigravity' + : provider === 'gemma' + ? 'Gemma' + : 'Gemini CLI'; + const color = PROVIDER_COLORS[provider] || theme.ui.comment; + return ( + + [{label}] + + ); +} + export function TeamCreatorWizard({ onComplete, onCancel, @@ -99,6 +122,7 @@ export function TeamCreatorWizard({ const [isSubmitting, setIsSubmitting] = useState(false); const [error, setError] = useState(null); const [createdPath, setCreatedPath] = useState(null); + const [rosterMode, setRosterMode] = useState<'list' | 'action'>('list'); const localAgents = useMemo( () => @@ -111,8 +135,8 @@ export function TeamCreatorWizard({ const allAvailableAgents = useMemo((): RosterListItem[] => { const local: RosterListItem[] = localAgents.map((a) => { - let logo = '󰈙'; // Default - let logoColor = theme.text.accent; + let logo = '✦'; // Default Gemini Icon + let logoColor = PROVIDER_COLORS['gemini']; if (a.name === 'codebase-investigator') { logo = '🔍'; @@ -121,8 +145,7 @@ export function TeamCreatorWizard({ logo = '󰞋'; logoColor = '#FBBC04'; // Yellow } else if (a.name === 'generalist') { - logo = '󰈙'; - logoColor = '#4285F4'; // Blue + logoColor = '#4285F4'; // Google Blue } return { @@ -144,6 +167,7 @@ export function TeamCreatorWizard({ })); return [...local, ...external]; }, [localAgents]); + const { settings } = useSettingsStore(); const { stdin, setRawMode } = useStdin(); const getPreferredEditor = useCallback( @@ -177,11 +201,18 @@ export function TeamCreatorWizard({ }, [step, teamName, displayName, instructions]); const handleBack = useCallback(() => { - if (step === 'roster') setStep('identity'); - else if (step === 'objective') setStep('roster'); - else if (step === 'confirmation') setStep('objective'); - else if (step === 'identity') onCancel(); - else if (step === 'success') onComplete(); + if (step === 'roster') { + setStep('identity'); + setRosterMode('list'); // Reset roster mode when going back + } else if (step === 'objective') { + setStep('roster'); + } else if (step === 'confirmation') { + setStep('objective'); + } else if (step === 'identity') { + onCancel(); + } else if (step === 'success') { + onComplete(); + } }, [step, onCancel, onComplete]); const handleToggleAgent = (name: string) => { @@ -301,6 +332,10 @@ export function TeamCreatorWizard({ return true; } if (key.name === 'tab') { + if (step === 'roster') { + setRosterMode((prev) => (prev === 'list' ? 'action' : 'list')); + return true; + } handleBack(); return true; } @@ -316,6 +351,32 @@ export function TeamCreatorWizard({ priority: true, }); + const handleRosterKeyPress = useCallback( + (key: Key) => { + if (key.sequence?.toLowerCase() === 'b') { + handleBack(); + return true; + } + if (rosterMode === 'action') { + if (keyMatchers[Command.RETURN](key)) { + handleNext(); + return true; + } + } + if (keyMatchers[Command.ESCAPE](key)) { + onCancel(); + return true; + } + return false; + }, + [handleNext, handleBack, onCancel, rosterMode, keyMatchers], + ); + + useKeypress(handleRosterKeyPress, { + isActive: step === 'roster', + priority: true, + }); + const handleObjectiveKeyPress = useCallback( (key: Key) => { if (keyMatchers[Command.OPEN_EXTERNAL_EDITOR](key)) { @@ -413,10 +474,6 @@ export function TeamCreatorWizard({ key: a.name, value: a, })); - rosterItems.push({ - key: 'done', - value: { name: 'done', kind: 'meta' as const }, - }); return ( - - Step 2: Team Roster - - + + + Step 2: Team Roster + + + + Selected: {selectedAgents.size} + + + + + - Select agents to include in your team. + {rosterMode === 'list' + ? 'Select agents to include in your team:' + : 'Switch back to the list if you need to select more agents:'} - + + items={rosterItems} - onSelect={(item) => { - if (item.name === 'done') handleNext(); - else handleToggleAgent(item.name); - }} - maxItemsToShow={10} + onSelect={(item) => handleToggleAgent(item.name)} + maxItemsToShow={5} showScrollArrows={true} + isFocused={rosterMode === 'list'} renderItem={(item, context) => { const value = item.value; - if (value.name === 'done') { - return ( - - [ Done - Continue to Objective ] - - ); - } const isChecked = selectedAgents.has(value.name); return ( - + - {value.kind === 'external' ? ( - - {' '} - [EXTERNAL] - - ) : !value.sourcePath ? ( - - {' '} - [BUILT-IN] - - ) : null} - - {' '} - ({value.kind} - {value.provider ? `: ${value.provider}` : ''}) - + {(() => { + const p = value.provider || 'gemini'; + const label = + p === 'claude-code' + ? 'Claude Code' + : p === 'codex' + ? 'Codex' + : p === 'antigravity' + ? 'Antigravity' + : p === 'gemma' + ? 'Gemma' + : 'Gemini CLI'; + const color = PROVIDER_COLORS[p] || theme.ui.comment; + return ( + + {' '} + [{label}] + + ); + })()} {value.description && ( - - {' '} + + {' '} {value.description} )} @@ -513,9 +569,37 @@ export function TeamCreatorWizard({ }} /> + + + + {rosterMode === 'action' ? '> ' : ' '}[ Done - Continue to + Objective ] + + + ); @@ -538,24 +622,27 @@ export function TeamCreatorWizard({ Define what this team does and how it should work. {selectedAgents.size > 0 && ( - - Referencing agents: - {Array.from(selectedAgents).map((name, i) => { - const agent = allAvailableAgents.find((a) => a.name === name); - return ( - - {agent?.logo && ( - - {agent.logo}{' '} - - )} - - @{name} - {i < selectedAgents.size - 1 ? ', ' : ''} - - - ); - })} + + + Referencing agents: + {Array.from(selectedAgents).map((name, i) => { + const agent = allAvailableAgents.find((a) => a.name === name); + return ( + + {agent?.logo && ( + + {agent.logo}{' '} + + )} + @{name} + + {i < selectedAgents.size - 1 && ( + , + )} + + ); + })} + )} - - Description: {description} - + + + Description: {description} + + Roster: @@ -618,7 +707,8 @@ export function TeamCreatorWizard({ {agent.logo}{' '} )} - {name} + {name} + ); })}