Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
8f1fd99
docs: overhaul and restructure project documentation
ericyangpan Jan 6, 2026
20c65ea
docs(performance): update audit doc to reflect current implementation…
ericyangpan Jan 6, 2026
676557e
refactor(lib): add manifest registry abstraction and enhance API
ericyangpan Jan 6, 2026
f97257b
feat(i18n): add translations for open-source-rank and search pages
ericyangpan Jan 9, 2026
1a2736e
chore(manifests): update manifest data across all categories
ericyangpan Jan 9, 2026
ae59bbe
refactor(app): update application pages and components
ericyangpan Jan 9, 2026
30de197
feat(content): update articles, docs, FAQ, and manifesto
ericyangpan Jan 9, 2026
ba593b8
feat(i18n): update translations across all active locales
ericyangpan Jan 9, 2026
2f86bf9
chore(docs): update project documentation and test files
ericyangpan Jan 9, 2026
e5a9b63
docs: add model benchmark and specification reference documentation
ericyangpan Jan 10, 2026
2f4c92e
feat(manifests): add new model manifests for latest AI models
ericyangpan Jan 10, 2026
d33b77d
feat(manifests): add provider manifests for major AI vendors
ericyangpan Jan 10, 2026
03c9c68
feat(manifests): update schema, mapping, and existing model manifests
ericyangpan Jan 10, 2026
249c7ad
refactor(types): update type system and core infrastructure
ericyangpan Jan 10, 2026
a0566aa
refactor(lib): update library utilities and generators
ericyangpan Jan 10, 2026
8613838
refactor(app): update application pages and routes
ericyangpan Jan 10, 2026
3e8695a
refactor(components): update UI components
ericyangpan Jan 10, 2026
9185b95
feat(i18n): add landscape page translations for all locales
ericyangpan Jan 10, 2026
6a0f086
feat(i18n): update translations and content across all locales
ericyangpan Jan 10, 2026
f3f7831
test: update validation tests and i18n skill documentation
ericyangpan Jan 10, 2026
fb1c8f2
build: add model comparison script
ericyangpan Jan 10, 2026
3f01c73
chore(schema): add outputModalities field
ericyangpan Jan 11, 2026
6625b7f
chore(manifests): add outputModalities to model CLIs
ericyangpan Jan 11, 2026
810f230
refactor(i18n): migrate components to hierarchical namespace
ericyangpan Jan 11, 2026
f1baaff
refactor(i18n): migrate pages to hierarchical namespace
ericyangpan Jan 11, 2026
a971817
refactor(i18n): migrate library files to hierarchical namespace
ericyangpan Jan 11, 2026
d72bfb7
refactor(i18n): restructure translation files hierarchy
ericyangpan Jan 11, 2026
1e1b158
docs: update project configuration and documentation
ericyangpan Jan 11, 2026
f3e5539
chore: remove temporary .bak files from repository
ericyangpan Jan 11, 2026
402ac54
refactor(i18n): update component code to use tComponent + tShared pat…
ericyangpan Jan 11, 2026
ddfdd52
refactor(i18n): consolidate translation files and remove duplicate keys
ericyangpan Jan 11, 2026
2bcaf96
docs(i18n): add i18n architecture rules and validation scripts
ericyangpan Jan 11, 2026
7d2fefb
docs(i18n): add i18n architecture rules and validation scripts
ericyangpan Jan 14, 2026
36316c3
refactor(metadata): type-safe generators with dedicated parameter int…
ericyangpan Jan 14, 2026
4e06d8e
refactor(pages): use tComponent + tShared translation pattern
ericyangpan Jan 14, 2026
4aa700f
refactor(product-components): use tComponent + tShared translation pa…
ericyangpan Jan 14, 2026
1420a1d
refactor(i18n): consolidate translation files and remove duplicate keys
ericyangpan Jan 14, 2026
78df09b
Merge branch 'main' into develop
ericyangpan Jan 15, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
refactor(lib): update library utilities and generators
Update metadata generators, pricing utilities, benchmark handling, and regenerate metadata/model/provider indexes to align with updated manifest schemas.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
  • Loading branch information
ericyangpan and claude committed Jan 10, 2026
commit a0566aaf13c3d1b4c1d160373c4849a5835f675d
2 changes: 1 addition & 1 deletion src/lib/benchmarks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export function formatBenchmarkValue(key: string, value: number): string {
* @param benchmarks - The benchmarks object to check
* @returns True if at least one benchmark has a non-null value
*/
export function hasBenchmarks(benchmarks: Record<string, number | null> | undefined): boolean {
export function hasBenchmarks(benchmarks: object | null | undefined): boolean {
if (!benchmarks) return false
return Object.values(benchmarks).some(value => value !== null && value !== undefined)
}
Expand Down
68 changes: 34 additions & 34 deletions src/lib/generated/metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,64 +46,64 @@ export const articlesMetadata: Record<string, ArticleMetadata[]> = {
es: [
{
slug: 'getting-started-with-ai-coding',
title: 'Getting Started with AI Coding: A Comprehensive Guide',
title: 'Comenzando con AI Coding: Una Guía Completa',
description:
'Learn how to set up your first AI-powered development environment with IDEs, CLIs, and the essential tools you need to boost your coding productivity.',
'Aprende cómo configurar tu primer entorno de desarrollo impulsado por IA con IDEs, CLIs y las herramientas esenciales que necesitas para impulsar tu productividad de programación.',
date: '2025-01-15',
},
{
slug: 'mcp-servers-explained',
title: 'Understanding MCP Servers: The Future of AI Context',
title: 'Entendiendo los Servidores MCP: El Futuro del Contexto de IA',
description:
'Deep dive into Model Context Protocol servers, how they work, and why they are crucial for building intelligent AI coding assistants that truly understand your project.',
'Un análisis profundo de los servidores del Protocolo de Contexto de Modelo, cómo funcionan y por qué son cruciales para construir asistentes de programación con IA que realmente entiendan tu proyecto.',
date: '2025-01-10',
},
],
fr: [
{
slug: 'getting-started-with-ai-coding',
title: 'Getting Started with AI Coding: A Comprehensive Guide',
title: 'Commencer avec AI Coding : Un Guide Complet',
description:
'Learn how to set up your first AI-powered development environment with IDEs, CLIs, and the essential tools you need to boost your coding productivity.',
"Apprenez comment configurer votre premier environnement de développement propulsé par l'IA avec des IDE, des CLI et les outils essentiels dont vous avez besoin pour stimuler votre productivité de programmation.",
date: '2025-01-15',
},
{
slug: 'mcp-servers-explained',
title: 'Understanding MCP Servers: The Future of AI Context',
title: "Comprendre les Serveurs MCP : L'Avenir du Contexte IA",
description:
'Deep dive into Model Context Protocol servers, how they work, and why they are crucial for building intelligent AI coding assistants that truly understand your project.',
'Un approfondissement des serveurs du Protocole de Contexte de Modèle, comment ils fonctionnent et pourquoi ils sont cruciaux pour construire des assistants de programmation IA intelligents qui comprennent vraiment votre projet.',
date: '2025-01-10',
},
],
id: [
{
slug: 'getting-started-with-ai-coding',
title: 'Getting Started with AI Coding: A Comprehensive Guide',
title: 'Memulai AI Coding: Panduan Lengkap',
description:
'Learn how to set up your first AI-powered development environment with IDEs, CLIs, and the essential tools you need to boost your coding productivity.',
'Pelajari cara menyiapkan lingkungan pengembangan bertenaga AI pertama Anda dengan IDE, CLI, dan alat penting yang Anda butuhkan untuk meningkatkan produktivitas pemrograman Anda.',
date: '2025-01-15',
},
{
slug: 'mcp-servers-explained',
title: 'Understanding MCP Servers: The Future of AI Context',
title: 'Memahami Server MCP: Masa Depan Konteks AI',
description:
'Deep dive into Model Context Protocol servers, how they work, and why they are crucial for building intelligent AI coding assistants that truly understand your project.',
'Eksplorasi mendalam tentang server Model Context Protocol, cara kerjanya, dan mengapa mereka penting untuk membangun asisten pemrograman AI cerdas yang benar-benar memahami proyek Anda.',
date: '2025-01-10',
},
],
ja: [
{
slug: 'getting-started-with-ai-coding',
title: 'Getting Started with AI Coding: A Comprehensive Guide',
title: 'AIコーディングの始め方:包括ガイド',
description:
'Learn how to set up your first AI-powered development environment with IDEs, CLIs, and the essential tools you need to boost your coding productivity.',
'IDE、CLI、コーディング生産性を向上させる必須ツールを使って、初めてのAI搭載開発環境を設定する方法を学びます。',
date: '2025-01-15',
},
{
slug: 'mcp-servers-explained',
title: 'Understanding MCP Servers: The Future of AI Context',
title: 'MCPサーバーの理解:AIコンテキストの未来',
description:
'Deep dive into Model Context Protocol servers, how they work, and why they are crucial for building intelligent AI coding assistants that truly understand your project.',
'モデルコンテキストプロトコルサーバーの詳細、その仕組み、およびプロジェクトを真に理解するインテリジェントなAIコーディングアシスタントを構築するために重要な理由について詳しく解説します。',
date: '2025-01-10',
},
],
Expand All @@ -126,48 +126,48 @@ export const articlesMetadata: Record<string, ArticleMetadata[]> = {
pt: [
{
slug: 'getting-started-with-ai-coding',
title: 'Getting Started with AI Coding: A Comprehensive Guide',
title: 'Começando com AI Coding: Um Guia Completo',
description:
'Learn how to set up your first AI-powered development environment with IDEs, CLIs, and the essential tools you need to boost your coding productivity.',
'Aprenda como configurar o seu primeiro ambiente de desenvolvimento alimentado por IA com IDEs, CLIs e as ferramentas essenciais que você precisa para aumentar a sua produtividade de programação.',
date: '2025-01-15',
},
{
slug: 'mcp-servers-explained',
title: 'Understanding MCP Servers: The Future of AI Context',
title: 'Entendendo Servidores MCP: O Futuro do Contexto de IA',
description:
'Deep dive into Model Context Protocol servers, how they work, and why they are crucial for building intelligent AI coding assistants that truly understand your project.',
'Um mergulho profundo em servidores do Protocolo de Contexto de Modelo, como funcionam e por que são cruciais para construir assistentes de programação com IA inteligentes que realmente entendem o seu projeto.',
date: '2025-01-10',
},
],
ru: [
{
slug: 'getting-started-with-ai-coding',
title: 'Getting Started with AI Coding: A Comprehensive Guide',
title: 'Начало работы с AI Coding: Полное руководство',
description:
'Learn how to set up your first AI-powered development environment with IDEs, CLIs, and the essential tools you need to boost your coding productivity.',
'Узнайте, как настроить вашу первую среду разработки на базе ИИ с использованием IDE, CLI и необходимых инструментов для повышения вашей продуктивности программирования.',
date: '2025-01-15',
},
{
slug: 'mcp-servers-explained',
title: 'Understanding MCP Servers: The Future of AI Context',
title: 'Понимание серверов MCP: Будущее контекста ИИ',
description:
'Deep dive into Model Context Protocol servers, how they work, and why they are crucial for building intelligent AI coding assistants that truly understand your project.',
'Глубокое погружение в серверы протокола контекста модели, как они работают и почему они критически важны для создания интеллектуальных ассистентов программирования на базе ИИ, которые действительно понимают ваш проект.',
date: '2025-01-10',
},
],
tr: [
{
slug: 'getting-started-with-ai-coding',
title: 'Getting Started with AI Coding: A Comprehensive Guide',
title: 'Yapay Zeka Kodlamaya Başlarken: Kapsamlı Bir Rehber',
description:
'Learn how to set up your first AI-powered development environment with IDEs, CLIs, and the essential tools you need to boost your coding productivity.',
"IDE'ler, CLI'ler ve kodlama verimliliğinizi artırmak için ihtiyacınız olan temel araçları kullanarak yapay zeka destekli ilk geliştirme ortamınızı nasıl kuracağınızı öğrenin.",
date: '2025-01-15',
},
{
slug: 'mcp-servers-explained',
title: 'Understanding MCP Servers: The Future of AI Context',
title: 'MCP Sunucularını Anlamak: Yapay Zeka Bağlamının Geleceği',
description:
'Deep dive into Model Context Protocol servers, how they work, and why they are crucial for building intelligent AI coding assistants that truly understand your project.',
'Model Bağlam Protokolü sunucularını, nasıl çalıştıklarını ve projenizi gerçekten anlayan akıllı yapay zeka kodlama asistanları oluşturmak için neden kritik olduklarını derinlemesine anlayın.',
date: '2025-01-10',
},
],
Expand All @@ -190,16 +190,16 @@ export const articlesMetadata: Record<string, ArticleMetadata[]> = {
'zh-Hant': [
{
slug: 'getting-started-with-ai-coding',
title: 'Getting Started with AI Coding: A Comprehensive Guide',
title: 'AI 編碼入門:綜合指南',
description:
'Learn how to set up your first AI-powered development environment with IDEs, CLIs, and the essential tools you need to boost your coding productivity.',
'學習如何使用 IDE、命令列和必備工具搭建你的第一個 AI 驅動開發環境,提升編碼生產力。',
date: '2025-01-15',
},
{
slug: 'mcp-servers-explained',
title: 'Understanding MCP Servers: The Future of AI Context',
title: '理解 MCP 伺服器:AI 上下文的未來',
description:
'Deep dive into Model Context Protocol servers, how they work, and why they are crucial for building intelligent AI coding assistants that truly understand your project.',
'深入了解模型上下文協議伺服器的工作原理,以及為什麼它們對構建真正理解你項目的智能 AI 編碼助手至關重要。',
date: '2025-01-10',
},
],
Expand Down Expand Up @@ -1110,7 +1110,7 @@ export const stackCounts: Record<string, number> = {
ides: 13,
clis: 20,
extensions: 15,
models: 26,
'model-providers': 7,
models: 32,
'model-providers': 13,
vendors: 36,
}
16 changes: 14 additions & 2 deletions src/lib/generated/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,32 @@
import ClaudeHaiku45 from '../../../manifests/models/claude-haiku-4-5.json'
import ClaudeOpus4 from '../../../manifests/models/claude-opus-4.json'
import ClaudeOpus41 from '../../../manifests/models/claude-opus-4-1.json'
import ClaudeOpus45 from '../../../manifests/models/claude-opus-4-5.json'
import ClaudeSonnet4 from '../../../manifests/models/claude-sonnet-4.json'
import ClaudeSonnet45 from '../../../manifests/models/claude-sonnet-4-5.json'
import Composer from '../../../manifests/models/composer.json'
import DeepseekR1 from '../../../manifests/models/deepseek-r1.json'
import DeepseekV3Terminus from '../../../manifests/models/deepseek-v3-terminus.json'
import Gemini25Flash from '../../../manifests/models/gemini-2-5-flash.json'
import Gemini25Pro from '../../../manifests/models/gemini-2-5-pro.json'
import Gemini3Flash from '../../../manifests/models/gemini-3-flash.json'
import Gemini3Pro from '../../../manifests/models/gemini-3-pro.json'
import Glm46 from '../../../manifests/models/glm-4-6.json'
import Glm46v from '../../../manifests/models/glm-4-6v.json'
import Glm47 from '../../../manifests/models/glm-4-7.json'
import Gpt41 from '../../../manifests/models/gpt-4-1.json'
import Gpt4o from '../../../manifests/models/gpt-4o.json'
import Gpt5 from '../../../manifests/models/gpt-5.json'
import Gpt51 from '../../../manifests/models/gpt-5-1.json'
import Gpt51Codex from '../../../manifests/models/gpt-5-1-codex.json'
import Gpt52 from '../../../manifests/models/gpt-5-2.json'
import Gpt5Codex from '../../../manifests/models/gpt-5-codex.json'
import GrokCodeFast1 from '../../../manifests/models/grok-code-fast-1.json'
import KatCoderProV1 from '../../../manifests/models/kat-coder-pro-v1.json'
import KimiK20905 from '../../../manifests/models/kimi-k2-0905.json'
import Llama4Maverick from '../../../manifests/models/llama-4-maverick.json'
import KimiK2Thinking from '../../../manifests/models/kimi-k2-thinking.json'
import MinimaxM2 from '../../../manifests/models/minimax-m2.json'
import MinimaxM21 from '../../../manifests/models/minimax-m2-1.json'
import Qwen3Coder30bA3b from '../../../manifests/models/qwen3-coder-30b-a3b.json'
import Qwen3Coder480bA35b from '../../../manifests/models/qwen3-coder-480b-a35b.json'
import Qwen3CoderPlus from '../../../manifests/models/qwen3-coder-plus.json'
Expand All @@ -36,26 +42,32 @@ export const modelsData = [
ClaudeHaiku45,
ClaudeOpus4,
ClaudeOpus41,
ClaudeOpus45,
ClaudeSonnet4,
ClaudeSonnet45,
Composer,
DeepseekR1,
DeepseekV3Terminus,
Gemini25Flash,
Gemini25Pro,
Gemini3Flash,
Gemini3Pro,
Glm46,
Glm46v,
Glm47,
Gpt41,
Gpt4o,
Gpt5,
Gpt51,
Gpt51Codex,
Gpt52,
Gpt5Codex,
GrokCodeFast1,
KatCoderProV1,
KimiK20905,
Llama4Maverick,
KimiK2Thinking,
MinimaxM2,
MinimaxM21,
Qwen3Coder30bA3b,
Qwen3Coder480bA35b,
Qwen3CoderPlus,
Expand Down
14 changes: 13 additions & 1 deletion src/lib/generated/providers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,37 @@
* Do not edit manually - run the script to regenerate
*/

import Alibaba from '../../../manifests/providers/alibaba.json'
import Anthropic from '../../../manifests/providers/anthropic.json'
import Deepseek from '../../../manifests/providers/deepseek.json'
import Google from '../../../manifests/providers/google.json'
import Kwaikatonai from '../../../manifests/providers/kwaikatonai.json'
import Meta from '../../../manifests/providers/meta.json'
import Minimax from '../../../manifests/providers/minimax.json'
import Moonshot from '../../../manifests/providers/moonshot.json'
import Openai from '../../../manifests/providers/openai.json'
import Openrouter from '../../../manifests/providers/openrouter.json'
import Siliconflow from '../../../manifests/providers/siliconflow.json'
import Xai from '../../../manifests/providers/xai.json'
import ZAi from '../../../manifests/providers/z-ai.json'
import type { ManifestProvider } from '../../types/manifests'

export const providersData = [
Alibaba,
Anthropic,
Deepseek,
Google,
Kwaikatonai,
Meta,
Minimax,
Moonshot,
Openai,
Openrouter,
Siliconflow,
Xai,
ZAi,
] as unknown as ManifestProvider[]

export type Provider = typeof Deepseek
export type Provider = typeof Alibaba

export default providersData
29 changes: 15 additions & 14 deletions src/lib/metadata/generators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,10 @@ export async function generateListPageMetadata(options: {
}): Promise<Metadata> {
const { locale, category, translationNamespace, additionalKeywords = [] } = options

const t = await getTranslations({ locale, namespace: translationNamespace })
const tPage = await getTranslations({ locale, namespace: translationNamespace })

const translatedTitle = t('title')
const description = t('subtitle')
const translatedTitle = tPage('title')
const description = tPage('subtitle')

// Build SEO-optimized title
const categoryExamples = CATEGORY_EXAMPLES[category as keyof typeof CATEGORY_EXAMPLES]
Expand Down Expand Up @@ -165,7 +165,7 @@ export async function generateSoftwareDetailMetadata(options: {
description: string
vendor: string
platforms?: Array<{ os: string }> | string[]
pricing?: Array<{ value: number | null; currency: string | null; per: string | null }>
pricing?: Array<{ value: number | null; currency?: string | null; per?: string | null }>
license?: string
}
typeDescription: string
Expand Down Expand Up @@ -242,25 +242,26 @@ export async function generateModelDetailMetadata(options: {
}): Promise<Metadata> {
const { locale, slug, model, translationNamespace } = options

const t = await getTranslations({ locale, namespace: translationNamespace })
const tPage = await getTranslations({ locale, namespace: translationNamespace })

// Build title with model-specific translation
const title = `${model.name} - ${t('metaTitle')}`
const title = `${model.name} - ${tPage('metaTitle')}`

// Build description with model specs
const specs: string[] = []
if (model.size) specs.push(`${t('modelSize')}: ${model.size}`)
if (model.size) specs.push(`${tPage('modelSize')}: ${model.size}`)
if (model.contextWindow)
specs.push(`${t('contextWindow')}: ${formatTokenCount(model.contextWindow)} tokens`)
if (model.maxOutput) specs.push(`${t('maxOutput')}: ${formatTokenCount(model.maxOutput)} tokens`)
specs.push(`${tPage('contextWindow')}: ${formatTokenCount(model.contextWindow)} tokens`)
if (model.maxOutput)
specs.push(`${tPage('maxOutput')}: ${formatTokenCount(model.maxOutput)} tokens`)

const pricingDisplay = model.tokenPricing?.input
? `$${model.tokenPricing.input}/M tokens`
: model.tokenPricing?.output
? `$${model.tokenPricing.output}/M tokens`
: null

if (pricingDisplay) specs.push(`${t('pricing')}: ${pricingDisplay}`)
if (pricingDisplay) specs.push(`${tPage('pricing')}: ${pricingDisplay}`)

const description = `${model.name} by ${model.vendor}. ${specs.join('. ')}. ${model.description}`

Expand All @@ -273,7 +274,7 @@ export async function generateModelDetailMetadata(options: {
])

// Social media titles
const socialTitle = `${model.name} - ${t('metaTitle')}`
const socialTitle = `${model.name} - ${tPage('metaTitle')}`

// Use common metadata builder
// Note: OG and Twitter images are automatically detected from opengraph-image.tsx files
Expand Down Expand Up @@ -314,9 +315,9 @@ export async function generateComparisonMetadata(options: {

if (translationNamespace) {
try {
const t = await getTranslations({ locale, namespace: translationNamespace })
title = `${t('title')} - ${categoryName} Comparison | ${METADATA_DEFAULTS.siteName}`
description = t('description')
const tPage = await getTranslations({ locale, namespace: translationNamespace })
title = `${tPage('title')} - ${categoryName} Comparison | ${METADATA_DEFAULTS.siteName}`
description = tPage('description')
} catch {
// Fallback to default English text if translations not available
title = `Compare ${categoryName} - Side-by-Side Comparison | ${METADATA_DEFAULTS.siteName}`
Expand Down
4 changes: 3 additions & 1 deletion src/lib/metadata/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,9 @@ export function buildAlternates(options: {
* Format price for display in descriptions
*/
export function formatPriceForDescription(
pricing: Array<{ value: number | null; currency: string | null; per: string | null }> | undefined
pricing:
| Array<{ value: number | null; currency?: string | null; per?: string | null }>
| undefined
): string | null {
if (!pricing || pricing.length === 0) return null

Expand Down
2 changes: 1 addition & 1 deletion src/lib/metadata/schemas/builders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export function buildPersonSchema(options: PersonSchemaOptions): SchemaPerson {
export interface PricingTierData {
name?: string
value: number | null
currency: string | null
currency?: string | null
per?: string | null
category?: string
}
Expand Down
Loading