feat(ui): integrate Kiro and Copilot providers, rename to CLIProxy Plus

- Rename sidebar/header from CLIProxy to CLIProxy Plus
- Add Kiro and Copilot to all provider lists and type unions
- Add provider logos and color configs
- Add model catalogs with upstream CLIProxyAPIPlus models
- Update Quick Setup Wizard with new providers
This commit is contained in:
kaitranntt committed 2025-12-21 22:27:36 -05:00
1 parent 9ca20e70de
commit 0f029f960a
11 files changed
+143 -11

No files matched your search

@@ -14,7 +14,7 @@ import { Label } from '@/components/ui/label';
import { useCreateVariant, useCliproxyAuth } from '@/hooks/use-cliproxy'; import { useCreateVariant, useCliproxyAuth } from '@/hooks/use-cliproxy';
import { usePrivacy } from '@/contexts/privacy-context'; import { usePrivacy } from '@/contexts/privacy-context';
const providers = ['gemini', 'codex', 'agy', 'qwen', 'iflow'] as const; const providers = ['gemini', 'codex', 'agy', 'qwen', 'iflow', 'kiro', 'copilot'] as const;
const schema = z.object({ const schema = z.object({
name: z name: z
@@ -39,6 +39,8 @@ const providerOptions = [
{ value: 'agy', label: 'Antigravity' }, { value: 'agy', label: 'Antigravity' },
{ value: 'qwen', label: 'Alibaba Qwen' }, { value: 'qwen', label: 'Alibaba Qwen' },
{ value: 'iflow', label: 'iFlow' }, { value: 'iflow', label: 'iFlow' },
{ value: 'kiro', label: 'Kiro (AWS)' },
{ value: 'copilot', label: 'GitHub Copilot' },
]; ];
export function CliproxyDialog({ open, onClose }: CliproxyDialogProps) { export function CliproxyDialog({ open, onClose }: CliproxyDialogProps) {
@@ -116,6 +116,7 @@ export function CliproxyHeader({
{ id: 'gemini', displayName: 'Gemini' }, { id: 'gemini', displayName: 'Gemini' },
{ id: 'codex', displayName: 'Codex' }, { id: 'codex', displayName: 'Codex' },
{ id: 'agy', displayName: 'Agy' }, { id: 'agy', displayName: 'Agy' },
{ id: 'kiro', displayName: 'Kiro' },
]; ];
const getProviderStatus = (providerId: string) => { const getProviderStatus = (providerId: string) => {
@@ -131,10 +132,8 @@ export function CliproxyHeader({
{/* Top row: Title and Login Buttons */} {/* Top row: Title and Login Buttons */}
<div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4"> <div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4">
<div> <div>
<h1 className="text-2xl font-bold tracking-tight">CLIProxy</h1> <h1 className="text-2xl font-bold tracking-tight">CLIProxy Plus</h1>
<p className="text-sm text-muted-foreground mt-1"> <p className="text-sm text-muted-foreground mt-1">CCS-level account management</p>
Manage OAuth providers and configuration
</p>
</div> </div>
{/* Login Buttons - Wrap on mobile */} {/* Login Buttons - Wrap on mobile */}
@@ -54,6 +54,8 @@ export function ProviderEditor({
codex: ['openai'], codex: ['openai'],
qwen: ['alibaba', 'qwen'], qwen: ['alibaba', 'qwen'],
iflow: ['iflow'], iflow: ['iflow'],
kiro: ['kiro', 'aws'],
copilot: ['github', 'copilot'],
}; };
const owners = ownerMap[provider.toLowerCase()] || [provider.toLowerCase()]; const owners = ownerMap[provider.toLowerCase()] || [provider.toLowerCase()];
return modelsData.models.filter((m) => return modelsData.models.filter((m) =>
@@ -18,6 +18,8 @@ const PROVIDER_IMAGES: Record<string, string> = {
agy: '/assets/providers/agy.png', agy: '/assets/providers/agy.png',
qwen: '/assets/providers/qwen-color.svg', qwen: '/assets/providers/qwen-color.svg',
iflow: '/assets/providers/iflow.png', iflow: '/assets/providers/iflow.png',
kiro: '/assets/providers/kiro.png',
copilot: '/assets/providers/copilot.svg',
}; };
/** Provider color configuration (for fallback only - no background for image logos) */ /** Provider color configuration (for fallback only - no background for image logos) */
@@ -28,6 +30,8 @@ const PROVIDER_CONFIG: Record<string, { text: string; letter: string }> = {
agy: { text: 'text-violet-600', letter: 'A' }, agy: { text: 'text-violet-600', letter: 'A' },
qwen: { text: 'text-cyan-600', letter: 'Q' }, qwen: { text: 'text-cyan-600', letter: 'Q' },
iflow: { text: 'text-indigo-600', letter: 'i' }, iflow: { text: 'text-indigo-600', letter: 'i' },
kiro: { text: 'text-teal-600', letter: 'K' },
copilot: { text: 'text-green-600', letter: 'C' },
}; };
/** Size configuration */ /** Size configuration */
+1 -1
View File
@@ -54,7 +54,7 @@ const navGroups = [
{ {
path: '/cliproxy', path: '/cliproxy',
icon: Zap, icon: Zap,
label: 'CLIProxy', label: 'CLIProxy Plus',
isCollapsible: true, isCollapsible: true,
children: [ children: [
{ path: '/cliproxy', label: 'Overview' }, { path: '/cliproxy', label: 'Overview' },
@@ -10,6 +10,8 @@ export const PROVIDERS: ProviderOption[] = [
{ id: 'agy', name: 'Antigravity', description: 'Antigravity AI models' }, { id: 'agy', name: 'Antigravity', description: 'Antigravity AI models' },
{ id: 'qwen', name: 'Alibaba Qwen', description: 'Qwen Code models' }, { id: 'qwen', name: 'Alibaba Qwen', description: 'Qwen Code models' },
{ id: 'iflow', name: 'iFlow', description: 'iFlow AI models' }, { id: 'iflow', name: 'iFlow', description: 'iFlow AI models' },
{ id: 'kiro', name: 'Kiro (AWS)', description: 'AWS CodeWhisperer models' },
{ id: 'copilot', name: 'GitHub Copilot', description: 'GitHub Copilot models' },
]; ];
export const ALL_STEPS = ['provider', 'auth', 'variant', 'success']; export const ALL_STEPS = ['provider', 'auth', 'variant', 'success'];
+4 -4
View File
@@ -47,20 +47,20 @@ export interface UpdateProfile {
export interface Variant { export interface Variant {
name: string; name: string;
provider: 'gemini' | 'codex' | 'agy' | 'qwen' | 'iflow'; provider: 'gemini' | 'codex' | 'agy' | 'qwen' | 'iflow' | 'kiro' | 'copilot';
settings: string; settings: string;
account?: string; account?: string;
} }
export interface CreateVariant { export interface CreateVariant {
name: string; name: string;
provider: 'gemini' | 'codex' | 'agy' | 'qwen' | 'iflow'; provider: 'gemini' | 'codex' | 'agy' | 'qwen' | 'iflow' | 'kiro' | 'copilot';
model?: string; model?: string;
account?: string; account?: string;
} }
export interface UpdateVariant { export interface UpdateVariant {
provider?: 'gemini' | 'codex' | 'agy' | 'qwen' | 'iflow'; provider?: 'gemini' | 'codex' | 'agy' | 'qwen' | 'iflow' | 'kiro' | 'copilot';
model?: string; model?: string;
account?: string; account?: string;
} }
@@ -69,7 +69,7 @@ export interface UpdateVariant {
export interface OAuthAccount { export interface OAuthAccount {
id: string; id: string;
email?: string; email?: string;
provider: 'gemini' | 'codex' | 'agy' | 'qwen' | 'iflow'; provider: 'gemini' | 'codex' | 'agy' | 'qwen' | 'iflow' | 'kiro' | 'copilot';
isDefault: boolean; isDefault: boolean;
tokenFile: string; tokenFile: string;
createdAt: string; createdAt: string;
+115
View File
@@ -151,4 +151,119 @@ export const MODEL_CATALOGS: Record<string, ProviderCatalog> = {
}, },
], ],
}, },
kiro: {
provider: 'kiro',
displayName: 'Kiro (AWS)',
defaultModel: 'kiro-claude-sonnet-4-5',
models: [
{
id: 'kiro-claude-opus-4-5',
name: 'Kiro Claude Opus 4.5',
description: 'Claude Opus 4.5 via Kiro (2.2x credit)',
presetMapping: {
default: 'kiro-claude-opus-4-5',
opus: 'kiro-claude-opus-4-5',
sonnet: 'kiro-claude-sonnet-4-5',
haiku: 'kiro-claude-haiku-4-5',
},
},
{
id: 'kiro-claude-sonnet-4-5',
name: 'Kiro Claude Sonnet 4.5',
description: 'Claude Sonnet 4.5 via Kiro (1.3x credit)',
presetMapping: {
default: 'kiro-claude-sonnet-4-5',
opus: 'kiro-claude-opus-4-5',
sonnet: 'kiro-claude-sonnet-4-5',
haiku: 'kiro-claude-haiku-4-5',
},
},
{
id: 'kiro-claude-sonnet-4',
name: 'Kiro Claude Sonnet 4',
description: 'Claude Sonnet 4 via Kiro (1.3x credit)',
presetMapping: {
default: 'kiro-claude-sonnet-4',
opus: 'kiro-claude-opus-4-5',
sonnet: 'kiro-claude-sonnet-4',
haiku: 'kiro-claude-haiku-4-5',
},
},
{
id: 'kiro-claude-haiku-4-5',
name: 'Kiro Claude Haiku 4.5',
description: 'Claude Haiku 4.5 via Kiro (0.4x credit)',
},
],
},
copilot: {
provider: 'copilot',
displayName: 'GitHub Copilot',
defaultModel: 'claude-sonnet-4.5',
models: [
{
id: 'claude-opus-4.5',
name: 'Claude Opus 4.5',
description: 'Anthropic Claude Opus 4.5 via GitHub Copilot',
presetMapping: {
default: 'claude-opus-4.5',
opus: 'claude-opus-4.5',
sonnet: 'claude-sonnet-4.5',
haiku: 'claude-haiku-4.5',
},
},
{
id: 'claude-sonnet-4.5',
name: 'Claude Sonnet 4.5',
description: 'Anthropic Claude Sonnet 4.5 via GitHub Copilot',
presetMapping: {
default: 'claude-sonnet-4.5',
opus: 'claude-opus-4.5',
sonnet: 'claude-sonnet-4.5',
haiku: 'claude-haiku-4.5',
},
},
{
id: 'claude-sonnet-4',
name: 'Claude Sonnet 4',
description: 'Anthropic Claude Sonnet 4 via GitHub Copilot',
},
{
id: 'claude-haiku-4.5',
name: 'Claude Haiku 4.5',
description: 'Anthropic Claude Haiku 4.5 via GitHub Copilot',
},
{
id: 'gpt-5.2',
name: 'GPT-5.2',
description: 'OpenAI GPT-5.2 via GitHub Copilot',
presetMapping: {
default: 'gpt-5.2',
opus: 'gpt-5.2',
sonnet: 'gpt-5.1',
haiku: 'gpt-5-mini',
},
},
{
id: 'gpt-5.1',
name: 'GPT-5.1',
description: 'OpenAI GPT-5.1 via GitHub Copilot',
},
{
id: 'gpt-5',
name: 'GPT-5',
description: 'OpenAI GPT-5 via GitHub Copilot',
},
{
id: 'gpt-5-mini',
name: 'GPT-5 Mini',
description: 'OpenAI GPT-5 Mini via GitHub Copilot',
},
{
id: 'gemini-3-pro',
name: 'Gemini 3 Pro',
description: 'Google Gemini 3 Pro via GitHub Copilot',
},
],
},
}; };
+6
View File
@@ -9,6 +9,8 @@ export const PROVIDER_ASSETS: Record<string, string> = {
agy: '/assets/providers/agy.png', agy: '/assets/providers/agy.png',
codex: '/assets/providers/openai.svg', codex: '/assets/providers/openai.svg',
qwen: '/assets/providers/qwen-color.svg', qwen: '/assets/providers/qwen-color.svg',
kiro: '/assets/providers/kiro.png',
copilot: '/assets/providers/copilot.svg',
}; };
// Provider brand colors // Provider brand colors
@@ -19,6 +21,8 @@ export const PROVIDER_COLORS: Record<string, string> = {
vertex: '#4285F4', vertex: '#4285F4',
iflow: '#f94144', iflow: '#f94144',
qwen: '#6236FF', qwen: '#6236FF',
kiro: '#4d908e', // Dark Cyan (AWS-inspired)
copilot: '#43aa8b', // Seaweed (GitHub-inspired)
}; };
// Provider display names // Provider display names
@@ -29,6 +33,8 @@ const PROVIDER_NAMES: Record<string, string> = {
vertex: 'Vertex AI', vertex: 'Vertex AI',
iflow: 'iFlow', iflow: 'iFlow',
qwen: 'Qwen', qwen: 'Qwen',
kiro: 'Kiro (AWS)',
copilot: 'GitHub Copilot',
}; };
// Map provider to display name // Map provider to display name
+2
View File
@@ -27,6 +27,8 @@ const PROVIDER_COLORS: Record<string, string> = {
vertex: '#577590', // Blue Slate vertex: '#577590', // Blue Slate
iflow: '#f94144', // Strawberry iflow: '#f94144', // Strawberry
qwen: '#f9c74f', // Tuscan qwen: '#f9c74f', // Tuscan
kiro: '#4d908e', // Dark Cyan (AWS-inspired)
copilot: '#43aa8b', // Seaweed (GitHub-inspired)
}; };
// Status colors (from Analytics Cost breakdown) - darker for light theme contrast // Status colors (from Analytics Cost breakdown) - darker for light theme contrast
+1 -1
View File
@@ -235,7 +235,7 @@ export function CliproxyPage() {
<div className="flex items-center justify-between mb-1"> <div className="flex items-center justify-between mb-1">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Zap className="w-5 h-5 text-primary" /> <Zap className="w-5 h-5 text-primary" />
<h1 className="font-semibold">CLIProxy</h1> <h1 className="font-semibold">CLIProxy Plus</h1>
</div> </div>
<Button <Button
variant="ghost" variant="ghost"