refactor: move Agent Profiles from dashboard to Settings
Move the Agent Profiles configuration from a separate dashboard tab to the Settings page under "Agent Settings". This provides a more intuitive location for users to configure their default agent profile. Changes: - Create AgentProfileSettings component for settings page - Add agent profiles to GeneralSettings 'agent' section - Remove 'agent-profiles' from sidebar navigation - Remove AgentProfiles view from App.tsx routing - Update SidebarView type The agent profiles are now accessible via Settings > Agent Settings, alongside other agent-related configuration options. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -29,7 +29,6 @@ import { Insights } from './components/Insights';
|
||||
import { GitHubIssues } from './components/GitHubIssues';
|
||||
import { Changelog } from './components/Changelog';
|
||||
import { Worktrees } from './components/Worktrees';
|
||||
import { AgentProfiles } from './components/AgentProfiles';
|
||||
import { WelcomeScreen } from './components/WelcomeScreen';
|
||||
import { RateLimitModal } from './components/RateLimitModal';
|
||||
import { SDKRateLimitModal } from './components/SDKRateLimitModal';
|
||||
@@ -462,9 +461,6 @@ export function App() {
|
||||
{activeView === 'worktrees' && selectedProjectId && (
|
||||
<Worktrees projectId={selectedProjectId} />
|
||||
)}
|
||||
{activeView === 'agent-profiles' && (
|
||||
<AgentProfiles />
|
||||
)}
|
||||
{activeView === 'agent-tools' && (
|
||||
<div className="flex h-full items-center justify-center">
|
||||
<div className="text-center">
|
||||
|
||||
@@ -16,8 +16,7 @@ import {
|
||||
FileText,
|
||||
Sparkles,
|
||||
GitBranch,
|
||||
HelpCircle,
|
||||
UserCog
|
||||
HelpCircle
|
||||
} from 'lucide-react';
|
||||
import { Button } from './ui/button';
|
||||
import { ScrollArea } from './ui/scroll-area';
|
||||
@@ -57,7 +56,7 @@ import { GitSetupModal } from './GitSetupModal';
|
||||
import { RateLimitIndicator } from './RateLimitIndicator';
|
||||
import type { Project, AutoBuildVersionInfo, GitStatus } from '../../shared/types';
|
||||
|
||||
export type SidebarView = 'kanban' | 'terminals' | 'roadmap' | 'context' | 'ideation' | 'github-issues' | 'changelog' | 'insights' | 'worktrees' | 'agent-tools' | 'agent-profiles';
|
||||
export type SidebarView = 'kanban' | 'terminals' | 'roadmap' | 'context' | 'ideation' | 'github-issues' | 'changelog' | 'insights' | 'worktrees' | 'agent-tools';
|
||||
|
||||
interface SidebarProps {
|
||||
onSettingsClick: () => void;
|
||||
@@ -85,8 +84,7 @@ const projectNavItems: NavItem[] = [
|
||||
|
||||
const toolsNavItems: NavItem[] = [
|
||||
{ id: 'github-issues', label: 'GitHub Issues', icon: Github, shortcut: 'G' },
|
||||
{ id: 'worktrees', label: 'Worktrees', icon: GitBranch, shortcut: 'W' },
|
||||
{ id: 'agent-profiles', label: 'Agent Profiles', icon: UserCog, shortcut: 'P' }
|
||||
{ id: 'worktrees', label: 'Worktrees', icon: GitBranch, shortcut: 'W' }
|
||||
];
|
||||
|
||||
export function Sidebar({
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
import { Brain, Scale, Zap, Check, Sparkles } from 'lucide-react';
|
||||
import { cn } from '../../lib/utils';
|
||||
import { DEFAULT_AGENT_PROFILES, AVAILABLE_MODELS, THINKING_LEVELS } from '../../../shared/constants';
|
||||
import { useSettingsStore, saveSettings } from '../../stores/settings-store';
|
||||
import { SettingsSection } from './SettingsSection';
|
||||
import type { AgentProfile } from '../../../shared/types/settings';
|
||||
|
||||
/**
|
||||
* Icon mapping for agent profile icons
|
||||
*/
|
||||
const iconMap: Record<string, React.ElementType> = {
|
||||
Brain,
|
||||
Scale,
|
||||
Zap,
|
||||
Sparkles
|
||||
};
|
||||
|
||||
/**
|
||||
* Agent Profile Settings component
|
||||
* Displays preset agent profiles for quick model/thinking level configuration
|
||||
* Used in the Settings page under Agent Settings
|
||||
*/
|
||||
export function AgentProfileSettings() {
|
||||
const settings = useSettingsStore((state) => state.settings);
|
||||
const selectedProfileId = settings.selectedAgentProfile || 'auto';
|
||||
|
||||
const handleSelectProfile = async (profileId: string) => {
|
||||
await saveSettings({ selectedAgentProfile: profileId });
|
||||
};
|
||||
|
||||
/**
|
||||
* Get human-readable model label
|
||||
*/
|
||||
const getModelLabel = (modelValue: string): string => {
|
||||
const model = AVAILABLE_MODELS.find((m) => m.value === modelValue);
|
||||
return model?.label || modelValue;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get human-readable thinking level label
|
||||
*/
|
||||
const getThinkingLabel = (thinkingValue: string): string => {
|
||||
const level = THINKING_LEVELS.find((l) => l.value === thinkingValue);
|
||||
return level?.label || thinkingValue;
|
||||
};
|
||||
|
||||
/**
|
||||
* Render a single profile card
|
||||
*/
|
||||
const renderProfileCard = (profile: AgentProfile) => {
|
||||
const isSelected = selectedProfileId === profile.id;
|
||||
const Icon = iconMap[profile.icon || 'Brain'] || Brain;
|
||||
|
||||
return (
|
||||
<button
|
||||
key={profile.id}
|
||||
onClick={() => handleSelectProfile(profile.id)}
|
||||
className={cn(
|
||||
'relative w-full rounded-lg border p-4 text-left transition-all duration-200',
|
||||
'hover:border-primary/50 hover:shadow-sm',
|
||||
isSelected
|
||||
? 'border-primary bg-primary/5'
|
||||
: 'border-border bg-card'
|
||||
)}
|
||||
>
|
||||
{/* Selected indicator */}
|
||||
{isSelected && (
|
||||
<div className="absolute right-3 top-3 flex h-5 w-5 items-center justify-center rounded-full bg-primary">
|
||||
<Check className="h-3 w-3 text-primary-foreground" />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Profile content */}
|
||||
<div className="flex items-start gap-3">
|
||||
<div
|
||||
className={cn(
|
||||
'flex h-10 w-10 items-center justify-center rounded-lg shrink-0',
|
||||
isSelected ? 'bg-primary/10' : 'bg-muted'
|
||||
)}
|
||||
>
|
||||
<Icon
|
||||
className={cn(
|
||||
'h-5 w-5',
|
||||
isSelected ? 'text-primary' : 'text-muted-foreground'
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex-1 min-w-0 pr-6">
|
||||
<h3 className="font-medium text-sm text-foreground">{profile.name}</h3>
|
||||
<p className="mt-0.5 text-xs text-muted-foreground line-clamp-2">
|
||||
{profile.description}
|
||||
</p>
|
||||
|
||||
{/* Model and thinking level badges */}
|
||||
<div className="mt-2 flex flex-wrap gap-1.5">
|
||||
<span className="inline-flex items-center rounded bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground">
|
||||
{getModelLabel(profile.model)}
|
||||
</span>
|
||||
<span className="inline-flex items-center rounded bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground">
|
||||
{getThinkingLabel(profile.thinkingLevel)} Thinking
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<SettingsSection
|
||||
title="Default Agent Profile"
|
||||
description="Select a preset configuration for model and thinking level"
|
||||
>
|
||||
<div className="space-y-4">
|
||||
{/* Description */}
|
||||
<div className="rounded-lg bg-muted/50 p-3">
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Agent profiles provide preset configurations for Claude model and thinking level.
|
||||
When you create a new task, these settings will be used as defaults. You can always
|
||||
override them in the task creation wizard.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Profile cards - 2 column grid on larger screens */}
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-3">
|
||||
{DEFAULT_AGENT_PROFILES.map(renderProfileCard)}
|
||||
</div>
|
||||
</div>
|
||||
</SettingsSection>
|
||||
);
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import { Input } from '../ui/input';
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../ui/select';
|
||||
import { Switch } from '../ui/switch';
|
||||
import { SettingsSection } from './SettingsSection';
|
||||
import { AgentProfileSettings } from './AgentProfileSettings';
|
||||
import { AVAILABLE_MODELS } from '../../../shared/constants';
|
||||
import type { AppSettings } from '../../../shared/types';
|
||||
|
||||
@@ -18,64 +19,51 @@ interface GeneralSettingsProps {
|
||||
export function GeneralSettings({ settings, onSettingsChange, section }: GeneralSettingsProps) {
|
||||
if (section === 'agent') {
|
||||
return (
|
||||
<SettingsSection
|
||||
title="Default Agent Settings"
|
||||
description="Configure defaults for new projects"
|
||||
>
|
||||
<div className="space-y-6">
|
||||
<div className="space-y-3">
|
||||
<Label htmlFor="defaultModel" className="text-sm font-medium text-foreground">Default Model</Label>
|
||||
<p className="text-sm text-muted-foreground">The AI model used for agent tasks</p>
|
||||
<Select
|
||||
value={settings.defaultModel}
|
||||
onValueChange={(value) => onSettingsChange({ ...settings, defaultModel: value })}
|
||||
>
|
||||
<SelectTrigger id="defaultModel" className="w-full max-w-md">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{AVAILABLE_MODELS.map((model) => (
|
||||
<SelectItem key={model.value} value={model.value}>
|
||||
{model.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="space-y-3">
|
||||
<Label htmlFor="agentFramework" className="text-sm font-medium text-foreground">Agent Framework</Label>
|
||||
<p className="text-sm text-muted-foreground">The coding framework used for autonomous tasks</p>
|
||||
<Select
|
||||
value={settings.agentFramework}
|
||||
onValueChange={(value) => onSettingsChange({ ...settings, agentFramework: value })}
|
||||
>
|
||||
<SelectTrigger id="agentFramework" className="w-full max-w-md">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="auto-claude">Auto Claude</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="space-y-3">
|
||||
<div className="flex items-center justify-between max-w-md">
|
||||
<div className="space-y-1">
|
||||
<Label htmlFor="autoNameTerminals" className="text-sm font-medium text-foreground">
|
||||
AI Terminal Naming
|
||||
</Label>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Automatically name terminals based on commands (uses Haiku)
|
||||
</p>
|
||||
<div className="space-y-8">
|
||||
{/* Agent Profile Selection */}
|
||||
<AgentProfileSettings />
|
||||
|
||||
{/* Other Agent Settings */}
|
||||
<SettingsSection
|
||||
title="Other Agent Settings"
|
||||
description="Additional agent configuration options"
|
||||
>
|
||||
<div className="space-y-6">
|
||||
<div className="space-y-3">
|
||||
<Label htmlFor="agentFramework" className="text-sm font-medium text-foreground">Agent Framework</Label>
|
||||
<p className="text-sm text-muted-foreground">The coding framework used for autonomous tasks</p>
|
||||
<Select
|
||||
value={settings.agentFramework}
|
||||
onValueChange={(value) => onSettingsChange({ ...settings, agentFramework: value })}
|
||||
>
|
||||
<SelectTrigger id="agentFramework" className="w-full max-w-md">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="auto-claude">Auto Claude</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="space-y-3">
|
||||
<div className="flex items-center justify-between max-w-md">
|
||||
<div className="space-y-1">
|
||||
<Label htmlFor="autoNameTerminals" className="text-sm font-medium text-foreground">
|
||||
AI Terminal Naming
|
||||
</Label>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Automatically name terminals based on commands (uses Haiku)
|
||||
</p>
|
||||
</div>
|
||||
<Switch
|
||||
id="autoNameTerminals"
|
||||
checked={settings.autoNameTerminals}
|
||||
onCheckedChange={(checked) => onSettingsChange({ ...settings, autoNameTerminals: checked })}
|
||||
/>
|
||||
</div>
|
||||
<Switch
|
||||
id="autoNameTerminals"
|
||||
checked={settings.autoNameTerminals}
|
||||
onCheckedChange={(checked) => onSettingsChange({ ...settings, autoNameTerminals: checked })}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</SettingsSection>
|
||||
</SettingsSection>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user