From ca78e63205aeb7cbd6c059c7f70fffcc509f860d Mon Sep 17 00:00:00 2001 From: Tam Nhu Tran Date: Wed, 25 Feb 2026 15:53:02 +0700 Subject: [PATCH] feat(ui): add target support to API profile dashboard - extend API client types with claude|droid target fields - add default target selector in API profile create dialog - show target badges in API profile list --- .../profiles/profile-create-dialog.tsx | 35 +++++++++++++++++++ ui/src/lib/api-client.ts | 8 +++++ ui/src/pages/api.tsx | 9 ++++- 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/ui/src/components/profiles/profile-create-dialog.tsx b/ui/src/components/profiles/profile-create-dialog.tsx index 6bb32bf1..510e165a 100644 --- a/ui/src/components/profiles/profile-create-dialog.tsx +++ b/ui/src/components/profiles/profile-create-dialog.tsx @@ -12,6 +12,13 @@ import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { ScrollArea } from '@/components/ui/scroll-area'; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from '@/components/ui/select'; import { Dialog, DialogContent, @@ -41,6 +48,7 @@ import { getNewestModelsPerProvider, } from '@/lib/openrouter-utils'; import type { CategorizedModel } from '@/lib/openrouter-types'; +import type { CliTarget } from '@/lib/api-client'; const schema = z.object({ name: z @@ -53,6 +61,7 @@ const schema = z.object({ opusModel: z.string().optional(), sonnetModel: z.string().optional(), haikuModel: z.string().optional(), + target: z.enum(['claude', 'droid']), }); type FormData = z.infer; @@ -78,6 +87,7 @@ const EMPTY_FORM_VALUES: FormData = { opusModel: '', sonnetModel: '', haikuModel: '', + target: 'claude', }; const RECOMMENDED_PRESETS = getPresetsByCategory('recommended'); @@ -117,6 +127,7 @@ export function ProfileCreateDialog({ }); const baseUrlValue = useWatch({ control, name: 'baseUrl' }); + const targetValue = useWatch({ control, name: 'target' }); const applyPresetToForm = useCallback( (preset: ProviderPreset | null) => { if (!preset) { @@ -445,6 +456,30 @@ export function ProfileCreateDialog({ ) )} + +
+ + +

+ Run with{' '} + + {targetValue === 'droid' ? 'ccsd' : 'ccs'} + {' '} + by default. You can still override each run with{' '} + --target. +

+
diff --git a/ui/src/lib/api-client.ts b/ui/src/lib/api-client.ts index 646d39f0..12ec590e 100644 --- a/ui/src/lib/api-client.ts +++ b/ui/src/lib/api-client.ts @@ -94,10 +94,13 @@ async function request(url: string, options?: RequestInit): Promise { } // Types +export type CliTarget = 'claude' | 'droid'; + export interface Profile { name: string; settingsPath: string; configured: boolean; + target?: CliTarget; } export interface CreateProfile { @@ -108,6 +111,7 @@ export interface CreateProfile { opusModel?: string; sonnetModel?: string; haikuModel?: string; + target?: CliTarget; } export interface UpdateProfile { @@ -117,6 +121,7 @@ export interface UpdateProfile { opusModel?: string; sonnetModel?: string; haikuModel?: string; + target?: CliTarget; } export interface Variant { @@ -126,6 +131,7 @@ export interface Variant { account?: string; port?: number; model?: string; + target?: CliTarget; type?: 'composite'; default_tier?: 'opus' | 'sonnet' | 'haiku'; tiers?: { @@ -140,6 +146,7 @@ export interface CreateVariant { provider: CLIProxyProvider; model?: string; account?: string; + target?: CliTarget; type?: 'composite'; default_tier?: 'opus' | 'sonnet' | 'haiku'; tiers?: { @@ -153,6 +160,7 @@ export interface UpdateVariant { provider?: CLIProxyProvider; model?: string; account?: string; + target?: CliTarget; type?: 'composite'; default_tier?: 'opus' | 'sonnet' | 'haiku'; tiers?: { diff --git a/ui/src/pages/api.tsx b/ui/src/pages/api.tsx index 0152d04a..1d56ac11 100644 --- a/ui/src/pages/api.tsx +++ b/ui/src/pages/api.tsx @@ -7,6 +7,7 @@ import { useState, useMemo } from 'react'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { ScrollArea } from '@/components/ui/scroll-area'; +import { Badge } from '@/components/ui/badge'; import { Plus, Search, @@ -222,6 +223,7 @@ export function ApiPage() { setDeleteConfirm(selectedProfileData.name)} onHasChangesUpdate={setEditorHasChanges} /> @@ -308,7 +310,12 @@ function ProfileListItem({ {/* Profile info */}
-
{profile.name}
+
+
{profile.name}
+ + {profile.target || 'claude'} + +
{profile.settingsPath}