diff --git a/ui/src/pages/home.tsx b/ui/src/pages/home.tsx
index ca463e7f..ae05f753 100644
--- a/ui/src/pages/home.tsx
+++ b/ui/src/pages/home.tsx
@@ -1,258 +1,382 @@
import { useNavigate } from 'react-router-dom';
import { Card, CardContent } from '@/components/ui/card';
-import { StatCard } from '@/components/stat-card';
-import { HeroSection } from '@/components/hero-section';
-import { QuickCommands } from '@/components/quick-commands';
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
import { Skeleton } from '@/components/ui/skeleton';
+import { Badge } from '@/components/ui/badge';
import {
Key,
Zap,
Users,
- Activity,
- Plus,
+ Search,
Stethoscope,
- BookOpen,
- FolderOpen,
AlertTriangle,
+ Terminal,
+ ArrowRight,
+ Command,
+ Sparkles,
} from 'lucide-react';
import { useOverview } from '@/hooks/use-overview';
import { useSharedSummary } from '@/hooks/use-shared';
+import { cn } from '@/lib/utils';
-const HEALTH_VARIANTS = {
- ok: 'success',
- warning: 'warning',
- error: 'error',
+const HEALTH_STATUS = {
+ ok: { label: 'Operational', class: 'bg-emerald-500/20 text-emerald-500 border-emerald-500/30' },
+ warning: { label: 'Degraded', class: 'bg-amber-500/20 text-amber-500 border-amber-500/30' },
+ error: { label: 'Issues', class: 'bg-red-500/20 text-red-500 border-red-500/30' },
} as const;
+// Three Pillars configuration - matches README branding
+const THREE_PILLARS = [
+ {
+ id: 'api',
+ title: 'API Keys',
+ description: 'Configure GLM, Kimi with your own API keys',
+ icon: Key,
+ path: '/api',
+ gradient: 'from-orange-500/20 to-amber-500/10',
+ iconBg: 'bg-orange-500/20 text-orange-500',
+ },
+ {
+ id: 'oauth',
+ title: 'OAuth Providers',
+ description: 'Gemini, Codex, Antigravity - zero config',
+ icon: Zap,
+ path: '/cliproxy',
+ gradient: 'from-blue-500/20 to-cyan-500/10',
+ iconBg: 'bg-blue-500/20 text-blue-500',
+ },
+ {
+ id: 'accounts',
+ title: 'Multiple Accounts',
+ description: 'Isolated Claude instances for work & personal',
+ icon: Users,
+ path: '/accounts',
+ gradient: 'from-violet-500/20 to-purple-500/10',
+ iconBg: 'bg-violet-500/20 text-violet-500',
+ },
+];
+
+// Quick launch shortcuts
+const QUICK_LAUNCH = [
+ { key: 'G', label: 'Gemini', command: 'ccs gemini' },
+ { key: 'C', label: 'Codex', command: 'ccs codex' },
+ { key: 'A', label: 'Agy', command: 'ccs agy' },
+];
+
export function HomePage() {
const navigate = useNavigate();
const { data: overview, isLoading: isOverviewLoading } = useOverview();
const { data: shared, isLoading: isSharedLoading } = useSharedSummary();
if (isOverviewLoading || isSharedLoading) {
- return (
-
- {/* Hero Skeleton */}
-
-
- {/* Stats Skeleton */}
-
- {[1, 2, 3, 4].map((i) => (
-
- ))}
-
-
- {/* Quick Actions Skeleton */}
-
-
- {/* Quick Commands Skeleton */}
-
-
-
- {[1, 2, 3, 4].map((i) => (
-
- ))}
-
-
-
- );
+ return ;
}
- const healthVariant = overview?.health
- ? HEALTH_VARIANTS[overview.health.status as keyof typeof HEALTH_VARIANTS]
- : undefined;
+ const healthInfo = overview?.health?.status
+ ? HEALTH_STATUS[overview.health.status as keyof typeof HEALTH_STATUS]
+ : HEALTH_STATUS.ok;
+
+ const pillarCounts = {
+ api: overview?.profiles ?? 0,
+ oauth: overview?.cliproxy ?? 0,
+ accounts: overview?.accounts ?? 0,
+ };
return (
-
- {/* Hero Section */}
-
+
+ {/* Gradient Mesh Background */}
+
- {/* Configuration Warning */}
- {shared?.symlinkStatus && !shared.symlinkStatus.valid && (
-
-
- Configuration Required
- {shared.symlinkStatus.message}
-
- )}
-
- {/* Stats Grid */}
-
-
-
System Status
-
-
- navigate('/api')}
- />
- navigate('/cliproxy')}
- />
- navigate('/accounts')}
- />
- navigate('/health')}
- />
-
-
-
-
- {/* Left Column: Quick Actions & Shared Data */}
-
- {/* Quick Actions */}
-
-
-
Quick Actions
-
-
-
navigate('/api')}
- >
-
-
-
-
New Profile
-
Create a new API profile
-
-
-
-
-
navigate('/health')}
- >
-
-
-
-
-
-
Run Doctor
-
Check system health
-
-
-
-
-
window.open('https://github.com/kaitranntt/ccs', '_blank')}
- >
-
-
-
-
-
-
Documentation
-
View guides & reference
-
-
-
-
-
navigate('/shared')}
- >
-
-
-
-
-
-
Shared Data
-
Manage resources
-
-
-
-
-
-
- {/* Shared Data Stats */}
-
-
-
Resource Summary
-
-
-
-
-
-
- {shared?.commands ?? 0}
-
- Commands
-
-
-
- {shared?.skills ?? 0}
-
- Skills
-
-
-
- {shared?.agents ?? 0}
-
-
Agents
+
+ {/* Hero Header */}
+
+
+
+
+
+
+
+
+
+
+
CCS
+
Multi-Account AI Management
+
-
-
-
-
+
+
+ v{overview?.version ?? '0.0.0'}
+
+
+
+ {healthInfo.label}
+
+
+
- {/* Right Column: Quick Commands */}
-
-
Command Palette
-
+ {/* Command Palette Search Bar */}
+
navigate('/health')}>
+
+
+
+ Search commands, profiles, or run diagnostics...
+
+
+ K
+
+
+
+
+
+
+
+ {/* Configuration Warning */}
+ {shared?.symlinkStatus && !shared.symlinkStatus.valid && (
+
+
+ Configuration Required
+ {shared.symlinkStatus.message}
+
+ )}
+
+ {/* Three Pillars Section */}
+
+
+
The Three Pillars
+ — What do you want to do?
+
+
+ {THREE_PILLARS.map((pillar) => {
+ const Icon = pillar.icon;
+ const count = pillarCounts[pillar.id as keyof typeof pillarCounts];
+ return (
+
navigate(pillar.path)}
+ >
+
+
+
+
+ {pillar.title}
+
+
+ {pillar.description}
+
+
+
+
+
+ );
+ })}
+
+
+
+ {/* Quick Launch & Health Grid */}
+
+ {/* Quick Launch */}
+
+
+
+
+
+ Quick Launch
+
+ Click to copy command
+
+
+ {QUICK_LAUNCH.map((item) => (
+
+ ))}
+ {/* Account shortcuts */}
+ {overview?.accounts && overview.accounts > 0 && (
+ <>
+
+ >
+ )}
+ {/* Doctor shortcut */}
+
+
+
+
+
+ {/* Health & Resources */}
+
+
+ {/* Health Summary */}
+
+
+ System Health
+
+
navigate('/health')}
+ >
+
+
+
+ {overview?.health?.passed ?? 0}/{overview?.health?.total ?? 0}
+
+
+
checks passed
+
+
+
+ {/* Resources Summary */}
+
+
+ Shared Resources
+
+
navigate('/shared')}
+ >
+
+
+ {shared?.commands ?? 0}
+
+ cmds
+
+
+
+ {shared?.skills ?? 0}
+
+ skills
+
+
+
+ {shared?.agents ?? 0}
+
+ agents
+
+
+
+
+
+
+
+
+ );
+}
+
+// Skeleton loader component
+function HomePageSkeleton() {
+ return (
+
+ {/* Hero Skeleton */}
+
+
+ {/* Pillars Skeleton */}
+
+ {[1, 2, 3].map((i) => (
+
+ ))}
+
+
+ {/* Quick Launch Skeleton */}
+
+
+
+
+ {[1, 2, 3, 4, 5, 6].map((i) => (
+
+ ))}
+
+
+
+
+
+
+
+ {[1, 2, 3].map((i) => (
+
+ ))}
+