import Link from 'next/link'; import { ArrowRight, BookOpen, Settings2, Star, Wrench, } from 'lucide-react'; import { notFound } from 'next/navigation'; import { DesktopDemo } from '@/components/hero/DesktopDemo'; import { DownloadButton } from '@/components/hero/DownloadButton'; import { blogSource, formatBlogDate, sortBlogPages } from '@/lib/blog'; import { formatStars, getRepoStats } from '@/lib/github'; import { isLanguage, type Language } from '@/lib/i18n'; import { releaseUrl, repositoryUrl } from '@/lib/shared'; const copy: Record< Language, { pillReleased: (version: string) => string; pillFallback: string; title: string; subtitle: string; readDocs: string; flow: [string, string, string]; docsEyebrow: string; docsTitle: string; viewAll: string; docs: { icon: typeof BookOpen; title: string; description: string; href: string }[]; blogEyebrow: string; blogTitle: string; } > = { zh: { pillReleased: (version) => `${version} 已发布 · 开源 · 本地运行`, pillFallback: '开源 · 本地运行 · 自由接入', title: 'Cursor 服务端的开源替代', subtitle: '在本机运行自己的模型网关,用自己的 API Key 接入 OpenAI、Anthropic 兼容服务或自定义端点,完整保留 Cursor Agent 的工具调用、Skills 和 MCP。', readDocs: '阅读文档', flow: ['Cursor 客户端', 'Cursor Byok 本地服务', '你的模型 API(OpenAI / Anthropic 兼容)'], docsEyebrow: 'DOCUMENTATION', docsTitle: '文档', viewAll: '查看全部', docs: [ { icon: BookOpen, title: '快速开始', description: '完成安装、初始化和第一次模型调用。', href: '/docs', }, { icon: Settings2, title: '模型配置', description: '配置协议、服务地址、凭据和生成参数。', href: '/docs/model-configuration', }, { icon: Wrench, title: '故障排查', description: '解决证书、连接和模型测试问题。', href: '/docs/troubleshooting', }, ], blogEyebrow: 'DEVELOPER BLOG', blogTitle: '开发者博客', }, en: { pillReleased: (version) => `${version} released · Open source · Runs locally`, pillFallback: 'Open source · Runs locally · Any provider', title: "The open-source alternative to Cursor's backend", subtitle: 'Run your own model gateway locally, connect OpenAI- and Anthropic-compatible services or custom endpoints with your own API keys, and keep Cursor Agent tool calling, Skills, and MCP intact.', readDocs: 'Read the docs', flow: ['Cursor client', 'Cursor Byok local service', 'Your model API (OpenAI / Anthropic compatible)'], docsEyebrow: 'DOCUMENTATION', docsTitle: 'Documentation', viewAll: 'View all', docs: [ { icon: BookOpen, title: 'Quick Start', description: 'Install, initialize, and make your first model call.', href: '/docs', }, { icon: Settings2, title: 'Model Configuration', description: 'Configure protocols, server addresses, credentials, and parameters.', href: '/docs/model-configuration', }, { icon: Wrench, title: 'Troubleshooting', description: 'Resolve certificate, connection, and model test issues.', href: '/docs/troubleshooting', }, ], blogEyebrow: 'DEVELOPER BLOG', blogTitle: 'Developer Blog', }, }; export default async function HomePage(props: PageProps<'/[lang]'>) { const { lang } = await props.params; if (!isLanguage(lang)) notFound(); const t = copy[lang]; const prefix = `/${lang}`; const posts = sortBlogPages(blogSource.getPages(lang)).slice(0, 3); const { stars, version } = await getRepoStats(); return (
{t.flow[0]} {t.flow[1]} {t.flow[2]}

{t.docsEyebrow}

{t.docsTitle}

{t.viewAll}
{t.docs.map(({ icon: Icon, title, description, href }) => (

{title}

{description}

))}

{t.blogEyebrow}

{t.blogTitle}

{t.viewAll}
{posts.map((post) => (

{post.data.title}

{post.data.description}

))}
); } function GitHubIcon({ className }: { className?: string }) { return ( ); }