From 32dbd5e174338d7627637667c63162ea4b9ffe7f Mon Sep 17 00:00:00 2001 From: kaitranntt Date: Mon, 26 Jan 2026 15:20:12 -0500 Subject: [PATCH] refactor(cliproxy): remove model alias functionality - delete model-alias-config.ts and cliproxy-alias-handler.ts - simplify sync to use ANTHROPIC_MODEL directly - remove alias routes, hooks, and UI components --- src/cliproxy/index.ts | 10 +- src/cliproxy/sync/index.ts | 13 - src/cliproxy/sync/local-config-sync.ts | 3 +- src/cliproxy/sync/model-alias-config.ts | 176 -------------- src/cliproxy/sync/profile-mapper.ts | 40 +--- src/commands/cliproxy-alias-handler.ts | 226 ------------------ src/commands/cliproxy-command.ts | 11 +- src/commands/cliproxy-sync-handler.ts | 6 +- src/web-server/routes/cliproxy-sync-routes.ts | 65 ----- .../components/cliproxy/sync/sync-dialog.tsx | 197 ++++++--------- .../cliproxy/sync/sync-status-card.tsx | 2 +- ui/src/hooks/use-cliproxy-sync.ts | 118 +-------- 12 files changed, 92 insertions(+), 775 deletions(-) delete mode 100644 src/cliproxy/sync/model-alias-config.ts delete mode 100644 src/commands/cliproxy-alias-handler.ts diff --git a/src/cliproxy/index.ts b/src/cliproxy/index.ts index 8fbcffbe..f762e438 100644 --- a/src/cliproxy/index.ts +++ b/src/cliproxy/index.ts @@ -180,7 +180,7 @@ export type { export { ManagementApiClient, createManagementClient } from './management-api-client'; // Sync module (profile sync to remote CLIProxy) -export type { SyncableProfile, SyncPreviewItem, ModelAlias, ModelAliasConfig } from './sync'; +export type { SyncableProfile, SyncPreviewItem } from './sync'; export { loadSyncableProfiles, mapProfileToClaudeKey, @@ -188,12 +188,4 @@ export { generateSyncPreview, getSyncableProfileCount, isProfileSyncable, - getModelAliasesPath, - loadModelAliases, - saveModelAliases, - getProfileAliases, - addProfileAlias, - removeProfileAlias, - listAllAliases, - DEFAULT_MODEL_ALIASES, } from './sync'; diff --git a/src/cliproxy/sync/index.ts b/src/cliproxy/sync/index.ts index cafcad26..3316ee10 100644 --- a/src/cliproxy/sync/index.ts +++ b/src/cliproxy/sync/index.ts @@ -15,19 +15,6 @@ export { isProfileSyncable, } from './profile-mapper'; -// Model alias config -export type { ModelAlias, ModelAliasConfig } from './model-alias-config'; -export { - getModelAliasesPath, - loadModelAliases, - saveModelAliases, - getProfileAliases, - addProfileAlias, - removeProfileAlias, - listAllAliases, - DEFAULT_MODEL_ALIASES, -} from './model-alias-config'; - // Local config sync export { syncToLocalConfig, getLocalSyncStatus } from './local-config-sync'; diff --git a/src/cliproxy/sync/local-config-sync.ts b/src/cliproxy/sync/local-config-sync.ts index ca19a04e..63b154e9 100644 --- a/src/cliproxy/sync/local-config-sync.ts +++ b/src/cliproxy/sync/local-config-sync.ts @@ -122,10 +122,11 @@ function transformToConfigFormat(key: ClaudeKey): Record { // Add empty proxy-url (required by CLIProxyAPI) entry['proxy-url'] = ''; + // Use model name directly (no alias mapping) if (key.models && key.models.length > 0) { entry.models = key.models.map((m) => ({ name: m.name, - alias: m.alias || '', + alias: '', })); } diff --git a/src/cliproxy/sync/model-alias-config.ts b/src/cliproxy/sync/model-alias-config.ts deleted file mode 100644 index 4cccc7f1..00000000 --- a/src/cliproxy/sync/model-alias-config.ts +++ /dev/null @@ -1,176 +0,0 @@ -/** - * Model Alias Configuration - * - * Manages model alias mappings for CLIProxy sync. - * Aliases map Claude model names to provider-specific models. - */ - -import * as fs from 'fs'; -import * as path from 'path'; -import { getCcsDir } from '../../utils/config-manager'; - -/** Model alias mapping */ -export interface ModelAlias { - /** Claude model name (e.g., "claude-3-5-sonnet") */ - from: string; - /** Target model (e.g., "glm-4.7-airx-thinking") */ - to: string; -} - -/** Model alias configuration file structure */ -export interface ModelAliasConfig { - /** Version for future schema changes */ - version: number; - /** Aliases for each profile name */ - aliases: Record; -} - -/** Default model aliases (common mappings) */ -export const DEFAULT_MODEL_ALIASES: Record = { - glm: [ - { from: 'claude-sonnet-4-20250514', to: 'glm-4.7-thinking' }, - { from: 'claude-3-5-sonnet-20241022', to: 'glm-4.7' }, - { from: 'claude-3-5-haiku-20241022', to: 'glm-4.7-flash' }, - ], - kimi: [ - { from: 'claude-sonnet-4-20250514', to: 'moonshot-v1-auto' }, - { from: 'claude-3-5-sonnet-20241022', to: 'moonshot-v1-128k' }, - { from: 'claude-3-5-haiku-20241022', to: 'moonshot-v1-32k' }, - ], - qwen: [ - { from: 'claude-sonnet-4-20250514', to: 'qwen-coder-plus' }, - { from: 'claude-3-5-sonnet-20241022', to: 'qwen-plus' }, - { from: 'claude-3-5-haiku-20241022', to: 'qwen-turbo' }, - ], -}; - -/** - * Get path to model aliases config file. - */ -export function getModelAliasesPath(): string { - return path.join(getCcsDir(), 'cliproxy', 'model-aliases.json'); -} - -/** - * Load model alias configuration. - * Returns defaults if file doesn't exist. - */ -export function loadModelAliases(): ModelAliasConfig { - const aliasPath = getModelAliasesPath(); - - try { - if (fs.existsSync(aliasPath)) { - const content = fs.readFileSync(aliasPath, 'utf8'); - const config = JSON.parse(content) as ModelAliasConfig; - return config; - } - } catch { - // Fall through to defaults - } - - // Return defaults - return { - version: 1, - aliases: { ...DEFAULT_MODEL_ALIASES }, - }; -} - -/** - * Save model alias configuration. - * @returns Success status with optional error message - */ -export function saveModelAliases(config: ModelAliasConfig): { success: boolean; error?: string } { - try { - const aliasPath = getModelAliasesPath(); - const dir = path.dirname(aliasPath); - - if (!fs.existsSync(dir)) { - fs.mkdirSync(dir, { recursive: true }); - } - - fs.writeFileSync(aliasPath, JSON.stringify(config, null, 2), 'utf8'); - return { success: true }; - } catch (error) { - return { - success: false, - error: error instanceof Error ? error.message : String(error), - }; - } -} - -/** - * Get aliases for a specific profile. - */ -export function getProfileAliases(profileName: string): ModelAlias[] { - const config = loadModelAliases(); - return config.aliases[profileName] ?? []; -} - -/** - * Add an alias for a profile. - */ -export function addProfileAlias(profileName: string, from: string, to: string): void { - // Validate inputs - if (!from || from.trim() === '') { - throw new Error('Model alias "from" cannot be empty'); - } - if (!to || to.trim() === '') { - throw new Error('Model alias "to" cannot be empty'); - } - - const config = loadModelAliases(); - - if (!config.aliases[profileName]) { - config.aliases[profileName] = []; - } - - // Check if alias already exists (update if so) - const existingIdx = config.aliases[profileName].findIndex((a) => a.from === from); - if (existingIdx >= 0) { - config.aliases[profileName][existingIdx].to = to; - } else { - config.aliases[profileName].push({ from, to }); - } - - const result = saveModelAliases(config); - if (!result.success) { - throw new Error(`Failed to save model aliases: ${result.error}`); - } -} - -/** - * Remove an alias for a profile. - */ -export function removeProfileAlias(profileName: string, from: string): boolean { - const config = loadModelAliases(); - - if (!config.aliases[profileName]) { - return false; - } - - const initialLen = config.aliases[profileName].length; - config.aliases[profileName] = config.aliases[profileName].filter((a) => a.from !== from); - - if (config.aliases[profileName].length === initialLen) { - return false; - } - - // Remove empty profile entry - if (config.aliases[profileName].length === 0) { - delete config.aliases[profileName]; - } - - const result = saveModelAliases(config); - if (!result.success) { - throw new Error(`Failed to save model aliases: ${result.error}`); - } - return true; -} - -/** - * List all aliases. - */ -export function listAllAliases(): Record { - const config = loadModelAliases(); - return config.aliases; -} diff --git a/src/cliproxy/sync/profile-mapper.ts b/src/cliproxy/sync/profile-mapper.ts index b3796ef4..9b3b6a6e 100644 --- a/src/cliproxy/sync/profile-mapper.ts +++ b/src/cliproxy/sync/profile-mapper.ts @@ -2,15 +2,13 @@ * Profile Mapper for CLIProxy Sync * * Transforms CCS settings-based profiles into CLIProxy ClaudeKey format. - * Handles model alias mapping and settings normalization. */ import * as fs from 'fs'; import * as path from 'path'; import { getCcsDir } from '../../utils/config-manager'; import { listApiProfiles, isApiProfileConfigured } from '../../api/services/profile-reader'; -import type { ClaudeKey, ClaudeModel } from '../management-api-types'; -import { getProfileAliases, type ModelAlias } from './model-alias-config'; +import type { ClaudeKey } from '../management-api-types'; /** * Profile info with settings for sync. @@ -80,16 +78,6 @@ export function loadSyncableProfiles(): SyncableProfile[] { return syncable; } -/** - * Map model aliases to ClaudeModel format. - */ -function mapAliasesToClaudeModels(aliases: ModelAlias[]): ClaudeModel[] { - return aliases.map((alias) => ({ - name: alias.from, - alias: alias.to, - })); -} - /** * Sanitize profile name for YAML safety. * Replaces non-alphanumeric chars (except - and _) with hyphens. @@ -109,6 +97,7 @@ export function mapProfileToClaudeKey(profile: SyncableProfile): ClaudeKey | nul if (!apiKey) return null; const baseUrl = env.ANTHROPIC_BASE_URL; + const modelName = env.ANTHROPIC_MODEL; // Generate prefix from profile name (e.g., "glm" -> "glm-") const sanitizedName = sanitizeProfileName(profile.name); @@ -117,10 +106,6 @@ export function mapProfileToClaudeKey(profile: SyncableProfile): ClaudeKey | nul } const prefix = `${sanitizedName}-`; - // Load model aliases for this profile - const aliases = getProfileAliases(profile.name); - const models = aliases.length > 0 ? mapAliasesToClaudeModels(aliases) : undefined; - const claudeKey: ClaudeKey = { 'api-key': apiKey, prefix, @@ -130,8 +115,14 @@ export function mapProfileToClaudeKey(profile: SyncableProfile): ClaudeKey | nul claudeKey['base-url'] = baseUrl; } - if (models && models.length > 0) { - claudeKey.models = models; + // Use model name directly from profile (no alias mapping) + if (modelName) { + claudeKey.models = [ + { + name: modelName, + alias: '', + }, + ]; } return claudeKey; @@ -164,10 +155,8 @@ export interface SyncPreviewItem { name: string; /** Base URL (masked) */ baseUrl?: string; - /** Whether profile has model aliases */ - hasAliases: boolean; - /** Number of model aliases */ - aliasCount: number; + /** Model name */ + modelName?: string; } export function generateSyncPreview(): SyncPreviewItem[] { @@ -175,13 +164,10 @@ export function generateSyncPreview(): SyncPreviewItem[] { const preview: SyncPreviewItem[] = []; for (const profile of profiles) { - const aliases = getProfileAliases(profile.name); - preview.push({ name: profile.name, baseUrl: profile.env?.ANTHROPIC_BASE_URL, - hasAliases: aliases.length > 0, - aliasCount: aliases.length, + modelName: profile.env?.ANTHROPIC_MODEL, }); } diff --git a/src/commands/cliproxy-alias-handler.ts b/src/commands/cliproxy-alias-handler.ts deleted file mode 100644 index b69a0f7c..00000000 --- a/src/commands/cliproxy-alias-handler.ts +++ /dev/null @@ -1,226 +0,0 @@ -/** - * CLIProxy Alias Command Handler - * - * Handles `ccs cliproxy alias` commands for managing model alias mappings. - */ - -import { addProfileAlias, removeProfileAlias, listAllAliases } from '../cliproxy/sync'; -import { initUI, header, subheader, color, dim, ok, fail, warn, info, table } from '../utils/ui'; - -interface AliasArgs { - subcommand: 'add' | 'remove' | 'list' | 'help' | null; - profile?: string; - from?: string; - to?: string; -} - -/** - * Parse alias command arguments. - */ -export function parseAliasArgs(args: string[]): AliasArgs { - const rawCommand = args[0]; - - if (!rawCommand || rawCommand === 'help' || args.includes('--help')) { - return { subcommand: 'help' }; - } - - if (rawCommand === 'list' || rawCommand === 'ls') { - return { subcommand: 'list', profile: args[1] }; - } - - if (rawCommand === 'add') { - // ccs cliproxy alias add - return { - subcommand: 'add', - profile: args[1], - from: args[2], - to: args[3], - }; - } - - if (rawCommand === 'remove' || rawCommand === 'rm' || rawCommand === 'delete') { - // ccs cliproxy alias remove - return { - subcommand: 'remove', - profile: args[1], - from: args[2], - }; - } - - return { subcommand: null }; -} - -/** - * Show alias command help. - */ -async function showAliasHelp(): Promise { - await initUI(); - console.log(''); - console.log(header('Model Alias Management')); - console.log(''); - console.log(subheader('Usage:')); - console.log(` ${color('ccs cliproxy alias', 'command')} [args]`); - console.log(''); - - console.log(subheader('Commands:')); - const commands: [string, string][] = [ - ['list [profile]', 'List all aliases (or for specific profile)'], - ['add ', 'Add model alias mapping'], - ['remove ', 'Remove model alias mapping'], - ]; - - const maxLen = Math.max(...commands.map(([cmd]) => cmd.length)); - for (const [cmd, desc] of commands) { - console.log(` ${color(cmd.padEnd(maxLen + 2), 'command')} ${desc}`); - } - - console.log(''); - console.log(subheader('Examples:')); - console.log(` ${dim('# List all aliases')}`); - console.log(` ${color('ccs cliproxy alias list', 'command')}`); - console.log(''); - console.log(` ${dim('# Add alias for GLM profile')}`); - console.log( - ` ${color('ccs cliproxy alias add glm claude-sonnet-4-20250514 glm-4.7-thinking', 'command')}` - ); - console.log(''); - console.log(` ${dim('# Remove alias')}`); - console.log(` ${color('ccs cliproxy alias remove glm claude-sonnet-4-20250514', 'command')}`); - console.log(''); -} - -/** - * Handle `ccs cliproxy alias list` command. - */ -async function handleAliasList(profile?: string): Promise { - await initUI(); - const allAliases = listAllAliases(); - - if (Object.keys(allAliases).length === 0) { - console.log(info('No model aliases configured')); - console.log(''); - console.log('Add aliases with:'); - console.log(` ${color('ccs cliproxy alias add ', 'command')}`); - console.log(''); - return; - } - - // Filter to specific profile if provided - const profiles = profile ? { [profile]: allAliases[profile] } : allAliases; - - if (profile && !allAliases[profile]) { - console.log(warn(`No aliases found for profile: ${profile}`)); - console.log(''); - return; - } - - console.log(header('Model Aliases')); - console.log(''); - - for (const [profileName, aliases] of Object.entries(profiles)) { - if (!aliases || aliases.length === 0) continue; - - console.log(subheader(profileName)); - - const rows = aliases.map((a) => [a.from, color('->', 'info'), a.to]); - console.log( - table(rows, { head: ['Claude Model', '', 'Target Model'], colWidths: [35, 4, 30] }) - ); - console.log(''); - } -} - -/** - * Handle `ccs cliproxy alias add` command. - */ -async function handleAliasAdd(profile: string, from: string, to: string): Promise { - await initUI(); - - if (!profile || !from || !to) { - console.log(fail('Missing required arguments')); - console.log(''); - console.log('Usage:'); - console.log(` ${color('ccs cliproxy alias add ', 'command')}`); - console.log(''); - console.log('Example:'); - console.log( - ` ${color('ccs cliproxy alias add glm claude-sonnet-4-20250514 glm-4.7-thinking', 'command')}` - ); - console.log(''); - process.exit(1); - } - - addProfileAlias(profile, from, to); - - console.log(ok(`Added alias for ${profile}`)); - console.log(` ${from} -> ${to}`); - console.log(''); - console.log(info('Run sync to apply changes:')); - console.log(` ${color('ccs cliproxy sync', 'command')}`); - console.log(''); -} - -/** - * Handle `ccs cliproxy alias remove` command. - */ -async function handleAliasRemove(profile: string, from: string): Promise { - await initUI(); - - if (!profile || !from) { - console.log(fail('Missing required arguments')); - console.log(''); - console.log('Usage:'); - console.log(` ${color('ccs cliproxy alias remove ', 'command')}`); - console.log(''); - process.exit(1); - } - - const removed = removeProfileAlias(profile, from); - - if (!removed) { - console.log(warn(`Alias not found: ${profile}/${from}`)); - console.log(''); - return; - } - - console.log(ok(`Removed alias from ${profile}`)); - console.log(` ${from}`); - console.log(''); - console.log(info('Run sync to apply changes:')); - console.log(` ${color('ccs cliproxy sync', 'command')}`); - console.log(''); -} - -/** - * Handle `ccs cliproxy alias` command router. - */ -export async function handleAlias(args: string[]): Promise { - const parsed = parseAliasArgs(args); - - switch (parsed.subcommand) { - case 'list': - await handleAliasList(parsed.profile); - break; - - case 'add': - if (parsed.profile && parsed.from && parsed.to) { - await handleAliasAdd(parsed.profile, parsed.from, parsed.to); - } else { - await handleAliasAdd('', '', ''); // Will show error message - } - break; - - case 'remove': - if (parsed.profile && parsed.from) { - await handleAliasRemove(parsed.profile, parsed.from); - } else { - await handleAliasRemove('', ''); // Will show error message - } - break; - - case 'help': - default: - await showAliasHelp(); - break; - } -} diff --git a/src/commands/cliproxy-command.ts b/src/commands/cliproxy-command.ts index fa21091f..d5cdf2fe 100644 --- a/src/commands/cliproxy-command.ts +++ b/src/commands/cliproxy-command.ts @@ -64,9 +64,8 @@ import { installLatest, } from '../cliproxy/services'; -// Import sync and alias handlers +// Import sync handler import { handleSync } from './cliproxy-sync-handler'; -import { handleAlias } from './cliproxy-alias-handler'; // ============================================================================ // ARGUMENT PARSING @@ -623,9 +622,6 @@ async function showHelp(): Promise { ['sync', 'Sync API profiles to remote CLIProxy'], ['sync --dry-run', 'Preview sync without applying'], ['sync --force', 'Sync without confirmation prompt'], - ['alias list', 'List model alias mappings'], - ['alias add ', 'Add model alias'], - ['alias remove ', 'Remove model alias'], ], ], [ @@ -1024,11 +1020,6 @@ export async function handleCliproxyCommand(args: string[]): Promise { return; } - if (command === 'alias') { - await handleAlias(remainingArgs.slice(1)); - return; - } - if (command === 'stop') { await handleStop(); return; diff --git a/src/commands/cliproxy-sync-handler.ts b/src/commands/cliproxy-sync-handler.ts index 5d000049..fb4bceef 100644 --- a/src/commands/cliproxy-sync-handler.ts +++ b/src/commands/cliproxy-sync-handler.ts @@ -61,12 +61,12 @@ export async function handleSync(args: string[]): Promise { console.log(''); const rows = preview.map((p) => { - const aliases = p.hasAliases ? color(`${p.aliasCount} aliases`, 'info') : dim('none'); + const model = p.modelName ? color(p.modelName, 'info') : dim('default'); const url = p.baseUrl ? dim(p.baseUrl) : dim('-'); - return [p.name, url, aliases]; + return [p.name, url, model]; }); - console.log(table(rows, { head: ['Profile', 'Base URL', 'Aliases'], colWidths: [15, 40, 15] })); + console.log(table(rows, { head: ['Profile', 'Base URL', 'Model'], colWidths: [15, 40, 20] })); console.log(''); if (parsed.verbose) { diff --git a/src/web-server/routes/cliproxy-sync-routes.ts b/src/web-server/routes/cliproxy-sync-routes.ts index c0917943..1bbec5fc 100644 --- a/src/web-server/routes/cliproxy-sync-routes.ts +++ b/src/web-server/routes/cliproxy-sync-routes.ts @@ -7,9 +7,6 @@ import { loadOrCreateUnifiedConfig } from '../../config/unified-config-loader'; import { generateSyncPayload, generateSyncPreview, - listAllAliases, - addProfileAlias, - removeProfileAlias, getAutoSyncStatus, restartAutoSyncWatcher, syncToLocalConfig, @@ -104,68 +101,6 @@ router.post('/', async (_req: Request, res: Response): Promise => { } }); -// ==================== Model Aliases ==================== - -/** - * GET /api/cliproxy/sync/aliases - List all model aliases - * Returns: { aliases: Record } - */ -router.get('/aliases', async (_req: Request, res: Response): Promise => { - try { - const aliases = listAllAliases(); - res.json({ aliases }); - } catch (error) { - res.status(500).json({ error: (error as Error).message }); - } -}); - -/** - * POST /api/cliproxy/sync/aliases - Add a model alias - * Body: { profile: string, from: string, to: string } - * Returns: { success: true } - */ -router.post('/aliases', async (req: Request, res: Response): Promise => { - try { - const { profile, from, to } = req.body; - const trimmedProfile = typeof profile === 'string' ? profile.trim() : ''; - const trimmedFrom = typeof from === 'string' ? from.trim() : ''; - const trimmedTo = typeof to === 'string' ? to.trim() : ''; - - if (!trimmedProfile || !trimmedFrom || !trimmedTo) { - res.status(400).json({ error: 'Missing required fields: profile, from, to' }); - return; - } - - addProfileAlias(trimmedProfile, trimmedFrom, trimmedTo); - res.json({ success: true, profile: trimmedProfile, from: trimmedFrom, to: trimmedTo }); - } catch (error) { - res.status(500).json({ error: (error as Error).message }); - } -}); - -/** - * DELETE /api/cliproxy/sync/aliases - Remove a model alias - * Body: { profile: string, from: string } - * Returns: { success: boolean } - */ -router.delete('/aliases', async (req: Request, res: Response): Promise => { - try { - const { profile, from } = req.body; - const trimmedProfile = typeof profile === 'string' ? profile.trim() : ''; - const trimmedFrom = typeof from === 'string' ? from.trim() : ''; - - if (!trimmedProfile || !trimmedFrom) { - res.status(400).json({ error: 'Missing required fields: profile, from' }); - return; - } - - const removed = removeProfileAlias(trimmedProfile, trimmedFrom); - res.json({ success: removed, profile: trimmedProfile, from: trimmedFrom }); - } catch (error) { - res.status(500).json({ error: (error as Error).message }); - } -}); - // ==================== Auto-Sync ==================== /** diff --git a/ui/src/components/cliproxy/sync/sync-dialog.tsx b/ui/src/components/cliproxy/sync/sync-dialog.tsx index 87da360d..b2b8e89e 100644 --- a/ui/src/components/cliproxy/sync/sync-dialog.tsx +++ b/ui/src/components/cliproxy/sync/sync-dialog.tsx @@ -3,7 +3,6 @@ * Dialog for managing sync configuration, preview, and execution */ -import { useState } from 'react'; import { Dialog, DialogContent, @@ -11,13 +10,12 @@ import { DialogHeader, DialogTitle, } from '@/components/ui/dialog'; -import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; import { ScrollArea } from '@/components/ui/scroll-area'; -import { Loader2, Upload, CheckCircle, AlertCircle, ArrowRight } from 'lucide-react'; +import { Loader2, Upload, CheckCircle } from 'lucide-react'; import { cn } from '@/lib/utils'; -import { useSyncPreview, useExecuteSync, useSyncAliases } from '@/hooks/use-cliproxy-sync'; +import { useSyncPreview, useExecuteSync } from '@/hooks/use-cliproxy-sync'; interface SyncDialogProps { open: boolean; @@ -25,9 +23,7 @@ interface SyncDialogProps { } export function SyncDialog({ open, onOpenChange }: SyncDialogProps) { - const [activeTab, setActiveTab] = useState('preview'); const { data: preview, isLoading: previewLoading } = useSyncPreview(); - const { data: aliasData } = useSyncAliases(); const { mutate: executeSync, isPending: isSyncing, isSuccess, reset } = useExecuteSync(); const handleSync = () => { @@ -56,132 +52,79 @@ export function SyncDialog({ open, onOpenChange }: SyncDialogProps) { - - - Preview - Model Aliases - - - - {previewLoading ? ( -
- -
- ) : preview?.count === 0 ? ( -
-

No profiles configured to sync.

-

Create API profiles first using the Profiles tab.

-
- ) : ( - -
- {preview?.profiles.map((profile) => ( -
-
-
{profile.name}
- {profile.baseUrl && ( -
- {profile.baseUrl} -
- )} -
-
- {profile.hasAliases && ( - - {profile.aliasCount} alias{profile.aliasCount !== 1 ? 'es' : ''} - - )} - - Ready - -
-
- ))} -
-
- )} - -
-
- {preview?.count ?? 0} profile{(preview?.count ?? 0) !== 1 ? 's' : ''} to sync -
-
- - -
+
+ {previewLoading ? ( +
+
- - - + ) : preview?.count === 0 ? ( +
+

No profiles configured to sync.

+

Create API profiles first using the Profiles tab.

+
+ ) : ( - {!aliasData?.aliases || Object.keys(aliasData.aliases).length === 0 ? ( -
-

No model aliases configured.

-

- Add aliases via CLI:{' '} - ccs cliproxy alias add -

-
- ) : ( -
- {Object.entries(aliasData.aliases).map(([profileName, aliases]) => ( -
-
{profileName}
-
- {aliases.map((alias) => ( -
- {alias.from} - - {alias.to} -
- ))} -
+
+ {preview?.profiles.map((profile) => ( +
+
+
{profile.name}
+ {profile.modelName && ( +
+ Model: {profile.modelName} +
+ )} + {profile.baseUrl && ( +
+ {profile.baseUrl} +
+ )}
- ))} -
- )} - - -
-
- -

- Model aliases map Claude model names to your provider's model names. Manage - aliases via CLI for now. UI editor coming soon. -

+ + Ready + +
+ ))}
+ + )} + +
+
+ {preview?.count ?? 0} profile{(preview?.count ?? 0) !== 1 ? 's' : ''} to sync
- - +
+ + +
+
+
); diff --git a/ui/src/components/cliproxy/sync/sync-status-card.tsx b/ui/src/components/cliproxy/sync/sync-status-card.tsx index b80dec9f..4c220292 100644 --- a/ui/src/components/cliproxy/sync/sync-status-card.tsx +++ b/ui/src/components/cliproxy/sync/sync-status-card.tsx @@ -89,7 +89,7 @@ export function SyncStatusCard() { className="flex-1" onClick={() => setDialogOpen(true)} > - Aliases + Details