From 09ad2fa1bb46892989b02be782cf3cfc09fcb12e Mon Sep 17 00:00:00 2001 From: Pan YANG Date: Wed, 29 Jul 2026 00:20:18 +0800 Subject: [PATCH 1/8] docs(agents): clarify repository data rules --- AGENTS.md | 117 ++++++++++++------------------------------------------ 1 file changed, 25 insertions(+), 92 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 9b553914..45d0922f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,104 +1,37 @@ # AGENTS.md -This file provides guidance to Codex (Codex.ai/code) when working with code in this repository. +## Internationalization -## Internationalization (i18n) +- Translation resources live under `translations/`. Every page, module, and data change must support every locale configured in `src/i18n/config.ts`; never hardcode a locale subset. +- Always use `Link` from `@/i18n/navigation`, not the Next.js default. +- Localize page metadata and reuse existing translation keys and shared phrases before adding new ones. +- Follow [docs/I18N-ARCHITECTURE-RULES.md](docs/I18N-ARCHITECTURE-RULES.md): keep page and component translations in their prescribed namespaces, co-locate page metadata under `meta`, and minimize cross-namespace `@:` references. +- Add new keys to every locale with English placeholders first; perform proper translation as a separate batch. -**Translation Resources Location:** All translation files are located in the `translations/` directory at the project root, organized by locale code (e.g., `translations/en/`, `translations/zh-Hans/`). +## Data and Schema -When creating or modifying any page, module, or data: -- **MUST support all configured languages (12 total):** - - English (en) - - German (de) - - Spanish (es) - - French (fr) - - Indonesian (id) - - Japanese (ja) - - Korean (ko) - - Portuguese (pt) - - Russian (ru) - - Turkish (tr) - - Simplified Chinese (zh-Hans) - - Traditional Chinese (zh-Hant) +- Never store product, catalog, editorial, ranking, pricing, benchmark, configuration, or other independently adjustable data in `.ts` or `.tsx` files. +- Store data in schema-validated JSON under `data/`, the appropriate manifest, or translation resources. This includes curated selections, display order, metadata, prices, scores, timelines, chart-label placement, and ranking weights. +- TypeScript may contain types, loaders, validators, transformations, calculations, presentation logic, and implementation-only constants with no product or editorial meaning. When uncertain, treat a value as data. +- Update the JSON schema, corresponding TypeScript type, and validation tests together whenever a data shape changes. +- Keep `src/types/manifests.ts` in one-to-one correspondence with the schemas under `manifests/$schemas/`. -- **NEVER hardcode** a subset of locales like `'en' | 'zh-Hans'` -- **MUST use the localized Link component:** Always import and use `import { Link } from '@/i18n/navigation'` instead of Next.js default Link +## Design -### Localization Best Practices +- Use the existing extremely minimalist visual language: sharp corners, restrained low-saturation color, and accents only where necessary. +- Prefer Lucide SVG icons; do not use emoji or text characters as icons. +- Use `max-w-8xl` globally and `max-w-6xl` for content pages and the homepage. -- **Metadata localization:** All meta information (titles, descriptions, keywords, OG tags, etc.) in pages MUST be properly localized -- **DRY principle for translations:** Before creating new translation keys, search existing translation modules thoroughly to reuse existing terms and phrases -- **Consistency:** Use the same translation keys across similar contexts +## Metadata and SEO -### Translation File Organization - -Follow the detailed architecture rules in [docs/I18N-ARCHITECTURE-RULES.md](docs/I18N-ARCHITECTURE-RULES.md) for organizing translation resources. - -**Core Principles:** -1. **Page translations**: Each page or page group should have its own JSON file (e.g., `ides.json`, `ide-detail.json`) -2. **Component translations**: Organize by component directory: - - `components/common.json` - Root-level components (Header, Footer, etc.) - - `components/navigation.json` - All navigation/* components - - `components/controls.json` - All controls/* components - - `components/sidebar.json` - All sidebar/* components - - `components/product.json` - All product/* components -3. **Minimize `@:` references**: Use `tPage + tShared` or `tComponent + tShared` patterns in code instead of cross-namespace references in JSON -4. **Metadata placement**: Co-locate page metadata (title, description, etc.) with page translations under a `meta` object -5. **Multi-language workflow**: New translation keys should initially use English placeholders across all locales, with proper translation in a separate batch step - -**Usage Pattern:** -```tsx -// Pages -const tPage = useTranslations('pages.modelDetail') -const tShared = useTranslations('shared') - -// Components (root-level) -const tComponent = useTranslations('components.common.header') - -// Components (subdirectories) -const tComponent = useTranslations('components.navigation.breadcrumb') -``` - -## Design System - -**Global Design Principles:** - -- **Minimalist approach:** Follow a unified, extremely minimalist design style throughout the entire application -- **No rounded corners:** All controls, components, labels, and UI elements MUST use sharp corners (border-radius: 0) -- **Restrained color usage:** Use colors extremely sparingly and intentionally. Prefer grayscale and limit accent colors to essential UI elements only. If colors must be used, prefer low-saturation designs. -- **Icon usage:** Prefer using Lucide SVG icons. Avoid using emoji or any other characters as icons. -- **Page width:** - - `max-w-8xl`: for all pages globally - - `max-w-6xl`: for content pages and homepage - -## Coding Principles - -### DRY - Don't Repeat Yourself -- Eliminate code duplication by extracting common logic -- Reuse existing components, functions, and translation keys -- Create shared utilities when patterns emerge - -### Type Safety & Schema Alignment -- **Manifest type definitions:** Always ensure that `src/types/manifests.ts` stays in one-to-one correspondence with the JSON schemas in `manifests/$schemas/` -- When modifying schema files, update the corresponding TypeScript types accordingly -- When adding new types, verify they match the schema structure exactly -- Maintain consistency between schema definitions and type definitions to prevent runtime errors - -## Metadata & SEO - -- **File-based OG images:** Use `opengraph-image.tsx` files for all routes, NOT code-based image paths -- **Request memoization:** Wrap all data fetchers with React `cache()` to prevent duplicate fetching in `generateMetadata()` and page components -- **Type-safe locales:** Always use `import type { Locale } from '@/i18n/config'` -- **Auto-detected OG images:** Do NOT manually specify `images` in OpenGraph metadata - Next.js auto-detects `opengraph-image.tsx` files - -**OG Image Design:** -- Size: 1200x630px (OpenGraph standard) -- Follow global design system strictly +- Use route-level `opengraph-image.tsx` files; do not manually set OpenGraph image paths. OG images are 1200×630 and follow the design system. +- Wrap data fetchers shared by `generateMetadata()` and page rendering with React `cache()`. +- Use `Locale` from `@/i18n/config` for locale types. ## Development Workflow -- **Development server:** Do not start `npm run dev` automatically. User will start it manually when needed. -- **Standalone preview assets:** Before starting `.next/standalone/server.js`, sync `public/` into `.next/standalone/public/` and `.next/static/` into `.next/standalone/.next/static/`. Repeat this after every production build because Next.js regenerates `.next/standalone/`. Never start the standalone server without these assets. -- **Standalone preview host:** The standalone server `HOSTNAME` must match the hostname used in the preview URL. For a `http://localhost:` preview, start with `HOSTNAME=localhost`; do not substitute `127.0.0.1`, because locale middleware rewrites can otherwise become self-redirects. -- **Standalone preview verification:** After starting or restarting a standalone preview, verify that one default-locale URL without a locale prefix returns `200`, one locale-prefixed URL returns `200`, and a stylesheet referenced by the page returns `200` with a CSS content type. When using tmux, include the asset sync and matching `HOSTNAME` in the pane start command. -- **Git commits:** Do not create commits autonomously. Always ask the user before committing changes. +- Do not start `npm run dev` automatically; the user starts it when needed. +- Before every `.next/standalone/server.js` start, including after each production build, sync `public/` to `.next/standalone/public/` and `.next/static/` to `.next/standalone/.next/static/`. +- Match standalone `HOSTNAME` to the preview URL hostname. For `http://localhost:`, use `HOSTNAME=localhost`, never `127.0.0.1`. +- After each standalone start or restart, verify a default-locale URL, a locale-prefixed URL, and a referenced stylesheet all return `200`, with the stylesheet served as CSS. A tmux start command must include asset sync and the matching `HOSTNAME`. +- Never create a commit without asking the user first. From d7cba8ee538eb6916014949dd8eead9e1b6b1254 Mon Sep 17 00:00:00 2001 From: Pan YANG Date: Wed, 29 Jul 2026 00:22:37 +0800 Subject: [PATCH 2/8] chore(data): remove legacy maintenance artifacts --- .github/workflows/ci.yml | 5 - data/changelogs.json | 7937 ----------------------------- docs/PROJECT-REVIEW-2026-07-18.md | 3 - package-lock.json | 324 +- package.json | 3 - scripts/validate/changelog.ts | 264 - tests/changelog.test.ts | 42 - 7 files changed, 110 insertions(+), 8468 deletions(-) delete mode 100644 data/changelogs.json delete mode 100644 scripts/validate/changelog.ts delete mode 100644 tests/changelog.test.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 861675dd..1cf4b0b1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -73,11 +73,6 @@ jobs: - name: Check data health run: npm run data-health:check - - name: Check manifest changelog - run: npm run changelog:check - env: - CHANGELOG_BASE: ${{ github.event.pull_request.base.sha || github.event.before }} - spell-check: name: Spell Check runs-on: ubuntu-latest diff --git a/data/changelogs.json b/data/changelogs.json deleted file mode 100644 index 83e05aca..00000000 --- a/data/changelogs.json +++ /dev/null @@ -1,7937 +0,0 @@ -{ - "version": 1, - "entries": [ - { - "id": "2026-07-28-manifest-update", - "date": "2026-07-28", - "summary": "Catalog provenance and community links completed", - "changes": [ - { - "category": "clis", - "id": "amazon-q-developer-cli", - "change": "updated", - "fields": ["communityUrls", "sources"] - }, - { - "category": "clis", - "id": "amp-cli", - "change": "updated", - "fields": ["sources"] - }, - { - "category": "clis", - "id": "augment-code-cli", - "change": "updated", - "fields": ["communityUrls", "sources"] - }, - { - "category": "clis", - "id": "claude-code-cli", - "change": "updated", - "fields": ["sources"] - }, - { - "category": "clis", - "id": "cline-cli", - "change": "updated", - "fields": ["communityUrls", "sources"] - }, - { - "category": "clis", - "id": "codebuddy-cli", - "change": "updated", - "fields": ["communityUrls", "sources"] - }, - { - "category": "clis", - "id": "codex-cli", - "change": "updated", - "fields": ["communityUrls", "sources"] - }, - { - "category": "clis", - "id": "continue-cli", - "change": "updated", - "fields": [ - "communityUrls", - "description", - "latestVersion", - "platforms", - "pricing", - "relatedProducts", - "resourceUrls", - "translations", - "verified", - "confidence", - "deprecated", - "familyId", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "clis", - "id": "cursor-cli", - "change": "updated", - "fields": ["sources"] - }, - { - "category": "clis", - "id": "droid-cli", - "change": "updated", - "fields": ["communityUrls"] - }, - { - "category": "clis", - "id": "gemini-cli", - "change": "updated", - "fields": ["sources"] - }, - { - "category": "clis", - "id": "github-copilot-cli", - "change": "updated", - "fields": ["communityUrls", "sources"] - }, - { - "category": "clis", - "id": "gitlab-duo-cli", - "change": "updated", - "fields": ["communityUrls"] - }, - { - "category": "clis", - "id": "grok-build", - "change": "updated", - "fields": ["communityUrls"] - }, - { - "category": "clis", - "id": "junie-cli", - "change": "updated", - "fields": ["communityUrls"] - }, - { - "category": "clis", - "id": "kilo-code-cli", - "change": "updated", - "fields": [ - "communityUrls", - "docsUrl", - "latestVersion", - "resourceUrls", - "websiteUrl", - "confidence", - "familyId", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "clis", - "id": "kiro-cli", - "change": "updated", - "fields": ["sources"] - }, - { - "category": "clis", - "id": "kode", - "change": "updated", - "fields": ["sources"] - }, - { - "category": "clis", - "id": "neovate-code", - "change": "updated", - "fields": ["sources"] - }, - { - "category": "clis", - "id": "omp", - "change": "updated", - "fields": ["communityUrls"] - }, - { - "category": "clis", - "id": "opencode", - "change": "updated", - "fields": ["communityUrls", "sources"] - }, - { - "category": "clis", - "id": "qoder-cli", - "change": "updated", - "fields": ["communityUrls", "sources"] - }, - { - "category": "clis", - "id": "rovo-dev-cli", - "change": "updated", - "fields": ["communityUrls"] - }, - { - "category": "desktops", - "id": "air", - "change": "updated", - "fields": ["communityUrls", "sources"] - }, - { - "category": "desktops", - "id": "codex-app", - "change": "updated", - "fields": ["communityUrls"] - }, - { - "category": "desktops", - "id": "factory-desktop", - "change": "updated", - "fields": ["communityUrls"] - }, - { - "category": "desktops", - "id": "opencode-desktop", - "change": "updated", - "fields": ["communityUrls"] - }, - { - "category": "desktops", - "id": "qoder", - "change": "updated", - "fields": ["communityUrls"] - }, - { - "category": "desktops", - "id": "stagewise", - "change": "updated", - "fields": ["communityUrls"] - }, - { - "category": "desktops", - "id": "trae-work", - "change": "updated", - "fields": ["sources"] - }, - { - "category": "desktops", - "id": "verdent-deck", - "change": "updated", - "fields": ["communityUrls"] - }, - { - "category": "extensions", - "id": "amp", - "change": "updated", - "fields": ["sources"] - }, - { - "category": "extensions", - "id": "augment-code", - "change": "updated", - "fields": ["communityUrls", "sources"] - }, - { - "category": "extensions", - "id": "claude-code", - "change": "updated", - "fields": ["sources"] - }, - { - "category": "extensions", - "id": "cline", - "change": "updated", - "fields": ["communityUrls"] - }, - { - "category": "extensions", - "id": "codex", - "change": "updated", - "fields": ["communityUrls", "sources"] - }, - { - "category": "extensions", - "id": "continue", - "change": "updated", - "fields": [ - "communityUrls", - "description", - "latestVersion", - "pricing", - "relatedProducts", - "resourceUrls", - "supportedIdes", - "translations", - "verified", - "confidence", - "deprecated", - "familyId", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "extensions", - "id": "droid", - "change": "updated", - "fields": ["communityUrls", "sources"] - }, - { - "category": "extensions", - "id": "gemini-code-assist", - "change": "updated", - "fields": ["communityUrls", "sources"] - }, - { - "category": "extensions", - "id": "github-copilot", - "change": "updated", - "fields": ["communityUrls", "sources"] - }, - { - "category": "extensions", - "id": "jetbrains-junie", - "change": "updated", - "fields": ["communityUrls", "sources"] - }, - { - "category": "extensions", - "id": "kilo-code", - "change": "updated", - "fields": [ - "communityUrls", - "latestVersion", - "confidence", - "familyId", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "extensions", - "id": "opencode-extension", - "change": "updated", - "fields": ["communityUrls"] - }, - { - "category": "extensions", - "id": "qoder", - "change": "updated", - "fields": ["communityUrls", "sources"] - }, - { - "category": "extensions", - "id": "roo-code", - "change": "updated", - "fields": [ - "communityUrls", - "description", - "docsUrl", - "latestVersion", - "pricing", - "resourceUrls", - "translations", - "verified", - "websiteUrl", - "confidence", - "deprecated", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "extensions", - "id": "rovo-dev", - "change": "updated", - "fields": ["communityUrls"] - }, - { - "category": "extensions", - "id": "tabnine", - "change": "updated", - "fields": ["communityUrls"] - }, - { - "category": "extensions", - "id": "verdent", - "change": "updated", - "fields": ["communityUrls", "sources"] - }, - { - "category": "ides", - "id": "antigravity", - "change": "updated", - "fields": ["sources"] - }, - { - "category": "ides", - "id": "codebuddy", - "change": "updated", - "fields": ["sources"] - }, - { - "category": "ides", - "id": "cursor", - "change": "updated", - "fields": ["sources"] - }, - { - "category": "ides", - "id": "intellij-idea", - "change": "updated", - "fields": ["communityUrls", "sources"] - }, - { - "category": "ides", - "id": "kiro", - "change": "updated", - "fields": ["sources"] - }, - { - "category": "ides", - "id": "trae", - "change": "updated", - "fields": ["sources"] - }, - { - "category": "ides", - "id": "vscode", - "change": "updated", - "fields": ["sources"] - }, - { - "category": "ides", - "id": "windsurf", - "change": "updated", - "fields": ["sources"] - }, - { - "category": "ides", - "id": "zed", - "change": "updated", - "fields": ["communityUrls"] - }, - { - "category": "models", - "id": "glm-4-6", - "change": "updated", - "fields": [ - "description", - "size", - "translations", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "models", - "id": "glm-4-6v", - "change": "updated", - "fields": [ - "benchmarks", - "description", - "knowledgeCutoff", - "lifecycle", - "maxOutput", - "size", - "translations", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "models", - "id": "gpt-4-1", - "change": "updated", - "fields": ["confidence", "lastVerifiedAt", "sources", "verifiedBy"] - }, - { - "category": "models", - "id": "gpt-4o", - "change": "updated", - "fields": [ - "docsUrl", - "lifecycle", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "models", - "id": "gpt-5", - "change": "updated", - "fields": ["docsUrl", "confidence", "lastVerifiedAt", "sources", "verifiedBy"] - }, - { - "category": "models", - "id": "gpt-5-1", - "change": "updated", - "fields": ["docsUrl", "confidence", "lastVerifiedAt", "sources", "verifiedBy"] - }, - { - "category": "models", - "id": "gpt-5-1-codex", - "change": "updated", - "fields": [ - "docsUrl", - "lifecycle", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "models", - "id": "gpt-5-codex", - "change": "updated", - "fields": [ - "docsUrl", - "lifecycle", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "models", - "id": "minimax-m2", - "change": "updated", - "fields": [ - "docsUrl", - "knowledgeCutoff", - "maxOutput", - "tokenPricing", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "models", - "id": "minimax-m2-1", - "change": "updated", - "fields": [ - "docsUrl", - "knowledgeCutoff", - "lifecycle", - "maxOutput", - "tokenPricing", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "models", - "id": "qwen3-coder-30b-a3b", - "change": "updated", - "fields": [ - "description", - "knowledgeCutoff", - "lifecycle", - "size", - "tokenPricing", - "translations", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "models", - "id": "qwen3-coder-480b-a35b", - "change": "updated", - "fields": [ - "description", - "knowledgeCutoff", - "lifecycle", - "tokenPricing", - "translations", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "providers", - "id": "alibaba", - "change": "updated", - "fields": ["sources"] - }, - { - "category": "providers", - "id": "anthropic", - "change": "updated", - "fields": ["communityUrls", "sources"] - }, - { - "category": "providers", - "id": "deepseek", - "change": "updated", - "fields": ["communityUrls"] - }, - { - "category": "providers", - "id": "google", - "change": "updated", - "fields": ["communityUrls", "sources"] - }, - { - "category": "providers", - "id": "meta", - "change": "updated", - "fields": ["communityUrls", "sources"] - }, - { - "category": "providers", - "id": "moonshot", - "change": "updated", - "fields": ["communityUrls"] - }, - { - "category": "providers", - "id": "openai", - "change": "updated", - "fields": ["communityUrls", "sources"] - }, - { - "category": "providers", - "id": "openrouter", - "change": "updated", - "fields": ["communityUrls"] - }, - { - "category": "providers", - "id": "siliconflow", - "change": "updated", - "fields": ["communityUrls", "confidence", "lastVerifiedAt", "sources", "verifiedBy"] - }, - { - "category": "providers", - "id": "xai", - "change": "updated", - "fields": ["communityUrls"] - }, - { - "category": "providers", - "id": "z-ai", - "change": "updated", - "fields": ["communityUrls"] - }, - { - "category": "vendors", - "id": "alibaba", - "change": "updated", - "fields": ["verified", "confidence", "lastVerifiedAt", "sources", "verifiedBy"] - }, - { - "category": "vendors", - "id": "anomaly", - "change": "updated", - "fields": ["lastVerifiedAt", "sources", "verified"] - }, - { - "category": "vendors", - "id": "ant-group", - "change": "updated", - "fields": [ - "description", - "translations", - "verified", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "vendors", - "id": "anthropic", - "change": "updated", - "fields": ["verified", "confidence", "lastVerifiedAt", "sources", "verifiedBy"] - }, - { - "category": "vendors", - "id": "anysphere", - "change": "updated", - "fields": ["verified", "confidence", "lastVerifiedAt", "sources", "verifiedBy"] - }, - { - "category": "vendors", - "id": "atlassian", - "change": "updated", - "fields": ["lastVerifiedAt", "sources", "verified"] - }, - { - "category": "vendors", - "id": "augment", - "change": "updated", - "fields": ["verified", "confidence", "lastVerifiedAt", "sources", "verifiedBy"] - }, - { - "category": "vendors", - "id": "aws", - "change": "updated", - "fields": [ - "description", - "translations", - "verified", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "vendors", - "id": "bytedance", - "change": "updated", - "fields": ["verified", "confidence", "lastVerifiedAt", "sources", "verifiedBy"] - }, - { - "category": "vendors", - "id": "cline", - "change": "updated", - "fields": [ - "description", - "translations", - "verified", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "vendors", - "id": "cognition", - "change": "updated", - "fields": [ - "verified", - "websiteUrl", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "vendors", - "id": "continue", - "change": "updated", - "fields": [ - "description", - "translations", - "verified", - "confidence", - "deprecated", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "vendors", - "id": "deepseek", - "change": "updated", - "fields": ["verified", "confidence", "lastVerifiedAt", "sources", "verifiedBy"] - }, - { - "category": "vendors", - "id": "factory-ai", - "change": "updated", - "fields": [ - "description", - "translations", - "verified", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "vendors", - "id": "github", - "change": "updated", - "fields": ["verified", "confidence", "lastVerifiedAt", "sources", "verifiedBy"] - }, - { - "category": "vendors", - "id": "gitlab", - "change": "updated", - "fields": ["lastVerifiedAt", "sources", "verified"] - }, - { - "category": "vendors", - "id": "google", - "change": "updated", - "fields": ["verified", "confidence", "lastVerifiedAt", "sources", "verifiedBy"] - }, - { - "category": "vendors", - "id": "jetbrains", - "change": "updated", - "fields": ["verified", "confidence", "lastVerifiedAt", "sources", "verifiedBy"] - }, - { - "category": "vendors", - "id": "kilo", - "change": "updated", - "fields": ["confidence", "lastVerifiedAt", "sources", "verifiedBy"] - }, - { - "category": "vendors", - "id": "meta", - "change": "updated", - "fields": ["verified", "confidence", "lastVerifiedAt", "sources", "verifiedBy"] - }, - { - "category": "vendors", - "id": "microsoft", - "change": "updated", - "fields": ["verified", "confidence", "lastVerifiedAt", "sources", "verifiedBy"] - }, - { - "category": "vendors", - "id": "minimax", - "change": "updated", - "fields": [ - "communityUrls", - "verified", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "vendors", - "id": "mistral-ai", - "change": "updated", - "fields": ["sources"] - }, - { - "category": "vendors", - "id": "moonshot", - "change": "updated", - "fields": ["verified", "confidence", "lastVerifiedAt", "sources", "verifiedBy"] - }, - { - "category": "vendors", - "id": "oh-my-pi", - "change": "updated", - "fields": ["lastVerifiedAt", "sources", "verified"] - }, - { - "category": "vendors", - "id": "openai", - "change": "updated", - "fields": ["verified", "confidence", "lastVerifiedAt", "sources", "verifiedBy"] - }, - { - "category": "vendors", - "id": "openrouter", - "change": "updated", - "fields": ["verified", "confidence", "lastVerifiedAt", "sources", "verifiedBy"] - }, - { - "category": "vendors", - "id": "roo-code", - "change": "updated", - "fields": [ - "description", - "translations", - "verified", - "websiteUrl", - "confidence", - "deprecated", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "vendors", - "id": "shareai-lab", - "change": "updated", - "fields": [ - "description", - "translations", - "verified", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "vendors", - "id": "siliconflow", - "change": "updated", - "fields": ["confidence", "lastVerifiedAt", "sources", "verifiedBy"] - }, - { - "category": "vendors", - "id": "sourcegraph", - "change": "updated", - "fields": [ - "description", - "translations", - "verified", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "vendors", - "id": "sst", - "change": "updated", - "fields": [ - "communityUrls", - "description", - "translations", - "verified", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "vendors", - "id": "stagewise", - "change": "updated", - "fields": ["lastVerifiedAt", "sources", "verified"] - }, - { - "category": "vendors", - "id": "tabnine", - "change": "updated", - "fields": [ - "description", - "translations", - "verified", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "vendors", - "id": "tencent", - "change": "updated", - "fields": [ - "description", - "translations", - "verified", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "vendors", - "id": "verdent-ai", - "change": "updated", - "fields": [ - "description", - "translations", - "verified", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "vendors", - "id": "xai", - "change": "updated", - "fields": ["verified", "confidence", "lastVerifiedAt", "sources", "verifiedBy"] - }, - { - "category": "vendors", - "id": "z-ai", - "change": "updated", - "fields": ["verified", "confidence", "lastVerifiedAt", "sources", "verifiedBy"] - }, - { - "category": "vendors", - "id": "zed-industries", - "change": "updated", - "fields": ["verified", "confidence", "lastVerifiedAt", "sources", "verifiedBy"] - } - ] - }, - { - "id": "2026-07-27-manifest-update", - "date": "2026-07-27", - "summary": "22 manifest records changed", - "changes": [ - { - "category": "models", - "id": "claude-opus-5", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gemma-4-26b-a4b", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gemma-4-31b", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "hy3", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "mimo-v2-5", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "mimo-v2-5-pro", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "mimo-v2-flash", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "qwen3-5-122b-a10b", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "qwen3-5-35b-a3b", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "qwen3-5-397b-a17b", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "vendors", - "id": "alibaba", - "change": "updated", - "fields": ["verified", "confidence", "lastVerifiedAt", "sources", "verifiedBy"] - }, - { - "category": "vendors", - "id": "anthropic", - "change": "updated", - "fields": ["verified", "confidence", "lastVerifiedAt", "sources", "verifiedBy"] - }, - { - "category": "vendors", - "id": "deepseek", - "change": "updated", - "fields": ["verified", "confidence", "lastVerifiedAt", "sources", "verifiedBy"] - }, - { - "category": "vendors", - "id": "google", - "change": "updated", - "fields": ["verified", "confidence", "lastVerifiedAt", "sources", "verifiedBy"] - }, - { - "category": "vendors", - "id": "kilo", - "change": "updated", - "fields": ["confidence", "lastVerifiedAt", "sources", "verifiedBy"] - }, - { - "category": "vendors", - "id": "moonshot", - "change": "updated", - "fields": ["verified", "confidence", "lastVerifiedAt", "sources", "verifiedBy"] - }, - { - "category": "vendors", - "id": "openai", - "change": "updated", - "fields": ["verified", "confidence", "lastVerifiedAt", "sources", "verifiedBy"] - }, - { - "category": "vendors", - "id": "siliconflow", - "change": "updated", - "fields": ["confidence", "lastVerifiedAt", "sources", "verifiedBy"] - }, - { - "category": "vendors", - "id": "tencent", - "change": "updated", - "fields": ["themeColor"] - }, - { - "category": "vendors", - "id": "xai", - "change": "updated", - "fields": ["verified", "confidence", "lastVerifiedAt", "sources", "verifiedBy"] - }, - { - "category": "vendors", - "id": "xiaomi", - "change": "added", - "fields": [ - "communityUrls", - "confidence", - "description", - "id", - "lastVerifiedAt", - "name", - "sources", - "themeColor", - "translations", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "vendors", - "id": "z-ai", - "change": "updated", - "fields": ["verified", "confidence", "lastVerifiedAt", "sources", "verifiedBy"] - } - ] - }, - { - "id": "2026-07-26-manifest-update", - "date": "2026-07-26", - "summary": "77 manifest records changed", - "changes": [ - { - "category": "clis", - "id": "antigravity-cli", - "change": "added", - "fields": [ - "communityUrls", - "confidence", - "description", - "docsUrl", - "familyId", - "githubUrl", - "id", - "lastVerifiedAt", - "latestVersion", - "license", - "name", - "platforms", - "pricing", - "relatedProducts", - "resourceUrls", - "sources", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "clis", - "id": "deepv-code", - "change": "removed", - "fields": [ - "communityUrls", - "confidence", - "description", - "docsUrl", - "githubUrl", - "id", - "lastVerifiedAt", - "latestVersion", - "license", - "name", - "platforms", - "pricing", - "relatedProducts", - "resourceUrls", - "sources", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "clis", - "id": "gemini-cli", - "change": "updated", - "fields": [ - "latestVersion", - "pricing", - "relatedProducts", - "verified", - "confidence", - "deprecated", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "clis", - "id": "grok-build", - "change": "updated", - "fields": [ - "communityUrls", - "githubUrl", - "lastVerifiedAt", - "latestVersion", - "resourceUrls", - "sources" - ] - }, - { - "category": "ides", - "id": "antigravity", - "change": "updated", - "fields": ["relatedProducts", "familyId"] - }, - { - "category": "ides", - "id": "codeflicker", - "change": "removed", - "fields": [ - "communityUrls", - "description", - "docsUrl", - "githubUrl", - "id", - "latestVersion", - "license", - "name", - "platforms", - "pricing", - "relatedProducts", - "resourceUrls", - "translations", - "vendor", - "verified", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "claude-fable-5", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "claude-haiku-4-5", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "claude-mythos-5", - "change": "removed", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "claude-opus-4", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "claude-opus-4-1", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "claude-opus-4-5", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "claude-opus-4-8", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "claude-sonnet-4", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "claude-sonnet-4-5", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "claude-sonnet-5", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "codestral-2405", - "change": "removed", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "codestral-2501", - "change": "removed", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "codestral-2508", - "change": "removed", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "composer", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "deepseek-coder-v2-0724", - "change": "removed", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "devstral-medium-1-0", - "change": "removed", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "devstral-small-1-0", - "change": "removed", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "devstral-small-1-1", - "change": "removed", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gemini-2-0-flash-lite", - "change": "removed", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gemini-3-1-flash-lite", - "change": "removed", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gemini-3-1-pro-preview", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "gemini-3-5-flash", - "change": "updated", - "fields": ["lastVerifiedAt", "lifecycle", "size"] - }, - { - "category": "models", - "id": "gemini-3-5-flash-lite", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gemini-3-6-flash", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gemini-3-flash", - "change": "updated", - "fields": ["lastVerifiedAt", "lifecycle", "size"] - }, - { - "category": "models", - "id": "gemini-3-pro", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "glm-4-5-air", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "glm-4-5v", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "glm-4-7-flash", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "glm-5-turbo", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "glm-5v-turbo", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gpt-4-1", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "gpt-4o", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "gpt-5", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "gpt-5-1", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "gpt-5-1-codex", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "gpt-5-1-codex-max", - "change": "removed", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gpt-5-2", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "gpt-5-2-pro", - "change": "removed", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gpt-5-4-pro", - "change": "removed", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gpt-5-5-pro", - "change": "removed", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gpt-5-6-luna", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "gpt-5-6-sol", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "gpt-5-6-terra", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "gpt-5-codex", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "gpt-5-pro", - "change": "removed", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "grok-build-0-1", - "change": "removed", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "grok-code-fast-1", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "kat-coder-pro-v1", - "change": "removed", - "fields": [ - "benchmarks", - "capabilities", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "tokenPricing", - "translations", - "vendor", - "verified", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "kimi-dev-72b", - "change": "removed", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "qwen3-5-plus", - "change": "removed", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "qwen3-6-27b", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "qwen3-6-35b-a3b", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "qwen3-6-max-preview", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "deprecated", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "qwen3-coder-flash", - "change": "removed", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "qwen3-coder-plus", - "change": "removed", - "fields": [ - "benchmarks", - "capabilities", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "tokenPricing", - "translations", - "vendor", - "verified", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "qwen3-max-2026-01-23", - "change": "removed", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "providers", - "id": "kwaikatonai", - "change": "removed", - "fields": [ - "applyKeyUrl", - "communityUrls", - "description", - "docsUrl", - "id", - "name", - "platformUrls", - "translations", - "type", - "vendor", - "verified", - "websiteUrl" - ] - }, - { - "category": "vendors", - "id": "alibaba", - "change": "updated", - "fields": ["themeColor"] - }, - { - "category": "vendors", - "id": "anthropic", - "change": "updated", - "fields": ["themeColor"] - }, - { - "category": "vendors", - "id": "deepseek", - "change": "updated", - "fields": ["themeColor"] - }, - { - "category": "vendors", - "id": "google", - "change": "updated", - "fields": ["themeColor"] - }, - { - "category": "vendors", - "id": "meta", - "change": "updated", - "fields": ["themeColor"] - }, - { - "category": "vendors", - "id": "minimax", - "change": "updated", - "fields": ["themeColor"] - }, - { - "category": "vendors", - "id": "mistral-ai", - "change": "updated", - "fields": ["themeColor"] - }, - { - "category": "vendors", - "id": "moonshot", - "change": "updated", - "fields": ["themeColor"] - }, - { - "category": "vendors", - "id": "openai", - "change": "updated", - "fields": ["themeColor"] - }, - { - "category": "vendors", - "id": "orionstar", - "change": "removed", - "fields": [ - "communityUrls", - "description", - "id", - "name", - "translations", - "verified", - "websiteUrl" - ] - }, - { - "category": "vendors", - "id": "streamlake", - "change": "removed", - "fields": [ - "aliases", - "communityUrls", - "description", - "id", - "name", - "translations", - "verified", - "websiteUrl" - ] - }, - { - "category": "vendors", - "id": "xai", - "change": "updated", - "fields": ["themeColor"] - }, - { - "category": "vendors", - "id": "z-ai", - "change": "updated", - "fields": ["themeColor"] - } - ] - }, - { - "id": "2026-07-25-manifest-update", - "date": "2026-07-25", - "summary": "33 manifest records changed", - "changes": [ - { - "category": "clis", - "id": "antigravity-cli", - "change": "added", - "fields": [ - "communityUrls", - "confidence", - "description", - "docsUrl", - "familyId", - "githubUrl", - "id", - "lastVerifiedAt", - "latestVersion", - "license", - "name", - "platforms", - "pricing", - "relatedProducts", - "resourceUrls", - "sources", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "clis", - "id": "gemini-cli", - "change": "updated", - "fields": [ - "latestVersion", - "pricing", - "relatedProducts", - "verified", - "confidence", - "deprecated", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "clis", - "id": "grok-build", - "change": "updated", - "fields": [ - "communityUrls", - "githubUrl", - "lastVerifiedAt", - "latestVersion", - "resourceUrls", - "sources" - ] - }, - { - "category": "ides", - "id": "antigravity", - "change": "updated", - "fields": ["relatedProducts", "familyId"] - }, - { - "category": "models", - "id": "claude-fable-5", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "claude-haiku-4-5", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "claude-opus-4", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "claude-opus-4-1", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "claude-opus-4-5", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "claude-opus-4-8", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "claude-sonnet-4", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "claude-sonnet-4-5", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "claude-sonnet-5", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "composer", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "gemini-3-1-flash-lite", - "change": "updated", - "fields": ["lastVerifiedAt", "lifecycle", "size"] - }, - { - "category": "models", - "id": "gemini-3-1-pro-preview", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "gemini-3-5-flash", - "change": "updated", - "fields": ["lastVerifiedAt", "lifecycle", "size"] - }, - { - "category": "models", - "id": "gemini-3-5-flash-lite", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gemini-3-6-flash", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gemini-3-flash", - "change": "updated", - "fields": ["lastVerifiedAt", "lifecycle", "size"] - }, - { - "category": "models", - "id": "gemini-3-pro", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "gpt-4-1", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "gpt-4o", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "gpt-5", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "gpt-5-1", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "gpt-5-1-codex", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "gpt-5-2", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "gpt-5-6-luna", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "gpt-5-6-sol", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "gpt-5-6-terra", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "gpt-5-codex", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "grok-code-fast-1", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "kat-coder-pro-v1", - "change": "updated", - "fields": ["size"] - } - ] - }, - { - "id": "2026-07-22-manifest-update", - "date": "2026-07-22", - "summary": "33 manifest records changed", - "changes": [ - { - "category": "clis", - "id": "antigravity-cli", - "change": "added", - "fields": [ - "communityUrls", - "confidence", - "description", - "docsUrl", - "familyId", - "githubUrl", - "id", - "lastVerifiedAt", - "latestVersion", - "license", - "name", - "platforms", - "pricing", - "relatedProducts", - "resourceUrls", - "sources", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "clis", - "id": "gemini-cli", - "change": "updated", - "fields": [ - "latestVersion", - "pricing", - "relatedProducts", - "verified", - "confidence", - "deprecated", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "clis", - "id": "grok-build", - "change": "updated", - "fields": [ - "communityUrls", - "githubUrl", - "lastVerifiedAt", - "latestVersion", - "resourceUrls", - "sources" - ] - }, - { - "category": "ides", - "id": "antigravity", - "change": "updated", - "fields": ["relatedProducts", "familyId"] - }, - { - "category": "models", - "id": "claude-fable-5", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "claude-haiku-4-5", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "claude-opus-4", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "claude-opus-4-1", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "claude-opus-4-5", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "claude-opus-4-8", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "claude-sonnet-4", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "claude-sonnet-4-5", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "claude-sonnet-5", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "composer", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "gemini-3-1-flash-lite", - "change": "updated", - "fields": ["lastVerifiedAt", "lifecycle", "size"] - }, - { - "category": "models", - "id": "gemini-3-1-pro-preview", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "gemini-3-5-flash", - "change": "updated", - "fields": ["lastVerifiedAt", "lifecycle", "size"] - }, - { - "category": "models", - "id": "gemini-3-5-flash-lite", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gemini-3-6-flash", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gemini-3-flash", - "change": "updated", - "fields": ["lastVerifiedAt", "lifecycle", "size"] - }, - { - "category": "models", - "id": "gemini-3-pro", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "gpt-4-1", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "gpt-4o", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "gpt-5", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "gpt-5-1", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "gpt-5-1-codex", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "gpt-5-2", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "gpt-5-6-luna", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "gpt-5-6-sol", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "gpt-5-6-terra", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "gpt-5-codex", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "grok-code-fast-1", - "change": "updated", - "fields": ["size"] - }, - { - "category": "models", - "id": "kat-coder-pro-v1", - "change": "updated", - "fields": ["size"] - } - ] - }, - { - "id": "2026-07-21-url-validation", - "date": "2026-07-21", - "summary": "Normalized and repaired manifest URLs flagged by scheduled validation", - "changes": [ - { - "category": "clis", - "id": "amazon-q-developer-cli", - "change": "updated", - "fields": ["websiteUrl"] - }, - { - "category": "clis", - "id": "deepv-code", - "change": "updated", - "fields": ["docsUrl", "websiteUrl"] - }, - { - "category": "clis", - "id": "droid-cli", - "change": "updated", - "fields": ["resourceUrls"] - }, - { - "category": "clis", - "id": "qoder-cli", - "change": "updated", - "fields": ["docsUrl"] - }, - { - "category": "extensions", - "id": "gemini-code-assist", - "change": "updated", - "fields": ["communityUrls", "websiteUrl"] - }, - { - "category": "ides", - "id": "air", - "change": "updated", - "fields": ["docsUrl", "resourceUrls", "websiteUrl"] - }, - { - "category": "models", - "id": "gemini-3-1-pro-preview", - "change": "updated", - "fields": ["sources"] - }, - { - "category": "models", - "id": "gemini-3-flash", - "change": "updated", - "fields": ["sources"] - }, - { - "category": "models", - "id": "glm-4-6v", - "change": "updated", - "fields": ["websiteUrl"] - }, - { - "category": "models", - "id": "gpt-5-2", - "change": "updated", - "fields": ["sources"] - }, - { - "category": "models", - "id": "gpt-5-6-luna", - "change": "updated", - "fields": ["sources"] - }, - { - "category": "models", - "id": "gpt-5-6-sol", - "change": "updated", - "fields": ["sources"] - }, - { - "category": "models", - "id": "gpt-5-6-terra", - "change": "updated", - "fields": ["sources"] - }, - { - "category": "providers", - "id": "alibaba", - "change": "updated", - "fields": ["communityUrls"] - }, - { - "category": "providers", - "id": "anthropic", - "change": "updated", - "fields": ["applyKeyUrl", "sources"] - }, - { - "category": "providers", - "id": "google", - "change": "updated", - "fields": ["sources"] - }, - { - "category": "providers", - "id": "meta", - "change": "updated", - "fields": ["applyKeyUrl", "docsUrl"] - }, - { - "category": "providers", - "id": "moonshot", - "change": "updated", - "fields": ["platformUrls"] - }, - { - "category": "providers", - "id": "openai", - "change": "updated", - "fields": ["sources"] - }, - { - "category": "vendors", - "id": "orionstar", - "change": "updated", - "fields": ["communityUrls"] - }, - { - "category": "vendors", - "id": "tabnine", - "change": "updated", - "fields": ["communityUrls"] - } - ] - }, - { - "id": "2026-07-21-manifest-update", - "date": "2026-07-21", - "summary": "183 manifest records changed", - "changes": [ - { - "category": "clis", - "id": "claude-code-cli", - "change": "updated", - "fields": ["relatedProducts", "familyId"] - }, - { - "category": "clis", - "id": "codex-cli", - "change": "updated", - "fields": ["relatedProducts", "familyId"] - }, - { - "category": "clis", - "id": "deepv-code", - "change": "updated", - "fields": [ - "githubUrl", - "resourceUrls", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "clis", - "id": "droid-cli", - "change": "updated", - "fields": ["relatedProducts", "familyId"] - }, - { - "category": "clis", - "id": "gitlab-duo-cli", - "change": "added", - "fields": [ - "communityUrls", - "confidence", - "description", - "docsUrl", - "familyId", - "githubUrl", - "id", - "lastVerifiedAt", - "latestVersion", - "license", - "name", - "platforms", - "pricing", - "relatedProducts", - "resourceUrls", - "sources", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "clis", - "id": "grok-build", - "change": "added", - "fields": [ - "communityUrls", - "confidence", - "description", - "docsUrl", - "familyId", - "githubUrl", - "id", - "lastVerifiedAt", - "latestVersion", - "license", - "name", - "platforms", - "pricing", - "relatedProducts", - "resourceUrls", - "sources", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "clis", - "id": "junie-cli", - "change": "added", - "fields": [ - "communityUrls", - "confidence", - "description", - "docsUrl", - "familyId", - "githubUrl", - "id", - "lastVerifiedAt", - "latestVersion", - "license", - "name", - "platforms", - "pricing", - "relatedProducts", - "resourceUrls", - "sources", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "clis", - "id": "kimi-cli", - "change": "updated", - "fields": [ - "communityUrls", - "description", - "docsUrl", - "githubUrl", - "latestVersion", - "name", - "platforms", - "pricing", - "relatedProducts", - "resourceUrls", - "translations", - "websiteUrl", - "confidence", - "familyId", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "clis", - "id": "mistral-vibe-cli", - "change": "added", - "fields": [ - "communityUrls", - "confidence", - "description", - "docsUrl", - "familyId", - "githubUrl", - "id", - "lastVerifiedAt", - "latestVersion", - "license", - "name", - "platforms", - "pricing", - "relatedProducts", - "resourceUrls", - "sources", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "clis", - "id": "omp", - "change": "added", - "fields": [ - "communityUrls", - "confidence", - "description", - "docsUrl", - "familyId", - "githubUrl", - "id", - "lastVerifiedAt", - "latestVersion", - "license", - "name", - "platforms", - "pricing", - "relatedProducts", - "resourceUrls", - "sources", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "clis", - "id": "opencode", - "change": "updated", - "fields": [ - "communityUrls", - "githubUrl", - "relatedProducts", - "resourceUrls", - "vendor", - "familyId" - ] - }, - { - "category": "clis", - "id": "qoder-cli", - "change": "updated", - "fields": ["relatedProducts", "familyId"] - }, - { - "category": "clis", - "id": "qwen-code", - "change": "added", - "fields": [ - "communityUrls", - "confidence", - "description", - "docsUrl", - "familyId", - "githubUrl", - "id", - "lastVerifiedAt", - "latestVersion", - "license", - "name", - "platforms", - "pricing", - "relatedProducts", - "resourceUrls", - "sources", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "clis", - "id": "rovo-dev-cli", - "change": "added", - "fields": [ - "communityUrls", - "confidence", - "description", - "docsUrl", - "familyId", - "githubUrl", - "id", - "lastVerifiedAt", - "latestVersion", - "license", - "name", - "platforms", - "pricing", - "relatedProducts", - "resourceUrls", - "sources", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "desktops", - "id": "air", - "change": "added", - "fields": [ - "communityUrls", - "confidence", - "description", - "docsUrl", - "familyId", - "githubUrl", - "id", - "lastVerifiedAt", - "latestVersion", - "license", - "name", - "platforms", - "pricing", - "relatedProducts", - "resourceUrls", - "sources", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "desktops", - "id": "claude-code-desktop", - "change": "added", - "fields": [ - "communityUrls", - "confidence", - "description", - "docsUrl", - "familyId", - "githubUrl", - "id", - "lastVerifiedAt", - "latestVersion", - "license", - "name", - "platforms", - "pricing", - "relatedProducts", - "resourceUrls", - "sources", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "desktops", - "id": "codex-app", - "change": "added", - "fields": [ - "communityUrls", - "confidence", - "description", - "docsUrl", - "familyId", - "githubUrl", - "id", - "lastVerifiedAt", - "latestVersion", - "license", - "name", - "platforms", - "pricing", - "relatedProducts", - "resourceUrls", - "sources", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "desktops", - "id": "factory-desktop", - "change": "added", - "fields": [ - "communityUrls", - "confidence", - "description", - "docsUrl", - "familyId", - "githubUrl", - "id", - "lastVerifiedAt", - "latestVersion", - "license", - "name", - "platforms", - "pricing", - "relatedProducts", - "resourceUrls", - "sources", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "desktops", - "id": "minimax-code", - "change": "added", - "fields": [ - "communityUrls", - "confidence", - "description", - "docsUrl", - "familyId", - "githubUrl", - "id", - "lastVerifiedAt", - "latestVersion", - "license", - "name", - "platforms", - "pricing", - "relatedProducts", - "resourceUrls", - "sources", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "desktops", - "id": "opencode-desktop", - "change": "added", - "fields": [ - "communityUrls", - "confidence", - "description", - "docsUrl", - "familyId", - "githubUrl", - "id", - "lastVerifiedAt", - "latestVersion", - "license", - "name", - "platforms", - "pricing", - "relatedProducts", - "resourceUrls", - "sources", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "desktops", - "id": "qoder", - "change": "added", - "fields": [ - "communityUrls", - "confidence", - "description", - "docsUrl", - "familyId", - "githubUrl", - "id", - "lastVerifiedAt", - "latestVersion", - "license", - "name", - "platforms", - "pricing", - "relatedProducts", - "resourceUrls", - "sources", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "desktops", - "id": "stagewise", - "change": "added", - "fields": [ - "communityUrls", - "confidence", - "description", - "docsUrl", - "familyId", - "githubUrl", - "id", - "lastVerifiedAt", - "latestVersion", - "license", - "name", - "platforms", - "pricing", - "relatedProducts", - "resourceUrls", - "sources", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "desktops", - "id": "trae-work", - "change": "added", - "fields": [ - "communityUrls", - "confidence", - "description", - "docsUrl", - "familyId", - "githubUrl", - "id", - "lastVerifiedAt", - "latestVersion", - "license", - "name", - "platforms", - "pricing", - "relatedProducts", - "resourceUrls", - "sources", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "desktops", - "id": "verdent-deck", - "change": "added", - "fields": [ - "communityUrls", - "confidence", - "description", - "docsUrl", - "familyId", - "githubUrl", - "id", - "lastVerifiedAt", - "latestVersion", - "license", - "name", - "platforms", - "pricing", - "relatedProducts", - "resourceUrls", - "sources", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "desktops", - "id": "workbuddy", - "change": "added", - "fields": [ - "communityUrls", - "confidence", - "description", - "docsUrl", - "familyId", - "githubUrl", - "id", - "lastVerifiedAt", - "latestVersion", - "license", - "name", - "platforms", - "pricing", - "relatedProducts", - "resourceUrls", - "sources", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "desktops", - "id": "zcode", - "change": "added", - "fields": [ - "communityUrls", - "confidence", - "description", - "docsUrl", - "familyId", - "githubUrl", - "id", - "lastVerifiedAt", - "latestVersion", - "license", - "name", - "platforms", - "pricing", - "relatedProducts", - "resourceUrls", - "sources", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "extensions", - "id": "claude-code", - "change": "updated", - "fields": ["relatedProducts", "familyId"] - }, - { - "category": "extensions", - "id": "codex", - "change": "updated", - "fields": [ - "communityUrls", - "docsUrl", - "githubUrl", - "latestVersion", - "license", - "relatedProducts", - "resourceUrls", - "confidence", - "familyId", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "extensions", - "id": "droid", - "change": "updated", - "fields": ["relatedProducts", "familyId"] - }, - { - "category": "extensions", - "id": "jetbrains-junie", - "change": "updated", - "fields": ["relatedProducts", "familyId"] - }, - { - "category": "extensions", - "id": "kimi-code", - "change": "added", - "fields": [ - "communityUrls", - "confidence", - "description", - "docsUrl", - "familyId", - "githubUrl", - "id", - "lastVerifiedAt", - "latestVersion", - "license", - "name", - "pricing", - "relatedProducts", - "resourceUrls", - "sources", - "supportedIdes", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "extensions", - "id": "mistral-vibe", - "change": "added", - "fields": [ - "communityUrls", - "confidence", - "description", - "docsUrl", - "familyId", - "githubUrl", - "id", - "lastVerifiedAt", - "latestVersion", - "license", - "name", - "pricing", - "relatedProducts", - "resourceUrls", - "sources", - "supportedIdes", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "extensions", - "id": "opencode-extension", - "change": "added", - "fields": [ - "communityUrls", - "confidence", - "description", - "docsUrl", - "familyId", - "githubUrl", - "id", - "lastVerifiedAt", - "latestVersion", - "license", - "name", - "pricing", - "relatedProducts", - "resourceUrls", - "sources", - "supportedIdes", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "extensions", - "id": "qoder", - "change": "updated", - "fields": ["relatedProducts", "familyId"] - }, - { - "category": "extensions", - "id": "rovo-dev", - "change": "added", - "fields": [ - "communityUrls", - "confidence", - "description", - "docsUrl", - "familyId", - "githubUrl", - "id", - "lastVerifiedAt", - "latestVersion", - "license", - "name", - "pricing", - "relatedProducts", - "resourceUrls", - "sources", - "supportedIdes", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "extensions", - "id": "verdent", - "change": "updated", - "fields": ["relatedProducts", "familyId"] - }, - { - "category": "ides", - "id": "air", - "change": "removed", - "fields": [ - "communityUrls", - "description", - "docsUrl", - "githubUrl", - "id", - "latestVersion", - "license", - "name", - "platforms", - "pricing", - "relatedProducts", - "resourceUrls", - "translations", - "vendor", - "verified", - "websiteUrl" - ] - }, - { - "category": "ides", - "id": "qoder", - "change": "removed", - "fields": [ - "communityUrls", - "description", - "docsUrl", - "githubUrl", - "id", - "latestVersion", - "license", - "name", - "platforms", - "pricing", - "relatedProducts", - "resourceUrls", - "translations", - "vendor", - "verified", - "websiteUrl" - ] - }, - { - "category": "ides", - "id": "trae", - "change": "updated", - "fields": [ - "latestVersion", - "name", - "pricing", - "relatedProducts", - "websiteUrl", - "confidence", - "familyId", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "ides", - "id": "verdent-deck", - "change": "removed", - "fields": [ - "communityUrls", - "description", - "docsUrl", - "githubUrl", - "id", - "latestVersion", - "license", - "name", - "platforms", - "pricing", - "relatedProducts", - "resourceUrls", - "translations", - "vendor", - "verified", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "claude-fable-5", - "change": "updated", - "fields": ["tokenPricing"] - }, - { - "category": "models", - "id": "claude-haiku-3", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "claude-haiku-3-5", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "claude-haiku-4-5", - "change": "updated", - "fields": ["tokenPricing"] - }, - { - "category": "models", - "id": "claude-mythos-5", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "claude-opus-3", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "claude-opus-4", - "change": "updated", - "fields": [ - "lifecycle", - "tokenPricing", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "models", - "id": "claude-opus-4-1", - "change": "updated", - "fields": [ - "lifecycle", - "tokenPricing", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "models", - "id": "claude-opus-4-5", - "change": "updated", - "fields": [ - "lifecycle", - "tokenPricing", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "models", - "id": "claude-opus-4-6", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "claude-opus-4-7", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "claude-opus-4-8", - "change": "updated", - "fields": ["tokenPricing"] - }, - { - "category": "models", - "id": "claude-sonnet-3", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "claude-sonnet-3-5-20240620", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "claude-sonnet-3-5-20241022", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "claude-sonnet-3-7", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "claude-sonnet-4", - "change": "updated", - "fields": [ - "lifecycle", - "tokenPricing", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "models", - "id": "claude-sonnet-4-5", - "change": "updated", - "fields": [ - "lifecycle", - "tokenPricing", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "models", - "id": "claude-sonnet-4-6", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "claude-sonnet-5", - "change": "updated", - "fields": ["tokenPricing"] - }, - { - "category": "models", - "id": "codestral-2405", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "codestral-2501", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "codestral-2508", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "composer", - "change": "updated", - "fields": ["tokenPricing"] - }, - { - "category": "models", - "id": "cursor-composer-2", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "cursor-composer-2-5", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "deepseek-3-2", - "change": "updated", - "fields": [ - "lifecycle", - "tokenPricing", - "verified", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "models", - "id": "deepseek-coder-v2-0724", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "deepseek-r1", - "change": "updated", - "fields": [ - "contextWindow", - "description", - "lifecycle", - "maxOutput", - "releaseDate", - "tokenPricing", - "verified", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "models", - "id": "deepseek-r1-0528", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "deepseek-v3", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "deepseek-v3-1", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "deepseek-v3-2-exp", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "deepseek-v3-terminus", - "change": "updated", - "fields": [ - "contextWindow", - "description", - "lifecycle", - "maxOutput", - "releaseDate", - "tokenPricing", - "verified", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "models", - "id": "deepseek-v4-flash", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "deepseek-v4-pro", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "devstral-2", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "devstral-medium-1-0", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "devstral-small-1-0", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "devstral-small-1-1", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "devstral-small-2", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gemini-2-0-flash", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gemini-2-0-flash-lite", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gemini-2-5-flash", - "change": "updated", - "fields": [ - "knowledgeCutoff", - "releaseDate", - "size", - "tokenPricing", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "models", - "id": "gemini-2-5-flash-lite", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gemini-2-5-pro", - "change": "updated", - "fields": [ - "knowledgeCutoff", - "releaseDate", - "size", - "tokenPricing", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "models", - "id": "gemini-3-1-flash-lite", - "change": "updated", - "fields": ["tokenPricing"] - }, - { - "category": "models", - "id": "gemini-3-1-pro-preview", - "change": "updated", - "fields": ["tokenPricing"] - }, - { - "category": "models", - "id": "gemini-3-5-flash", - "change": "updated", - "fields": ["tokenPricing"] - }, - { - "category": "models", - "id": "gemini-3-flash", - "change": "updated", - "fields": ["tokenPricing"] - }, - { - "category": "models", - "id": "gemini-3-pro", - "change": "updated", - "fields": [ - "lifecycle", - "tokenPricing", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "models", - "id": "glm-4-5", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "glm-4-6", - "change": "updated", - "fields": ["tokenPricing"] - }, - { - "category": "models", - "id": "glm-4-6v", - "change": "updated", - "fields": ["tokenPricing"] - }, - { - "category": "models", - "id": "glm-4-7", - "change": "updated", - "fields": [ - "description", - "docsUrl", - "knowledgeCutoff", - "lifecycle", - "tokenPricing", - "translations", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "models", - "id": "glm-5", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "glm-5-1", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "glm-5-2", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gpt-4-1", - "change": "updated", - "fields": ["tokenPricing"] - }, - { - "category": "models", - "id": "gpt-4-1-mini", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gpt-4-1-nano", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gpt-4o", - "change": "updated", - "fields": ["tokenPricing"] - }, - { - "category": "models", - "id": "gpt-4o-mini", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gpt-5", - "change": "updated", - "fields": ["tokenPricing"] - }, - { - "category": "models", - "id": "gpt-5-1", - "change": "updated", - "fields": ["tokenPricing"] - }, - { - "category": "models", - "id": "gpt-5-1-codex", - "change": "updated", - "fields": ["tokenPricing"] - }, - { - "category": "models", - "id": "gpt-5-1-codex-max", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gpt-5-1-codex-mini", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gpt-5-2", - "change": "updated", - "fields": ["tokenPricing"] - }, - { - "category": "models", - "id": "gpt-5-2-codex", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gpt-5-2-pro", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gpt-5-3-codex", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gpt-5-4", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gpt-5-4-mini", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gpt-5-4-nano", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gpt-5-4-pro", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gpt-5-5", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gpt-5-5-pro", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gpt-5-6-luna", - "change": "updated", - "fields": ["tokenPricing"] - }, - { - "category": "models", - "id": "gpt-5-6-sol", - "change": "updated", - "fields": ["tokenPricing"] - }, - { - "category": "models", - "id": "gpt-5-6-terra", - "change": "updated", - "fields": ["tokenPricing"] - }, - { - "category": "models", - "id": "gpt-5-codex", - "change": "updated", - "fields": ["tokenPricing"] - }, - { - "category": "models", - "id": "gpt-5-mini", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gpt-5-nano", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gpt-5-pro", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "grok-4", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "grok-4-1-fast", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "grok-4-20", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "grok-4-3", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "grok-4-5", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "grok-4-fast", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "grok-build-0-1", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "grok-code-fast-1", - "change": "updated", - "fields": [ - "lifecycle", - "tokenPricing", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "models", - "id": "kat-coder-pro-v1", - "change": "updated", - "fields": ["benchmarks", "tokenPricing", "vendor"] - }, - { - "category": "models", - "id": "kimi-dev-72b", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "kimi-k2-0905", - "change": "updated", - "fields": [ - "lifecycle", - "tokenPricing", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "models", - "id": "kimi-k2-5", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "kimi-k2-6", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "kimi-k2-7-code", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "kimi-k2-instruct", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "kimi-k2-thinking", - "change": "updated", - "fields": [ - "lifecycle", - "tokenPricing", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "models", - "id": "kimi-k3", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "llama-4-maverick", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "llama-4-scout", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "minimax-m2", - "change": "updated", - "fields": ["tokenPricing"] - }, - { - "category": "models", - "id": "minimax-m2-1", - "change": "updated", - "fields": ["tokenPricing"] - }, - { - "category": "models", - "id": "minimax-m2-5", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "minimax-m2-7", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "minimax-m3", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "mistral-medium-3-5", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "mistral-small-4", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "muse-spark-1-1", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "o3", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "o3-mini", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "o4-mini", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "qwen3-5-plus", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "qwen3-6-plus", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "qwen3-7-max", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "qwen3-7-plus", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "qwen3-coder-30b-a3b", - "change": "updated", - "fields": ["tokenPricing"] - }, - { - "category": "models", - "id": "qwen3-coder-480b-a35b", - "change": "updated", - "fields": ["tokenPricing"] - }, - { - "category": "models", - "id": "qwen3-coder-flash", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "qwen3-coder-next", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "qwen3-coder-plus", - "change": "updated", - "fields": ["tokenPricing"] - }, - { - "category": "models", - "id": "qwen3-max-2026-01-23", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "providers", - "id": "kwaikatonai", - "change": "updated", - "fields": ["vendor"] - }, - { - "category": "vendors", - "id": "anomaly", - "change": "added", - "fields": [ - "aliases", - "communityUrls", - "confidence", - "description", - "id", - "lastVerifiedAt", - "name", - "sources", - "translations", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "vendors", - "id": "atlassian", - "change": "added", - "fields": [ - "communityUrls", - "confidence", - "description", - "id", - "lastVerifiedAt", - "name", - "sources", - "translations", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "vendors", - "id": "cline", - "change": "updated", - "fields": ["aliases"] - }, - { - "category": "vendors", - "id": "cline-bot", - "change": "removed", - "fields": [ - "communityUrls", - "description", - "id", - "name", - "translations", - "verified", - "websiteUrl" - ] - }, - { - "category": "vendors", - "id": "continue", - "change": "updated", - "fields": ["aliases"] - }, - { - "category": "vendors", - "id": "continue-dev", - "change": "removed", - "fields": [ - "communityUrls", - "description", - "id", - "name", - "translations", - "verified", - "websiteUrl" - ] - }, - { - "category": "vendors", - "id": "factory-ai", - "change": "updated", - "fields": ["aliases"] - }, - { - "category": "vendors", - "id": "gitlab", - "change": "added", - "fields": [ - "communityUrls", - "confidence", - "description", - "id", - "lastVerifiedAt", - "name", - "sources", - "translations", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "vendors", - "id": "kwai", - "change": "removed", - "fields": [ - "communityUrls", - "description", - "id", - "name", - "translations", - "verified", - "websiteUrl" - ] - }, - { - "category": "vendors", - "id": "kwaikat", - "change": "removed", - "fields": [ - "communityUrls", - "description", - "id", - "name", - "translations", - "verified", - "websiteUrl" - ] - }, - { - "category": "vendors", - "id": "mistral-ai", - "change": "added", - "fields": [ - "aliases", - "communityUrls", - "confidence", - "description", - "id", - "lastVerifiedAt", - "name", - "sources", - "translations", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "vendors", - "id": "moonshot", - "change": "updated", - "fields": ["name", "aliases"] - }, - { - "category": "vendors", - "id": "moonshot-ai", - "change": "removed", - "fields": [ - "communityUrls", - "description", - "id", - "name", - "translations", - "verified", - "websiteUrl" - ] - }, - { - "category": "vendors", - "id": "oh-my-pi", - "change": "added", - "fields": [ - "aliases", - "communityUrls", - "confidence", - "description", - "id", - "lastVerifiedAt", - "name", - "sources", - "translations", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "vendors", - "id": "stagewise", - "change": "added", - "fields": [ - "communityUrls", - "confidence", - "description", - "id", - "lastVerifiedAt", - "name", - "sources", - "translations", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "vendors", - "id": "streamlake", - "change": "updated", - "fields": ["aliases"] - }, - { - "category": "vendors", - "id": "z-ai", - "change": "updated", - "fields": ["aliases"] - } - ] - }, - { - "id": "2026-07-20-latest-models", - "date": "2026-07-20", - "summary": "Added current flagship model families from OpenAI, Anthropic, and Google", - "changes": [ - { - "category": "models", - "id": "claude-fable-5", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "claude-opus-4-8", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "claude-sonnet-5", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gemini-3-1-flash-lite", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gemini-3-1-pro-preview", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gemini-3-5-flash", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gpt-5-6-luna", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gpt-5-6-sol", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - }, - { - "category": "models", - "id": "gpt-5-6-terra", - "change": "added", - "fields": [ - "benchmarks", - "capabilities", - "confidence", - "contextWindow", - "description", - "docsUrl", - "id", - "inputModalities", - "knowledgeCutoff", - "lastVerifiedAt", - "lifecycle", - "maxOutput", - "name", - "outputModalities", - "platformUrls", - "releaseDate", - "size", - "sources", - "tokenPricing", - "translations", - "vendor", - "verified", - "verifiedBy", - "websiteUrl" - ] - } - ] - }, - { - "id": "2026-07-19-data-integrity", - "date": "2026-07-19", - "summary": "Fixed product relationships and expanded official-source provenance for coding assistants", - "changes": [ - { - "category": "clis", - "id": "claude-code-cli", - "change": "updated", - "fields": [ - "docsUrl", - "latestVersion", - "resourceUrls", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "extensions", - "id": "claude-code", - "change": "updated", - "fields": [ - "docsUrl", - "latestVersion", - "resourceUrls", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "extensions", - "id": "droid", - "change": "updated", - "fields": ["relatedProducts"] - }, - { - "category": "extensions", - "id": "gemini-code-assist", - "change": "updated", - "fields": [ - "docsUrl", - "latestVersion", - "license", - "pricing", - "resourceUrls", - "supportedIdes", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "extensions", - "id": "qoder", - "change": "updated", - "fields": ["relatedProducts"] - }, - { - "category": "ides", - "id": "intellij-idea", - "change": "updated", - "fields": ["relatedProducts"] - }, - { - "category": "ides", - "id": "vscode", - "change": "updated", - "fields": ["relatedProducts"] - }, - { - "category": "ides", - "id": "zed", - "change": "updated", - "fields": ["relatedProducts"] - } - ] - }, - { - "id": "2026-07-18-project-review", - "date": "2026-07-18", - "summary": "Backfilled official-source provenance for priority providers and models", - "changes": [ - { - "category": "models", - "id": "claude-haiku-4-5", - "change": "updated", - "fields": ["docsUrl", "confidence", "lastVerifiedAt", "sources", "verifiedBy"] - }, - { - "category": "models", - "id": "gemini-3-flash", - "change": "updated", - "fields": ["docsUrl", "confidence", "lastVerifiedAt", "sources", "verifiedBy"] - }, - { - "category": "models", - "id": "gpt-5-2", - "change": "updated", - "fields": [ - "docsUrl", - "lifecycle", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "providers", - "id": "anthropic", - "change": "updated", - "fields": [ - "applyKeyUrl", - "docsUrl", - "verified", - "confidence", - "lastVerifiedAt", - "sources", - "verifiedBy" - ] - }, - { - "category": "providers", - "id": "google", - "change": "updated", - "fields": ["docsUrl", "verified", "confidence", "lastVerifiedAt", "sources", "verifiedBy"] - }, - { - "category": "providers", - "id": "openai", - "change": "updated", - "fields": ["docsUrl", "verified", "confidence", "lastVerifiedAt", "sources", "verifiedBy"] - } - ] - } - ] -} diff --git a/docs/PROJECT-REVIEW-2026-07-18.md b/docs/PROJECT-REVIEW-2026-07-18.md index ce81809e..5ac78abd 100644 --- a/docs/PROJECT-REVIEW-2026-07-18.md +++ b/docs/PROJECT-REVIEW-2026-07-18.md @@ -74,7 +74,6 @@ Baseline captured on 2026-07-18: integrity, translation placeholders, and missing pricing/benchmark values. - [x] Add freshness policies (for example 30/60/90-day review thresholds by field/category). - [ ] Automate change discovery from official sources, but keep human review before merge. -- [x] Populate a real changelog from manifest diffs instead of keeping an empty static file. ## P1 — Product Experience @@ -173,8 +172,6 @@ evidence; completed items are reflected in the checklists and implementation log canonical pair URLs, and the comparison selector; adding a third model replaces the oldest pick. - Added Playwright browser smoke coverage for search-to-detail navigation, locale-preserving route switches, and persistent model comparison selections, and made it a required CI job. -- Replaced the empty changelog placeholder with a deterministic manifest-diff record and added a CI - guard requiring future manifest changes to be represented in `data/changelogs.json`. - Fixed the search result category badge to use the shared translated category names after browser testing exposed a missing runtime message lookup. - Upgraded Next.js, OpenNext Cloudflare, next-intl, React, Vitest, Wrangler, and AJV to compatible diff --git a/package-lock.json b/package-lock.json index 861e2ec6..b1451476 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3763,64 +3763,132 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/@node-minify/terser": { + "node_modules/@node-minify/core": { "version": "8.0.6", - "resolved": "https://registry.npmjs.org/@node-minify/terser/-/terser-8.0.6.tgz", - "integrity": "sha512-grQ1ipham743ch2c3++C8Isk6toJnxJSyDiwUI/IWUCh4CZFD6aYVw6UAY40IpCnjrq5aXGwiv5OZJn6Pr0hvg==", + "resolved": "https://registry.npmmirror.com/@node-minify/core/-/core-8.0.6.tgz", + "integrity": "sha512-/vxN46ieWDLU67CmgbArEvOb41zlYFOkOtr9QW9CnTrBLuTyGgkyNWC2y5+khvRw3Br58p2B5ZVSx/PxCTru6g==", "license": "MIT", "dependencies": { "@node-minify/utils": "8.0.6", - "terser": "5.16.9" + "glob": "9.3.5", + "mkdirp": "1.0.4" }, "engines": { "node": ">=16.0.0" } }, - "node_modules/@node-minify/utils": { - "version": "8.0.6", - "resolved": "https://registry.npmjs.org/@node-minify/utils/-/utils-8.0.6.tgz", - "integrity": "sha512-csY4qcR7jUwiZmkreNTJhcypQfts2aY2CK+a+rXgXUImZiZiySh0FvwHjRnlqWKvg+y6ae9lHFzDRjBTmqlTIQ==", + "node_modules/@node-minify/core/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/@node-minify/core/node_modules/brace-expansion": { + "version": "2.1.3", + "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.1.3.tgz", + "integrity": "sha512-DRdx5neNsG/QXbniLFWi2YmC/68oeOOmKz6zOjVk6ZS1ZLXgLIKqVEc6hWsmkjBbgii0SwaBTcJ5XKj5gzY/4A==", "license": "MIT", "dependencies": { - "gzip-size": "6.0.0" + "balanced-match": "^1.0.0" + } + }, + "node_modules/@node-minify/core/node_modules/glob": { + "version": "9.3.5", + "resolved": "https://registry.npmmirror.com/glob/-/glob-9.3.5.tgz", + "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "minimatch": "^8.0.2", + "minipass": "^4.2.4", + "path-scurry": "^1.6.1" }, "engines": { - "node": ">=16.0.0" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "license": "MIT", + "node_modules/@node-minify/core/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" + }, + "node_modules/@node-minify/core/node_modules/minimatch": { + "version": "8.0.7", + "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-8.0.7.tgz", + "integrity": "sha512-V+1uQNdzybxa14e/p00HZnQNNcTjnRJjDxg2V8wtkjFctq4M7hXFws4oekyTP0Jebeq7QYtpFyOeBAjc88zvYg==", + "license": "ISC", "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">= 8" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "node_modules/@node-minify/core/node_modules/minipass": { + "version": "4.2.8", + "resolved": "https://registry.npmmirror.com/minipass/-/minipass-4.2.8.tgz", + "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/@node-minify/core/node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmmirror.com/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@node-minify/core/node_modules/path-scurry/node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmmirror.com/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/@node-minify/terser": { + "version": "8.0.6", + "resolved": "https://registry.npmjs.org/@node-minify/terser/-/terser-8.0.6.tgz", + "integrity": "sha512-grQ1ipham743ch2c3++C8Isk6toJnxJSyDiwUI/IWUCh4CZFD6aYVw6UAY40IpCnjrq5aXGwiv5OZJn6Pr0hvg==", "license": "MIT", + "dependencies": { + "@node-minify/utils": "8.0.6", + "terser": "5.16.9" + }, "engines": { - "node": ">= 8" + "node": ">=16.0.0" } }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "node_modules/@node-minify/utils": { + "version": "8.0.6", + "resolved": "https://registry.npmjs.org/@node-minify/utils/-/utils-8.0.6.tgz", + "integrity": "sha512-csY4qcR7jUwiZmkreNTJhcypQfts2aY2CK+a+rXgXUImZiZiySh0FvwHjRnlqWKvg+y6ae9lHFzDRjBTmqlTIQ==", "license": "MIT", "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" + "gzip-size": "6.0.0" }, "engines": { - "node": ">= 8" + "node": ">=16.0.0" } }, "node_modules/@opennextjs/aws": { @@ -3854,32 +3922,6 @@ "next": ">=15.5.21 <16 || >=16.2.11" } }, - "node_modules/@opennextjs/aws/node_modules/@node-minify/core": { - "version": "8.0.5", - "resolved": "https://registry.npmjs.org/@node-minify/core/-/core-8.0.5.tgz", - "integrity": "sha512-uiK27SlEWq4bGRWOprXMwCTEa+fuVQdLehHMTAwGtHeqvE3i6XjKpYLFI7/ecWiGbDzDB1Gcf1NCiVyiVXfajw==", - "license": "MIT", - "dependencies": { - "@node-minify/utils": "8.0.5", - "globby": "11.1.0", - "mkdirp": "1.0.4" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@opennextjs/aws/node_modules/@node-minify/utils": { - "version": "8.0.5", - "resolved": "https://registry.npmjs.org/@node-minify/utils/-/utils-8.0.5.tgz", - "integrity": "sha512-hBetTLSmbXmNF11A11AkfYeTxhPt83HY2oNNIwGSkv7C9V/beHZ0HbqFOmfRBudCc1hpiKZcTshUk7hbG0/XIQ==", - "license": "MIT", - "dependencies": { - "gzip-size": "6.0.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, "node_modules/@opennextjs/cloudflare": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/@opennextjs/cloudflare/-/cloudflare-1.20.2.tgz", @@ -6682,15 +6724,6 @@ "integrity": "sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==", "license": "MIT" }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/assertion-error": { "version": "2.0.1", "resolved": "https://registry.npmmirror.com/assertion-error/-/assertion-error-2.0.1.tgz", @@ -6830,6 +6863,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, "license": "MIT", "dependencies": { "fill-range": "^7.1.1" @@ -7837,18 +7871,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "license": "MIT", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/dotenv": { "version": "16.6.1", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", @@ -8596,34 +8618,6 @@ "node": ">=6.0.0" } }, - "node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -8656,15 +8650,6 @@ ], "license": "BSD-3-Clause" }, - "node_modules/fastq": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", - "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, "node_modules/fault": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", @@ -8714,6 +8699,7 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" @@ -8894,6 +8880,12 @@ "node": ">= 0.8" } }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "license": "ISC" + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -9059,26 +9051,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "license": "MIT", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", @@ -9627,6 +9599,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.12.0" @@ -10718,15 +10691,6 @@ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "license": "MIT" }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, "node_modules/micromark": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", @@ -11500,6 +11464,7 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, "license": "MIT", "dependencies": { "braces": "^3.0.3", @@ -11513,6 +11478,7 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, "license": "MIT", "engines": { "node": ">=8.6" @@ -12128,15 +12094,6 @@ "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", "license": "MIT" }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/pathe": { "version": "2.0.3", "resolved": "https://registry.npmmirror.com/pathe/-/pathe-2.0.3.tgz", @@ -12317,26 +12274,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, "node_modules/range-parser": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.3.0.tgz", @@ -12809,16 +12746,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/reusify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, "node_modules/rfdc": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", @@ -12886,29 +12813,6 @@ "url": "https://opencollective.com/express" } }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -13163,15 +13067,6 @@ "node": ">= 10" } }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/slice-ansi": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", @@ -13590,6 +13485,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, "license": "MIT", "dependencies": { "is-number": "^7.0.0" diff --git a/package.json b/package.json index 5d4af954..fc66800d 100644 --- a/package.json +++ b/package.json @@ -34,8 +34,6 @@ "data-health": "npx tsx scripts/validate/data-health.ts", "data-health:check": "npx tsx scripts/validate/data-health.ts --check-snapshot --fail-on=error", "data-health:report": "npx tsx scripts/validate/data-health.ts --write", - "changelog:check": "npx tsx scripts/validate/changelog.ts --check", - "changelog:generate": "npx tsx scripts/validate/changelog.ts --write", "dev:e2e": "next dev --turbopack -p 3100", "generate": "npx tsx scripts/generate/index.ts", "generate:manifests": "npx tsx scripts/generate/index.ts manifest-indexes", @@ -114,7 +112,6 @@ "node": "^22.0.0" }, "overrides": { - "@node-minify/core": "8.0.5", "next": { "sharp": "0.35.2" }, diff --git a/scripts/validate/changelog.ts b/scripts/validate/changelog.ts deleted file mode 100644 index 9906fbf6..00000000 --- a/scripts/validate/changelog.ts +++ /dev/null @@ -1,264 +0,0 @@ -#!/usr/bin/env node - -import { execFileSync } from 'node:child_process' -import fs from 'node:fs' -import path from 'node:path' -import { fileURLToPath } from 'node:url' - -const MANIFEST_CATEGORIES = [ - 'ides', - 'clis', - 'desktops', - 'extensions', - 'models', - 'providers', - 'vendors', -] as const - -type ManifestCategory = (typeof MANIFEST_CATEGORIES)[number] -type ChangeType = 'added' | 'updated' | 'removed' - -export interface ManifestChange { - category: ManifestCategory - id: string - change: ChangeType - fields: string[] -} - -interface ChangelogEntry { - id: string - date: string - summary: string - changes: ManifestChange[] -} - -interface ChangelogFile { - version: 1 - entries: ChangelogEntry[] -} - -function comparableFields(record: Record | null): string[] { - return record - ? Object.keys(record) - .filter(key => key !== '$schema') - .sort() - : [] -} - -export function createManifestChange( - category: ManifestCategory, - id: string, - before: Record | null, - after: Record | null -): ManifestChange | null { - if (!before && !after) return null - if (!before) return { category, id, change: 'added', fields: comparableFields(after) } - if (!after) return { category, id, change: 'removed', fields: comparableFields(before) } - - const fields = [...new Set([...comparableFields(before), ...comparableFields(after)])].filter( - key => JSON.stringify(before[key]) !== JSON.stringify(after[key]) - ) - return fields.length > 0 ? { category, id, change: 'updated', fields } : null -} - -function runGit(rootDir: string, args: string[]): string { - return execFileSync('git', args, { cwd: rootDir, encoding: 'utf8' }).trim() -} - -function readBaseManifest( - rootDir: string, - base: string, - filePath: string -): Record | null { - try { - return JSON.parse(runGit(rootDir, ['show', `${base}:${filePath}`])) as Record - } catch { - return null - } -} - -function readWorkingManifest(rootDir: string, filePath: string): Record | null { - const absolutePath = path.join(rootDir, filePath) - return fs.existsSync(absolutePath) - ? (JSON.parse(fs.readFileSync(absolutePath, 'utf8')) as Record) - : null -} - -function parseManifestPath(filePath: string): { category: ManifestCategory; id: string } | null { - const match = /^manifests\/([^/]+)\/([^/]+)\.json$/.exec(filePath) - if (!match || !MANIFEST_CATEGORIES.includes(match[1] as ManifestCategory)) return null - return { category: match[1] as ManifestCategory, id: match[2]! } -} - -export function collectManifestChanges(rootDir: string, base: string): ManifestChange[] { - const manifestPaths = MANIFEST_CATEGORIES.map(category => `manifests/${category}`) - const trackedOutput = runGit(rootDir, [ - 'diff', - '--name-status', - '--find-renames', - base, - '--', - ...manifestPaths, - ]) - const untrackedOutput = runGit(rootDir, [ - 'ls-files', - '--others', - '--exclude-standard', - '--', - ...manifestPaths, - ]) - const lines = [ - ...(trackedOutput ? trackedOutput.split('\n') : []), - ...(untrackedOutput ? untrackedOutput.split('\n').map(filePath => `A\t${filePath}`) : []), - ] - if (lines.length === 0) return [] - - const changes: ManifestChange[] = [] - for (const line of lines) { - const [status = '', firstPath, secondPath] = line.split('\t') - const paths = status.startsWith('R') ? [firstPath, secondPath] : [firstPath] - for (const filePath of paths.filter((value): value is string => Boolean(value))) { - const parsed = parseManifestPath(filePath) - if (!parsed) continue - const before = - status.startsWith('A') || (status.startsWith('R') && filePath === secondPath) - ? null - : readBaseManifest(rootDir, base, filePath) - const after = - status.startsWith('D') || (status.startsWith('R') && filePath === firstPath) - ? null - : readWorkingManifest(rootDir, filePath) - const change = createManifestChange(parsed.category, parsed.id, before, after) - if (change) changes.push(change) - } - } - - return changes.sort( - (a, b) => - a.category.localeCompare(b.category) || - a.id.localeCompare(b.id) || - a.change.localeCompare(b.change) - ) -} - -function parseChangelog(content: string): ChangelogFile { - const parsed = JSON.parse(content) as Partial - if (parsed.version === undefined && Object.keys(parsed).length === 0) { - return { version: 1, entries: [] } - } - if (parsed.version !== 1 || !Array.isArray(parsed.entries)) { - throw new Error('data/changelogs.json must contain version 1 and an entries array') - } - return parsed as ChangelogFile -} - -function readChangelog(filePath: string): ChangelogFile { - return parseChangelog(fs.readFileSync(filePath, 'utf8')) -} - -function readBaseChangelog(rootDir: string, base: string): ChangelogFile { - try { - return parseChangelog(runGit(rootDir, ['show', `${base}:data/changelogs.json`])) - } catch { - return { version: 1, entries: [] } - } -} - -function changesMatch(left: ManifestChange, right: ManifestChange): boolean { - return ( - left.category === right.category && - left.id === right.id && - left.change === right.change && - JSON.stringify(left.fields) === JSON.stringify(right.fields) - ) -} - -function validateChangelog(changelog: ChangelogFile): void { - const entryIds = new Set() - for (const entry of changelog.entries) { - if (!entry.id || !/^\d{4}-\d{2}-\d{2}$/.test(entry.date) || !entry.summary) { - throw new Error(`Invalid changelog entry: ${entry.id || '(missing id)'}`) - } - if (entryIds.has(entry.id)) throw new Error(`Duplicate changelog entry id: ${entry.id}`) - entryIds.add(entry.id) - if (!Array.isArray(entry.changes) || entry.changes.length === 0) { - throw new Error(`Changelog entry has no manifest changes: ${entry.id}`) - } - } -} - -function getArgument(name: string): string | null { - const prefix = `--${name}=` - return process.argv.find(argument => argument.startsWith(prefix))?.slice(prefix.length) ?? null -} - -async function main(): Promise { - const rootDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..') - const changelogPath = path.join(rootDir, 'data', 'changelogs.json') - const base = getArgument('base') ?? process.env.CHANGELOG_BASE ?? 'origin/main' - const date = getArgument('date') ?? new Date().toISOString().slice(0, 10) - const id = getArgument('id') ?? `${date}-manifest-update` - const changes = collectManifestChanges(rootDir, base) - const summary = - getArgument('summary') ?? - `${changes.length} manifest record${changes.length === 1 ? '' : 's'} changed` - const changelog = readChangelog(changelogPath) - - if (process.argv.includes('--write')) { - if (changes.length === 0) throw new Error(`No manifest changes found relative to ${base}`) - const entry: ChangelogEntry = { - id, - date, - summary, - changes, - } - changelog.entries = [...changelog.entries.filter(existing => existing.id !== id), entry].sort( - (a, b) => b.date.localeCompare(a.date) || b.id.localeCompare(a.id) - ) - fs.writeFileSync(changelogPath, `${JSON.stringify(changelog, null, 2)}\n`, 'utf8') - execFileSync('npx', ['biome', 'format', '--write', changelogPath], { - cwd: rootDir, - stdio: 'ignore', - }) - console.log(`Wrote ${changes.length} manifest changes to data/changelogs.json`) - } - - validateChangelog(changelog) - - if (process.argv.includes('--check') && changes.length > 0) { - try { - execFileSync('git', ['diff', '--quiet', base, '--', 'data/changelogs.json'], { cwd: rootDir }) - throw new Error('Manifest changes require an update to data/changelogs.json') - } catch (error) { - if (error instanceof Error && error.message.startsWith('Manifest changes require')) - throw error - } - - const baseChangelog = readBaseChangelog(rootDir, base) - const changedEntries = changelog.entries.filter(entry => { - const previous = baseChangelog.entries.find(candidate => candidate.id === entry.id) - return !previous || JSON.stringify(previous) !== JSON.stringify(entry) - }) - const missing = changes.filter( - change => - !changedEntries.some(entry => entry.changes.some(saved => changesMatch(change, saved))) - ) - if (missing.length > 0) { - throw new Error( - `Changelog is missing manifest changes: ${missing.map(change => `${change.category}/${change.id}`).join(', ')}` - ) - } - } - - console.log( - `Changelog valid: ${changelog.entries.length} entries; ${changes.length} manifest changes relative to ${base}` - ) -} - -const currentFile = fileURLToPath(import.meta.url) -if (process.argv[1] && path.resolve(process.argv[1]) === currentFile) { - main().catch(error => { - console.error(error) - process.exitCode = 1 - }) -} diff --git a/tests/changelog.test.ts b/tests/changelog.test.ts deleted file mode 100644 index 3f61b7da..00000000 --- a/tests/changelog.test.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { describe, expect, it } from 'vitest' - -import { createManifestChange } from '../scripts/validate/changelog' - -describe('manifest changelog generation', () => { - it('captures added and removed records', () => { - expect( - createManifestChange('models', 'new-model', null, { id: 'new-model', name: 'New' }) - ).toEqual({ - category: 'models', - id: 'new-model', - change: 'added', - fields: ['id', 'name'], - }) - expect(createManifestChange('providers', 'old', { id: 'old' }, null)).toEqual({ - category: 'providers', - id: 'old', - change: 'removed', - fields: ['id'], - }) - }) - - it('reports only changed top-level fields', () => { - expect( - createManifestChange( - 'models', - 'example', - { $schema: 'old', id: 'example', name: 'Before', verified: false }, - { $schema: 'new', id: 'example', name: 'After', verified: true } - ) - ).toEqual({ - category: 'models', - id: 'example', - change: 'updated', - fields: ['name', 'verified'], - }) - }) - - it('ignores records without material changes', () => { - expect(createManifestChange('vendors', 'same', { id: 'same' }, { id: 'same' })).toBeNull() - }) -}) From 95e3b9f96e99c4ebd630646db19946acf76536d4 Mon Sep 17 00:00:00 2001 From: Pan YANG Date: Wed, 29 Jul 2026 00:22:57 +0800 Subject: [PATCH 3/8] feat(data): automate catalog freshness --- .github/workflows/check-data-health.yml | 119 +++++++ .github/workflows/monitor-model-sources.yml | 65 ++++ .github/workflows/update-benchmarks.yml | 73 ++++ .github/workflows/update-product-versions.yml | 76 ++++ cspell.json | 2 + .../model-intelligence-index.schema.json | 21 -- ...model-price-intelligence-index.schema.json | 23 -- data/model-intelligence-index.json | 4 - data/model-price-intelligence-index.json | 30 +- manifests/$schemas/model.schema.json | 77 ++++ manifests/$schemas/ref/entity.schema.json | 22 ++ manifests/$schemas/ref/product.schema.json | 68 ++++ manifests/clis/claude-code-cli.json | 6 +- manifests/clis/cline-cli.json | 6 +- manifests/clis/codebuddy-cli.json | 6 +- manifests/clis/codex-cli.json | 6 +- manifests/clis/continue-cli.json | 4 + manifests/clis/cursor-cli.json | 6 +- manifests/clis/gemini-cli.json | 6 +- manifests/clis/github-copilot-cli.json | 6 +- manifests/clis/kilo-code-cli.json | 4 + manifests/clis/kode.json | 6 +- manifests/clis/mistral-vibe-cli.json | 6 +- manifests/clis/neovate-code.json | 6 +- manifests/clis/opencode.json | 6 +- manifests/clis/qoder-cli.json | 6 +- manifests/clis/qwen-code.json | 6 +- manifests/desktops/opencode-desktop.json | 6 +- manifests/extensions/claude-code.json | 6 +- manifests/extensions/codex.json | 6 +- manifests/extensions/droid.json | 6 +- manifests/extensions/kimi-code.json | 6 +- manifests/extensions/mistral-vibe.json | 6 +- manifests/extensions/opencode-extension.json | 6 +- manifests/extensions/rovo-dev.json | 6 +- manifests/models/claude-haiku-4-5.json | 7 +- manifests/models/claude-opus-4.json | 16 +- manifests/models/claude-sonnet-4-5.json | 9 + manifests/models/claude-sonnet-4.json | 9 + manifests/models/deepseek-3-2.json | 7 +- manifests/models/gemini-2-5-flash.json | 9 + manifests/models/gemini-2-5-pro.json | 9 + manifests/models/gemini-3-5-flash.json | 14 +- manifests/models/glm-4-6.json | 9 + manifests/models/glm-5-2.json | 14 +- manifests/models/gpt-4-1.json | 9 + manifests/models/gpt-4o.json | 9 + manifests/models/gpt-5-1.json | 9 + manifests/models/gpt-5-6-sol.json | 7 +- manifests/models/gpt-5.json | 9 + manifests/models/grok-4-20.json | 7 +- manifests/models/hy3.json | 19 +- manifests/models/kimi-k2-thinking.json | 7 +- manifests/models/minimax-m2-7.json | 7 +- manifests/models/minimax-m2.json | 9 + manifests/models/mistral-small-4.json | 7 +- manifests/models/qwen3-7-max.json | 42 ++- manifests/models/qwen3-7-plus.json | 28 +- package.json | 7 +- scripts/README.md | 17 +- scripts/fetch/fetch-benchmarks.ts | 43 +++ scripts/fetch/fetch-model-sources.ts | 52 +++ scripts/fetch/fetch-product-versions.ts | 42 +++ scripts/fetch/index.ts | 1 + scripts/fetch/lib/benchmark-sync.ts | 199 +++++++++++ scripts/fetch/lib/model-source-sync.ts | 198 +++++++++++ scripts/fetch/lib/product-version-sync.ts | 336 ++++++++++++++++++ scripts/validate/data-health.ts | 29 +- .../model-intelligence-index/page.tsx | 4 +- src/lib/model-intelligence-index.ts | 20 +- src/lib/model-price-intelligence-index.ts | 95 +++-- src/types/manifests.ts | 54 +++ tests/benchmark-sync.test.ts | 131 +++++++ tests/data-health.test.ts | 19 + tests/model-intelligence-index.test.ts | 10 - tests/model-price-intelligence-index.test.ts | 3 +- tests/model-source-sync.test.ts | 126 +++++++ tests/product-version-sync.test.ts | 223 ++++++++++++ tests/validate/manifests.schema.test.ts | 1 + tests/validate/ranking-data.schema.test.ts | 6 +- tests/validate/typesAlignment.test.ts | 5 + 81 files changed, 2416 insertions(+), 191 deletions(-) create mode 100644 .github/workflows/check-data-health.yml create mode 100644 .github/workflows/monitor-model-sources.yml create mode 100644 .github/workflows/update-benchmarks.yml create mode 100644 .github/workflows/update-product-versions.yml delete mode 100644 data/$schemas/model-intelligence-index.schema.json delete mode 100644 data/model-intelligence-index.json create mode 100644 scripts/fetch/fetch-benchmarks.ts create mode 100644 scripts/fetch/fetch-model-sources.ts create mode 100644 scripts/fetch/fetch-product-versions.ts create mode 100644 scripts/fetch/lib/benchmark-sync.ts create mode 100644 scripts/fetch/lib/model-source-sync.ts create mode 100644 scripts/fetch/lib/product-version-sync.ts create mode 100644 tests/benchmark-sync.test.ts create mode 100644 tests/model-source-sync.test.ts create mode 100644 tests/product-version-sync.test.ts diff --git a/.github/workflows/check-data-health.yml b/.github/workflows/check-data-health.yml new file mode 100644 index 00000000..67510236 --- /dev/null +++ b/.github/workflows/check-data-health.yml @@ -0,0 +1,119 @@ +name: Check Current Data Health + +on: + schedule: + - cron: '0 3 * * 1' + workflow_dispatch: + +concurrency: + group: check-current-data-health + cancel-in-progress: false + +permissions: + contents: read + issues: write + +jobs: + check-data-health: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v7 + + - name: Setup Node.js + uses: actions/setup-node@v7 + with: + node-version: '22' + cache: 'npm' + + - name: Install dependencies + run: npm ci + + - name: Check current data health + id: data-health + continue-on-error: true + run: | + npx tsx scripts/validate/data-health.ts \ + --as-of="$(TZ=Asia/Shanghai date +%F)" \ + --fail-on=error \ + --fail-on-code=stale-verification,future-verification-date \ + 2>&1 | tee data-health-current.log + + - name: Report stale or invalid data + if: steps.data-health.outcome == 'failure' + uses: actions/github-script@v8 + with: + script: | + const fs = require('node:fs'); + const title = 'Current manifest data requires review'; + const output = fs.readFileSync('data-health-current.log', 'utf8').slice(-6000); + const body = `## Current Data Health Check Failed + + The scheduled check evaluates freshness against today's date in Asia/Shanghai without + rewriting the committed snapshot. + + **Check run:** [View details](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) + + \`\`\`text + ${output} + \`\`\``; + + const issues = await github.paginate(github.rest.issues.listForRepo, { + owner: context.repo.owner, + repo: context.repo.repo, + state: 'open', + labels: 'automated', + per_page: 100 + }); + const existingIssue = issues.find(issue => issue.title === title); + + if (!existingIssue) { + await github.rest.issues.create({ + owner: context.repo.owner, + repo: context.repo.repo, + title, + body, + labels: ['automated', 'maintenance'] + }); + } else { + await github.rest.issues.update({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: existingIssue.number, + body + }); + } + + - name: Close resolved data-health issues + if: steps.data-health.outcome == 'success' + uses: actions/github-script@v8 + with: + script: | + const issues = await github.paginate(github.rest.issues.listForRepo, { + owner: context.repo.owner, + repo: context.repo.repo, + state: 'open', + labels: 'automated', + per_page: 100 + }); + + for (const issue of issues.filter(issue => issue.title === 'Current manifest data requires review')) { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issue.number, + body: `Current-date data health passed in ${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}.` + }); + await github.rest.issues.update({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issue.number, + state: 'closed', + state_reason: 'completed' + }); + } + + - name: Fail after reporting + if: steps.data-health.outcome == 'failure' + run: exit 1 diff --git a/.github/workflows/monitor-model-sources.yml b/.github/workflows/monitor-model-sources.yml new file mode 100644 index 00000000..3bea449f --- /dev/null +++ b/.github/workflows/monitor-model-sources.yml @@ -0,0 +1,65 @@ +name: Monitor Model Pricing and Lifecycle Sources + +on: + schedule: + - cron: '0 4 * * 1' + workflow_dispatch: + +concurrency: + group: monitor-model-sources + cancel-in-progress: false + +permissions: + contents: write + pull-requests: write + +jobs: + monitor-model-sources: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v7 + + - name: Setup Node.js + uses: actions/setup-node@v7 + with: + node-version: '22' + cache: 'npm' + + - name: Install dependencies + run: npm ci + + - name: Check monitored official sources + run: npm run fetch:model-sources + + - name: Validate monitoring metadata + run: | + npm run test:validate + npm run format:check + npm run biome:check + git diff --check + + - name: Check for changes + id: git-check + run: | + git diff --exit-code manifests/models || echo "changes=true" >> "$GITHUB_OUTPUT" + + - name: Create review pull request + if: steps.git-check.outputs.changes == 'true' + uses: peter-evans/create-pull-request@v8 + with: + token: ${{ secrets.GITHUB_TOKEN }} + commit-message: 'chore(data): flag changed model sources' + title: 'chore(data): review changed model sources' + body: | + ## Review required + One or more monitored official pricing or lifecycle pages changed. + + This automation updates only normalized source-content digests and observation dates. + It deliberately does **not** change token prices, model availability, lifecycle status, + or any other model fact. Review the cited official pages before changing those fields. + branch: auto-review-model-sources + delete-branch: true + labels: | + automated diff --git a/.github/workflows/update-benchmarks.yml b/.github/workflows/update-benchmarks.yml new file mode 100644 index 00000000..2dc59c28 --- /dev/null +++ b/.github/workflows/update-benchmarks.yml @@ -0,0 +1,73 @@ +name: Update Benchmarks + +on: + schedule: + - cron: '30 2 * * 1' + workflow_dispatch: + +concurrency: + group: update-benchmarks + cancel-in-progress: false + +permissions: + contents: write + pull-requests: write + +jobs: + update-benchmarks: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v7 + + - name: Setup Node.js + uses: actions/setup-node@v7 + with: + node-version: '22' + cache: 'npm' + + - name: Install dependencies + run: npm ci + + - name: Refresh exact benchmark mappings + run: npm run fetch:benchmarks + + - name: Regenerate manifest modules + run: npm run generate:manifests + + - name: Validate updated data + run: | + npm run test:validate + npm run data-health:check + npm run format:check + npm run biome:check + git diff --check + + - name: Check for changes + id: git-check + run: | + git diff --exit-code manifests src/lib/generated || echo "changes=true" >> "$GITHUB_OUTPUT" + + - name: Create pull request + if: steps.git-check.outputs.changes == 'true' + uses: peter-evans/create-pull-request@v8 + with: + token: ${{ secrets.GITHUB_TOKEN }} + commit-message: 'chore(data): refresh benchmark scores' + title: 'chore(data): refresh benchmark scores' + body: | + ## Summary + Automated refresh from exact entries in the official SWE-bench leaderboard data. + + Each model manifest declares the upstream result ID and exact displayed label. The + refresh fails rather than applying fuzzy model-name matching. + + ## Validation + - Manifest schemas + - Generated manifest modules + - Data health + branch: auto-update-benchmarks + delete-branch: true + labels: | + automated diff --git a/.github/workflows/update-product-versions.yml b/.github/workflows/update-product-versions.yml new file mode 100644 index 00000000..46f51898 --- /dev/null +++ b/.github/workflows/update-product-versions.yml @@ -0,0 +1,76 @@ +name: Update Product Versions + +on: + schedule: + - cron: '0 2 * * 1' + workflow_dispatch: + +concurrency: + group: update-product-versions + cancel-in-progress: false + +permissions: + contents: write + pull-requests: write + +jobs: + update-product-versions: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v7 + + - name: Setup Node.js + uses: actions/setup-node@v7 + with: + node-version: '22' + cache: 'npm' + + - name: Install dependencies + run: npm ci + + - name: Refresh tracked product versions + run: npm run fetch:product-versions + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Regenerate manifest modules + run: npm run generate:manifests + + - name: Validate updated data + run: | + npm run test:validate + npm run validate:i18n + npm run data-health:check + npm run format:check + npm run biome:check + git diff --check + + - name: Check for changes + id: git-check + run: | + git diff --exit-code manifests src/lib/generated || echo "changes=true" >> "$GITHUB_OUTPUT" + + - name: Create pull request + if: steps.git-check.outputs.changes == 'true' + uses: peter-evans/create-pull-request@v8 + with: + token: ${{ secrets.GITHUB_TOKEN }} + commit-message: 'chore(data): refresh product versions' + title: 'chore(data): refresh product versions' + body: | + ## Summary + Automated refresh of product versions from the registry sources declared in each manifest. + + ## Validation + - Manifest schemas + - Generated manifest modules + - Internationalization structure + - Data health + + The workflow preserves existing values when any configured source cannot be verified. + branch: auto-update-product-versions + delete-branch: true + labels: | + automated diff --git a/cspell.json b/cspell.json index ce31117e..9cc860e4 100644 --- a/cspell.json +++ b/cspell.json @@ -241,6 +241,7 @@ "mengdebug", "menginstal", "mnda", + "mistralai", "modalli", "modaliteleri", "modlu", @@ -248,6 +249,7 @@ "Modları", "multilíngue", "npmjs", + "pypi", "orkestr", "мультимодальный", "мультимодального", diff --git a/data/$schemas/model-intelligence-index.schema.json b/data/$schemas/model-intelligence-index.schema.json deleted file mode 100644 index c7e61ca1..00000000 --- a/data/$schemas/model-intelligence-index.schema.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "title": "Model Intelligence Index Configuration", - "description": "Editorial display configuration for the model intelligence ranking.", - "type": "object", - "properties": { - "$schema": { - "type": "string" - }, - "hiddenVendorIds": { - "type": "array", - "items": { - "type": "string", - "pattern": "^[a-z0-9-]+$" - }, - "uniqueItems": true - } - }, - "required": ["$schema", "hiddenVendorIds"], - "additionalProperties": false -} diff --git a/data/$schemas/model-price-intelligence-index.schema.json b/data/$schemas/model-price-intelligence-index.schema.json index 741d8183..019674fe 100644 --- a/data/$schemas/model-price-intelligence-index.schema.json +++ b/data/$schemas/model-price-intelligence-index.schema.json @@ -57,33 +57,10 @@ }, "linearLabelAnchor": { "$ref": "#/$defs/labelAnchor" - }, - "usdPriceOverride": { - "$ref": "#/$defs/usdPriceOverride" } }, "required": ["modelId", "labelDx", "labelDy", "labelAnchor"], "additionalProperties": false - }, - "usdPriceOverride": { - "type": "object", - "properties": { - "input": { - "type": "number", - "exclusiveMinimum": 0 - }, - "output": { - "type": "number", - "exclusiveMinimum": 0 - }, - "sourceUrl": { - "type": "string", - "format": "uri", - "pattern": "^https://" - } - }, - "required": ["input", "output", "sourceUrl"], - "additionalProperties": false } } } diff --git a/data/model-intelligence-index.json b/data/model-intelligence-index.json deleted file mode 100644 index f74dd810..00000000 --- a/data/model-intelligence-index.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "$schema": "./$schemas/model-intelligence-index.schema.json", - "hiddenVendorIds": ["mistral-ai"] -} diff --git a/data/model-price-intelligence-index.json b/data/model-price-intelligence-index.json index 0cbfff38..f1574da6 100644 --- a/data/model-price-intelligence-index.json +++ b/data/model-price-intelligence-index.json @@ -28,12 +28,7 @@ "labelAnchor": "start", "linearLabelDx": -16, "linearLabelDy": -46, - "linearLabelAnchor": "end", - "usdPriceOverride": { - "input": 0.14, - "output": 0.58, - "sourceUrl": "https://artificialanalysis.ai/models/hy3" - } + "linearLabelAnchor": "end" }, { "modelId": "minimax-m3", @@ -60,12 +55,7 @@ "labelAnchor": "start", "linearLabelDx": 18, "linearLabelDy": -22, - "linearLabelAnchor": "start", - "usdPriceOverride": { - "input": 0.4, - "output": 1.6, - "sourceUrl": "https://artificialanalysis.ai/models/qwen3-7-plus" - } + "linearLabelAnchor": "start" }, { "modelId": "glm-5-2", @@ -113,12 +103,7 @@ "modelId": "qwen3-7-max", "labelDx": -10, "labelDy": 24, - "labelAnchor": "end", - "usdPriceOverride": { - "input": 2.5, - "output": 7.5, - "sourceUrl": "https://artificialanalysis.ai/models/qwen3-7-max" - } + "labelAnchor": "end" }, { "modelId": "gemini-3-1-pro-preview", @@ -144,6 +129,15 @@ "labelDy": 34, "labelAnchor": "end" }, + { + "modelId": "claude-fable-5", + "labelDx": 12, + "labelDy": -14, + "labelAnchor": "start", + "linearLabelDx": -10, + "linearLabelDy": -14, + "linearLabelAnchor": "end" + }, { "modelId": "gpt-5-6-sol", "labelDx": 8, diff --git a/manifests/$schemas/model.schema.json b/manifests/$schemas/model.schema.json index bd24099b..a79666a6 100644 --- a/manifests/$schemas/model.schema.json +++ b/manifests/$schemas/model.schema.json @@ -27,6 +27,10 @@ "tokenPricing": { "$ref": "#/$defs/tokenPricing" }, + "referenceTokenPricing": { + "$ref": "#/$defs/referenceTokenPricing", + "description": "Optional externally tracked token pricing used when the first-party offer is unavailable or not directly comparable. This must not replace tokenPricing." + }, "releaseDate": { "type": ["string", "null"], "format": "date", @@ -115,6 +119,15 @@ ], "additionalProperties": false }, + "benchmarkTracking": { + "type": "array", + "description": "Exact upstream leaderboard entries used to refresh benchmark fields without fuzzy model-name matching", + "items": { + "$ref": "#/$defs/benchmarkTracking" + }, + "minItems": 1, + "uniqueItems": true + }, "platformUrls": { "$ref": "./ref/platform-urls.schema.json", "description": "URLs to various third-party platform pages for this model" @@ -137,6 +150,30 @@ } ], "$defs": { + "benchmarkTracking": { + "type": "object", + "properties": { + "provider": { + "const": "swe-bench" + }, + "benchmark": { + "const": "sweBench" + }, + "leaderboard": { + "const": "Verified" + }, + "resultId": { + "type": "string", + "minLength": 1 + }, + "modelLabel": { + "type": "string", + "minLength": 1 + } + }, + "required": ["provider", "benchmark", "leaderboard", "resultId", "modelLabel"], + "additionalProperties": false + }, "tokenPricing": { "description": "First-party, pay-as-you-go standard API token pricing. Rates use the offer's native currency per million tokens.", "oneOf": [ @@ -320,6 +357,46 @@ }, "required": ["input", "output", "cacheRead", "cacheWrite"], "additionalProperties": false + }, + "referenceTokenPricing": { + "type": "object", + "properties": { + "currency": { + "type": "string", + "pattern": "^[A-Z]{3}$", + "description": "ISO 4217 currency code" + }, + "basis": { + "type": "string", + "enum": ["first-party-api", "provider-median"], + "description": "Whether the tracked price represents the model vendor's API or a median across third-party API providers" + }, + "rates": { + "$ref": "#/$defs/tokenPricingRates" + }, + "source": { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 1 + }, + "url": { + "type": "string", + "format": "uri", + "pattern": "^https://" + }, + "observedAt": { + "type": "string", + "format": "date" + } + }, + "required": ["name", "url", "observedAt"], + "additionalProperties": false + } + }, + "required": ["currency", "basis", "rates", "source"], + "additionalProperties": false } } } diff --git a/manifests/$schemas/ref/entity.schema.json b/manifests/$schemas/ref/entity.schema.json index 627e8771..e1b2adad 100644 --- a/manifests/$schemas/ref/entity.schema.json +++ b/manifests/$schemas/ref/entity.schema.json @@ -84,10 +84,32 @@ }, "minItems": 1, "uniqueItems": true + }, + "changeTracking": { + "$ref": "#/$defs/sourceChangeTracking", + "description": "Optional content fingerprint used to detect upstream source changes without automatically accepting field-value changes" } }, "required": ["url"], "additionalProperties": false + }, + "sourceChangeTracking": { + "type": "object", + "properties": { + "method": { + "const": "normalized-content-sha256" + }, + "digest": { + "type": ["string", "null"], + "pattern": "^sha256:[a-f0-9]{64}$" + }, + "observedAt": { + "type": ["string", "null"], + "format": "date" + } + }, + "required": ["method", "digest", "observedAt"], + "additionalProperties": false } } } diff --git a/manifests/$schemas/ref/product.schema.json b/manifests/$schemas/ref/product.schema.json index 3c2d9e8a..8579501c 100644 --- a/manifests/$schemas/ref/product.schema.json +++ b/manifests/$schemas/ref/product.schema.json @@ -19,6 +19,10 @@ "type": "string", "description": "The latest stable version number (typically found on download page or changelog page)" }, + "releaseTracking": { + "$ref": "#/$defs/releaseTracking", + "description": "Optional declarative source used to refresh latestVersion without embedding product data in synchronization code" + }, "githubUrl": { "type": ["string", "null"], "format": "uri", @@ -62,6 +66,70 @@ } ], "$defs": { + "releaseTracking": { + "oneOf": [ + { + "type": "object", + "properties": { + "provider": { + "const": "npm" + }, + "identifier": { + "type": "string", + "minLength": 1 + }, + "channel": { + "type": "string", + "pattern": "^[a-z][a-z0-9._-]*$" + } + }, + "required": ["provider", "identifier"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "provider": { + "enum": ["homebrew-formula", "homebrew-cask", "crates-io", "pypi"] + }, + "identifier": { + "type": "string", + "pattern": "^[a-z0-9][a-z0-9+._@-]*$" + } + }, + "required": ["provider", "identifier"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "provider": { + "const": "vscode-marketplace" + }, + "identifier": { + "type": "string", + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_-]*\\.[a-zA-Z0-9][a-zA-Z0-9._-]*$" + } + }, + "required": ["provider", "identifier"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "provider": { + "const": "github-release" + }, + "identifier": { + "type": "string", + "pattern": "^[a-zA-Z0-9._-]+/[a-zA-Z0-9._-]+$" + } + }, + "required": ["provider", "identifier"], + "additionalProperties": false + } + ] + }, "relatedProducts": { "type": "array", "description": "Related products (IDEs, CLIs, extensions, or desktop apps)", diff --git a/manifests/clis/claude-code-cli.json b/manifests/clis/claude-code-cli.json index 27f8825d..0eb90cb7 100644 --- a/manifests/clis/claude-code-cli.json +++ b/manifests/clis/claude-code-cli.json @@ -108,7 +108,11 @@ "websiteUrl": "https://code.claude.com", "docsUrl": "https://code.claude.com/docs", "vendor": "Anthropic", - "latestVersion": "2.1.215", + "latestVersion": "2.1.220", + "releaseTracking": { + "provider": "npm", + "identifier": "@anthropic-ai/claude-code" + }, "githubUrl": "https://github.com/anthropics/claude-code", "license": "Proprietary", "pricing": [ diff --git a/manifests/clis/cline-cli.json b/manifests/clis/cline-cli.json index cfaa2989..cf4954b5 100644 --- a/manifests/clis/cline-cli.json +++ b/manifests/clis/cline-cli.json @@ -42,7 +42,11 @@ "websiteUrl": "https://cline.bot/cline-cli", "docsUrl": "https://cline.bot/docs", "vendor": "Cline Bot", - "latestVersion": "Preview", + "latestVersion": "3.0.46", + "releaseTracking": { + "provider": "npm", + "identifier": "cline" + }, "githubUrl": null, "license": "Proprietary", "pricing": [ diff --git a/manifests/clis/codebuddy-cli.json b/manifests/clis/codebuddy-cli.json index 9cdb4322..9634581c 100644 --- a/manifests/clis/codebuddy-cli.json +++ b/manifests/clis/codebuddy-cli.json @@ -42,7 +42,11 @@ "websiteUrl": "https://www.codebuddy.ai/cli", "docsUrl": "https://www.codebuddy.ai/docs/cli", "vendor": "Tencent", - "latestVersion": "Latest", + "latestVersion": "1.0.0", + "releaseTracking": { + "provider": "npm", + "identifier": "codebuddy-cli" + }, "githubUrl": null, "license": "Proprietary", "pricing": [ diff --git a/manifests/clis/codex-cli.json b/manifests/clis/codex-cli.json index 1afbd7c6..921d4329 100644 --- a/manifests/clis/codex-cli.json +++ b/manifests/clis/codex-cli.json @@ -43,7 +43,11 @@ "websiteUrl": "https://openai.com/codex", "docsUrl": "https://developers.openai.com/codex/cli", "vendor": "OpenAI", - "latestVersion": "0.44.0", + "latestVersion": "0.145.0", + "releaseTracking": { + "provider": "npm", + "identifier": "@openai/codex" + }, "githubUrl": "https://github.com/openai/codex", "license": "Apache-2.0", "pricing": [ diff --git a/manifests/clis/continue-cli.json b/manifests/clis/continue-cli.json index 8abf3bdb..6b643f9b 100644 --- a/manifests/clis/continue-cli.json +++ b/manifests/clis/continue-cli.json @@ -78,6 +78,10 @@ "vendor": "Continue Dev", "familyId": "continue", "latestVersion": "2.0.0", + "releaseTracking": { + "provider": "npm", + "identifier": "@continuedev/cli" + }, "githubUrl": "https://github.com/continuedev/continue", "license": "Apache-2.0", "pricing": [], diff --git a/manifests/clis/cursor-cli.json b/manifests/clis/cursor-cli.json index 8488197d..0ac25135 100644 --- a/manifests/clis/cursor-cli.json +++ b/manifests/clis/cursor-cli.json @@ -42,7 +42,11 @@ "websiteUrl": "https://cursor.com/cli", "docsUrl": "https://cursor.com/docs/cli/overview", "vendor": "Anysphere", - "latestVersion": "2025.11.25-e276529", + "latestVersion": "2026.07.23-e383d2b", + "releaseTracking": { + "provider": "homebrew-cask", + "identifier": "cursor-cli" + }, "githubUrl": "https://github.com/cursor/cursor", "license": "Proprietary", "pricing": [ diff --git a/manifests/clis/gemini-cli.json b/manifests/clis/gemini-cli.json index 573c4743..b568c374 100644 --- a/manifests/clis/gemini-cli.json +++ b/manifests/clis/gemini-cli.json @@ -73,7 +73,11 @@ "websiteUrl": "https://geminicli.com", "docsUrl": "https://geminicli.com/docs", "vendor": "Google", - "latestVersion": "0.50.0", + "latestVersion": "0.52.0", + "releaseTracking": { + "provider": "npm", + "identifier": "@google/gemini-cli" + }, "githubUrl": "https://github.com/google-gemini/gemini-cli", "license": "Apache-2.0", "pricing": [ diff --git a/manifests/clis/github-copilot-cli.json b/manifests/clis/github-copilot-cli.json index 9a3686fb..73be6122 100644 --- a/manifests/clis/github-copilot-cli.json +++ b/manifests/clis/github-copilot-cli.json @@ -42,7 +42,11 @@ "websiteUrl": "https://github.com/features/copilot/cli", "docsUrl": "https://docs.github.com/en/copilot/concepts/agents/about-copilot-cli", "vendor": "GitHub", - "latestVersion": "0.0.365", + "latestVersion": "1.0.75", + "releaseTracking": { + "provider": "npm", + "identifier": "@github/copilot" + }, "githubUrl": "https://github.com/github/copilot-cli", "license": "Proprietary", "pricing": [ diff --git a/manifests/clis/kilo-code-cli.json b/manifests/clis/kilo-code-cli.json index bb4312fa..9b08071d 100644 --- a/manifests/clis/kilo-code-cli.json +++ b/manifests/clis/kilo-code-cli.json @@ -43,6 +43,10 @@ "docsUrl": "https://kilo.ai/docs/code-with-ai/platforms/cli", "vendor": "Kilo", "latestVersion": "7.4.16", + "releaseTracking": { + "provider": "npm", + "identifier": "@kilocode/cli" + }, "githubUrl": "https://github.com/Kilo-Org/kilocode", "license": "Apache-2.0", "familyId": "kilo-code", diff --git a/manifests/clis/kode.json b/manifests/clis/kode.json index 32fe86fd..53e8c6d6 100644 --- a/manifests/clis/kode.json +++ b/manifests/clis/kode.json @@ -42,7 +42,11 @@ "websiteUrl": "https://github.com/shareAI-lab/Kode", "docsUrl": "https://github.com/shareAI-lab/Kode/blob/main/README.md", "vendor": "shareAI Lab", - "latestVersion": "1.2.0", + "latestVersion": "2.2.1", + "releaseTracking": { + "provider": "npm", + "identifier": "@shareai-lab/kode" + }, "githubUrl": "https://github.com/shareAI-lab/Kode-cli", "license": "Apache-2.0", "pricing": [ diff --git a/manifests/clis/mistral-vibe-cli.json b/manifests/clis/mistral-vibe-cli.json index 4a9492c4..32c1ac44 100644 --- a/manifests/clis/mistral-vibe-cli.json +++ b/manifests/clis/mistral-vibe-cli.json @@ -56,7 +56,11 @@ "websiteUrl": "https://mistral.ai/products/vibe", "docsUrl": "https://docs.mistral.ai/vibe/code/overview", "vendor": "Mistral AI", - "latestVersion": "Latest", + "latestVersion": "2.23.0", + "releaseTracking": { + "provider": "pypi", + "identifier": "mistral-vibe" + }, "githubUrl": null, "license": "Proprietary", "pricing": [ diff --git a/manifests/clis/neovate-code.json b/manifests/clis/neovate-code.json index bcb3a05f..8ab03fc7 100644 --- a/manifests/clis/neovate-code.json +++ b/manifests/clis/neovate-code.json @@ -42,7 +42,11 @@ "websiteUrl": "https://neovateai.dev", "docsUrl": "https://neovateai.dev/en/docs/overview", "vendor": "Ant Group", - "latestVersion": "0.12.7", + "latestVersion": "0.28.5", + "releaseTracking": { + "provider": "npm", + "identifier": "@neovate/code" + }, "githubUrl": "https://github.com/neovateai/neovate-code", "license": "MIT", "pricing": [ diff --git a/manifests/clis/opencode.json b/manifests/clis/opencode.json index 2b1300b5..855b39ad 100644 --- a/manifests/clis/opencode.json +++ b/manifests/clis/opencode.json @@ -43,7 +43,11 @@ "websiteUrl": "https://opencode.ai", "docsUrl": "https://opencode.ai", "vendor": "Anomaly", - "latestVersion": "0.15.16", + "latestVersion": "1.18.8", + "releaseTracking": { + "provider": "npm", + "identifier": "opencode-ai" + }, "githubUrl": "https://github.com/anomalyco/opencode", "license": "MIT", "pricing": [ diff --git a/manifests/clis/qoder-cli.json b/manifests/clis/qoder-cli.json index 3b939355..92e06572 100644 --- a/manifests/clis/qoder-cli.json +++ b/manifests/clis/qoder-cli.json @@ -43,7 +43,11 @@ "websiteUrl": "https://qoder.com/cli", "docsUrl": "https://docs.qoder.com/en/cli/quick-start", "vendor": "Alibaba", - "latestVersion": "Latest", + "latestVersion": "1.1.7", + "releaseTracking": { + "provider": "npm", + "identifier": "@qoder-ai/qodercli" + }, "githubUrl": null, "license": "Proprietary", "pricing": [ diff --git a/manifests/clis/qwen-code.json b/manifests/clis/qwen-code.json index 5f3eb410..c61ad4e4 100644 --- a/manifests/clis/qwen-code.json +++ b/manifests/clis/qwen-code.json @@ -56,7 +56,11 @@ "websiteUrl": "https://qwenlm.github.io/qwen-code-docs", "docsUrl": "https://qwenlm.github.io/qwen-code-docs", "vendor": "Alibaba", - "latestVersion": "0.18.0", + "latestVersion": "0.21.0", + "releaseTracking": { + "provider": "npm", + "identifier": "@qwen-code/qwen-code" + }, "githubUrl": "https://github.com/QwenLM/qwen-code", "license": "Apache-2.0", "pricing": [ diff --git a/manifests/desktops/opencode-desktop.json b/manifests/desktops/opencode-desktop.json index d8d8e028..c91fd8cc 100644 --- a/manifests/desktops/opencode-desktop.json +++ b/manifests/desktops/opencode-desktop.json @@ -56,7 +56,11 @@ "websiteUrl": "https://opencode.ai/download", "docsUrl": "https://opencode.ai/docs", "vendor": "Anomaly", - "latestVersion": "Latest", + "latestVersion": "1.18.8", + "releaseTracking": { + "provider": "homebrew-cask", + "identifier": "opencode-desktop" + }, "githubUrl": "https://github.com/anomalyco/opencode", "license": "MIT", "pricing": [ diff --git a/manifests/extensions/claude-code.json b/manifests/extensions/claude-code.json index bac53aa6..084d220f 100644 --- a/manifests/extensions/claude-code.json +++ b/manifests/extensions/claude-code.json @@ -103,7 +103,11 @@ "websiteUrl": "https://code.claude.com", "docsUrl": "https://code.claude.com/docs/en/ide-integrations", "vendor": "Anthropic", - "latestVersion": "Latest", + "latestVersion": "2.1.220", + "releaseTracking": { + "provider": "vscode-marketplace", + "identifier": "anthropic.claude-code" + }, "githubUrl": "https://github.com/anthropics/claude-code", "license": "Proprietary", "pricing": [ diff --git a/manifests/extensions/codex.json b/manifests/extensions/codex.json index 201534a6..f1bc8192 100644 --- a/manifests/extensions/codex.json +++ b/manifests/extensions/codex.json @@ -63,7 +63,11 @@ "websiteUrl": "https://openai.com/codex", "docsUrl": "https://developers.openai.com/codex/ide", "vendor": "OpenAI", - "latestVersion": "Latest", + "latestVersion": "26.5721.30844", + "releaseTracking": { + "provider": "vscode-marketplace", + "identifier": "openai.chatgpt" + }, "githubUrl": null, "license": "Proprietary", "pricing": [ diff --git a/manifests/extensions/droid.json b/manifests/extensions/droid.json index 2594f654..36890ad4 100644 --- a/manifests/extensions/droid.json +++ b/manifests/extensions/droid.json @@ -43,7 +43,11 @@ "websiteUrl": "https://factory.ai", "docsUrl": "https://docs.factory.ai", "vendor": "Factory.ai", - "latestVersion": "Latest", + "latestVersion": "0.2.3", + "releaseTracking": { + "provider": "vscode-marketplace", + "identifier": "Factory.factory-vscode-extension" + }, "githubUrl": null, "license": "Proprietary", "pricing": [ diff --git a/manifests/extensions/kimi-code.json b/manifests/extensions/kimi-code.json index b656add8..dc254f43 100644 --- a/manifests/extensions/kimi-code.json +++ b/manifests/extensions/kimi-code.json @@ -56,7 +56,11 @@ "websiteUrl": "https://www.kimi.com/code", "docsUrl": "https://www.kimi.com/code/docs/en", "vendor": "Moonshot AI", - "latestVersion": "Latest", + "latestVersion": "0.6.4", + "releaseTracking": { + "provider": "vscode-marketplace", + "identifier": "moonshot-ai.kimi-code" + }, "githubUrl": "https://github.com/MoonshotAI/kimi-code", "license": "Apache-2.0", "pricing": [ diff --git a/manifests/extensions/mistral-vibe.json b/manifests/extensions/mistral-vibe.json index 94a6555d..23f8ad8d 100644 --- a/manifests/extensions/mistral-vibe.json +++ b/manifests/extensions/mistral-vibe.json @@ -56,7 +56,11 @@ "websiteUrl": "https://mistral.ai/products/vibe", "docsUrl": "https://docs.mistral.ai/vibe/code/overview", "vendor": "Mistral AI", - "latestVersion": "Latest", + "latestVersion": "1.14.4", + "releaseTracking": { + "provider": "vscode-marketplace", + "identifier": "mistralai.mistral-vibe-code" + }, "githubUrl": null, "license": "Proprietary", "pricing": [ diff --git a/manifests/extensions/opencode-extension.json b/manifests/extensions/opencode-extension.json index eb0d6153..47ca4117 100644 --- a/manifests/extensions/opencode-extension.json +++ b/manifests/extensions/opencode-extension.json @@ -56,7 +56,11 @@ "websiteUrl": "https://opencode.ai/download", "docsUrl": "https://opencode.ai/docs/ide", "vendor": "Anomaly", - "latestVersion": "Latest", + "latestVersion": "0.0.13", + "releaseTracking": { + "provider": "vscode-marketplace", + "identifier": "sst-dev.opencode" + }, "githubUrl": "https://github.com/anomalyco/opencode", "license": "MIT", "pricing": [ diff --git a/manifests/extensions/rovo-dev.json b/manifests/extensions/rovo-dev.json index 1d1df147..bb4369f8 100644 --- a/manifests/extensions/rovo-dev.json +++ b/manifests/extensions/rovo-dev.json @@ -60,7 +60,11 @@ "websiteUrl": "https://marketplace.visualstudio.com/items?itemName=Atlassian.atlascode", "docsUrl": "https://support.atlassian.com/rovo/docs/work-with-rovo-dev-agents/", "vendor": "Atlassian", - "latestVersion": "Latest", + "latestVersion": "4.1.191", + "releaseTracking": { + "provider": "vscode-marketplace", + "identifier": "Atlassian.atlascode" + }, "githubUrl": null, "license": "Proprietary", "pricing": [ diff --git a/manifests/models/claude-haiku-4-5.json b/manifests/models/claude-haiku-4-5.json index 36a912c2..4b160ab4 100644 --- a/manifests/models/claude-haiku-4-5.json +++ b/manifests/models/claude-haiku-4-5.json @@ -57,7 +57,12 @@ { "url": "https://platform.claude.com/docs/en/about-claude/pricing", "title": "Claude API pricing", - "fields": ["tokenPricing"] + "fields": ["tokenPricing"], + "changeTracking": { + "method": "normalized-content-sha256", + "digest": "sha256:2ff7f541d89a824c7125b0cfab826e4b839e85f2ded2613c746415903266274b", + "observedAt": "2026-07-28" + } }, { "url": "https://www.anthropic.com/news/claude-haiku-4-5", diff --git a/manifests/models/claude-opus-4.json b/manifests/models/claude-opus-4.json index 3aa15822..8cf0c338 100644 --- a/manifests/models/claude-opus-4.json +++ b/manifests/models/claude-opus-4.json @@ -43,7 +43,12 @@ { "url": "https://platform.claude.com/docs/en/about-claude/model-deprecations", "title": "Anthropic model deprecations", - "fields": ["lifecycle"] + "fields": ["lifecycle"], + "changeTracking": { + "method": "normalized-content-sha256", + "digest": "sha256:af2e27075e6c7826cf4d7ef23f722bcbf0406d5bc0adaa0facf07e3b92b9c0b0", + "observedAt": "2026-07-28" + } } ], "lastVerifiedAt": "2026-07-21", @@ -95,6 +100,15 @@ "sciCode": 1.5, "liveCodeBench": 46.9 }, + "benchmarkTracking": [ + { + "provider": "swe-bench", + "benchmark": "sweBench", + "leaderboard": "Verified", + "resultId": "20250802_mini-v1.0.0_claude-4-opus-20250514", + "modelLabel": "mini-SWE-agent + Claude 4 Opus (20250514)" + } + ], "platformUrls": { "huggingface": null, "artificialAnalysis": "https://artificialanalysis.ai/models/claude-4-opus", diff --git a/manifests/models/claude-sonnet-4-5.json b/manifests/models/claude-sonnet-4-5.json index 2d665cbd..f827a761 100644 --- a/manifests/models/claude-sonnet-4-5.json +++ b/manifests/models/claude-sonnet-4-5.json @@ -95,6 +95,15 @@ "sciCode": null, "liveCodeBench": 46.9 }, + "benchmarkTracking": [ + { + "provider": "swe-bench", + "benchmark": "sweBench", + "leaderboard": "Verified", + "resultId": "20250929_mini-v1.13.3_sonnet-4-5-20250929", + "modelLabel": "mini-SWE-agent + Claude 4.5 Sonnet (20250929)" + } + ], "platformUrls": { "huggingface": null, "artificialAnalysis": "https://artificialanalysis.ai/models/claude-4-5-sonnet", diff --git a/manifests/models/claude-sonnet-4.json b/manifests/models/claude-sonnet-4.json index 05dcfb46..55198c4e 100644 --- a/manifests/models/claude-sonnet-4.json +++ b/manifests/models/claude-sonnet-4.json @@ -95,6 +95,15 @@ "sciCode": null, "liveCodeBench": 55.9 }, + "benchmarkTracking": [ + { + "provider": "swe-bench", + "benchmark": "sweBench", + "leaderboard": "Verified", + "resultId": "20250726_mini-v1.0.0_claude-sonnet-4-20250514", + "modelLabel": "mini-SWE-agent + Claude 4 Sonnet (20250514)" + } + ], "platformUrls": { "huggingface": null, "artificialAnalysis": "https://artificialanalysis.ai/models/claude-4-sonnet", diff --git a/manifests/models/deepseek-3-2.json b/manifests/models/deepseek-3-2.json index 83cb2ffd..8723a164 100644 --- a/manifests/models/deepseek-3-2.json +++ b/manifests/models/deepseek-3-2.json @@ -60,7 +60,12 @@ { "url": "https://api-docs.deepseek.com/quick_start/pricing", "title": "DeepSeek API pricing", - "fields": ["tokenPricing"] + "fields": ["tokenPricing"], + "changeTracking": { + "method": "normalized-content-sha256", + "digest": "sha256:d1c1fc8b58ad75475827f978beac79318391da95b942891f47a8aafe811712ba", + "observedAt": "2026-07-28" + } } ], "lastVerifiedAt": "2026-07-21", diff --git a/manifests/models/gemini-2-5-flash.json b/manifests/models/gemini-2-5-flash.json index 7758bc92..33ce1fbf 100644 --- a/manifests/models/gemini-2-5-flash.json +++ b/manifests/models/gemini-2-5-flash.json @@ -111,6 +111,15 @@ "sciCode": null, "liveCodeBench": 60.6 }, + "benchmarkTracking": [ + { + "provider": "swe-bench", + "benchmark": "sweBench", + "leaderboard": "Verified", + "resultId": "20250726_mini-v1.0.0_gemini-2.5-flash", + "modelLabel": "mini-SWE-agent + Gemini 2.5 Flash (2025-04-17)" + } + ], "platformUrls": { "huggingface": null, "artificialAnalysis": "https://artificialanalysis.ai/models/gemini-2-5-flash", diff --git a/manifests/models/gemini-2-5-pro.json b/manifests/models/gemini-2-5-pro.json index 2d1e3b84..486fdd98 100644 --- a/manifests/models/gemini-2-5-pro.json +++ b/manifests/models/gemini-2-5-pro.json @@ -111,6 +111,15 @@ "sciCode": 1.5, "liveCodeBench": 71.8 }, + "benchmarkTracking": [ + { + "provider": "swe-bench", + "benchmark": "sweBench", + "leaderboard": "Verified", + "resultId": "20250726_mini-v1.0.0_gemini-2.5-pro", + "modelLabel": "mini-SWE-agent + Gemini 2.5 Pro (2025-05-06)" + } + ], "platformUrls": { "huggingface": null, "artificialAnalysis": "https://artificialanalysis.ai/models/gemini-2-5-pro", diff --git a/manifests/models/gemini-3-5-flash.json b/manifests/models/gemini-3-5-flash.json index 10d8dad5..9ad61384 100644 --- a/manifests/models/gemini-3-5-flash.json +++ b/manifests/models/gemini-3-5-flash.json @@ -56,12 +56,22 @@ { "url": "https://ai.google.dev/gemini-api/docs/pricing", "title": "Gemini Developer API pricing", - "fields": ["tokenPricing"] + "fields": ["tokenPricing"], + "changeTracking": { + "method": "normalized-content-sha256", + "digest": "sha256:aab4d993819344eb390d8e59a37ab5d9712daca3ed395b4271bbebb586bb0c50", + "observedAt": "2026-07-28" + } }, { "url": "https://ai.google.dev/gemini-api/docs/changelog", "title": "Gemini API release notes", - "fields": ["name", "description", "releaseDate", "lifecycle"] + "fields": ["name", "description", "releaseDate", "lifecycle"], + "changeTracking": { + "method": "normalized-content-sha256", + "digest": "sha256:d903a1d48cc08625d5514f5f0d800daed7c207f46cfa33dcef4dcbb98ab16065", + "observedAt": "2026-07-28" + } } ], "lastVerifiedAt": "2026-07-22", diff --git a/manifests/models/glm-4-6.json b/manifests/models/glm-4-6.json index 9cc531e0..fe6461d5 100644 --- a/manifests/models/glm-4-6.json +++ b/manifests/models/glm-4-6.json @@ -85,6 +85,15 @@ "sciCode": null, "liveCodeBench": null }, + "benchmarkTracking": [ + { + "provider": "swe-bench", + "benchmark": "sweBench", + "leaderboard": "Verified", + "resultId": "20251201_mini-v1.17.1_glm-4.6", + "modelLabel": "mini-SWE-agent + GLM-4.6 (T=1)" + } + ], "platformUrls": { "huggingface": "https://huggingface.co/zai-org/GLM-4.6", "artificialAnalysis": "https://artificialanalysis.ai/models/glm-4-6", diff --git a/manifests/models/glm-5-2.json b/manifests/models/glm-5-2.json index ddc50861..86341d6f 100644 --- a/manifests/models/glm-5-2.json +++ b/manifests/models/glm-5-2.json @@ -57,12 +57,22 @@ { "url": "https://docs.z.ai/release-notes/new-released", "title": "Z.ai model release notes", - "fields": ["releaseDate", "lifecycle"] + "fields": ["releaseDate", "lifecycle"], + "changeTracking": { + "method": "normalized-content-sha256", + "digest": "sha256:5b5ab3620167e1331f3de0aeeefe0cb5df12d59e706e0228bac5dcab6248a6fe", + "observedAt": "2026-07-28" + } }, { "url": "https://docs.z.ai/guides/overview/pricing", "title": "Z.ai API pricing", - "fields": ["tokenPricing"] + "fields": ["tokenPricing"], + "changeTracking": { + "method": "normalized-content-sha256", + "digest": "sha256:3f331fe3d6f5ed696378e4c29c6ce553f463417299d5aa2d222ad8b48fe3ec7a", + "observedAt": "2026-07-28" + } }, { "url": "https://huggingface.co/zai-org/GLM-5.2", diff --git a/manifests/models/gpt-4-1.json b/manifests/models/gpt-4-1.json index 6598e070..703f6606 100644 --- a/manifests/models/gpt-4-1.json +++ b/manifests/models/gpt-4-1.json @@ -85,6 +85,15 @@ "sciCode": null, "liveCodeBench": null }, + "benchmarkTracking": [ + { + "provider": "swe-bench", + "benchmark": "sweBench", + "leaderboard": "Verified", + "resultId": "20250726_mini-v1.0.0_gpt-4.1-2025-04-14", + "modelLabel": "mini-SWE-agent + GPT-4.1 (2025-04-14)" + } + ], "platformUrls": { "huggingface": null, "artificialAnalysis": "https://artificialanalysis.ai/models/gpt-4-1", diff --git a/manifests/models/gpt-4o.json b/manifests/models/gpt-4o.json index c6f55a61..0c3f58f3 100644 --- a/manifests/models/gpt-4o.json +++ b/manifests/models/gpt-4o.json @@ -85,6 +85,15 @@ "sciCode": 1.5, "liveCodeBench": 29.5 }, + "benchmarkTracking": [ + { + "provider": "swe-bench", + "benchmark": "sweBench", + "leaderboard": "Verified", + "resultId": "20250720_mini-v0.0.0-gpt-4o-2024-11-20", + "modelLabel": "mini-SWE-agent + GPT-4o (2024-11-20)" + } + ], "platformUrls": { "huggingface": null, "artificialAnalysis": "https://artificialanalysis.ai/models/gpt-4o", diff --git a/manifests/models/gpt-5-1.json b/manifests/models/gpt-5-1.json index da92f19a..362baffa 100644 --- a/manifests/models/gpt-5-1.json +++ b/manifests/models/gpt-5-1.json @@ -85,6 +85,15 @@ "sciCode": null, "liveCodeBench": null }, + "benchmarkTracking": [ + { + "provider": "swe-bench", + "benchmark": "sweBench", + "leaderboard": "Verified", + "resultId": "20251120_mini-v1.15.0_gpt-5.1-2025-11-13", + "modelLabel": "mini-SWE-agent + GPT-5.1 (2025-11-13) (medium reasoning)" + } + ], "platformUrls": { "huggingface": null, "artificialAnalysis": "https://artificialanalysis.ai/models/gpt-5-1", diff --git a/manifests/models/gpt-5-6-sol.json b/manifests/models/gpt-5-6-sol.json index 6fdb183e..fe7fd379 100644 --- a/manifests/models/gpt-5-6-sol.json +++ b/manifests/models/gpt-5-6-sol.json @@ -52,7 +52,12 @@ "inputModalities", "outputModalities", "capabilities" - ] + ], + "changeTracking": { + "method": "normalized-content-sha256", + "digest": "sha256:a8689d63a32710a7b7c1ecb3b7898d57820ce6de6a68f5bec671e606685af349", + "observedAt": "2026-07-28" + } }, { "url": "https://openai.com/index/gpt-5-6", diff --git a/manifests/models/gpt-5.json b/manifests/models/gpt-5.json index daa47e20..b33b2732 100644 --- a/manifests/models/gpt-5.json +++ b/manifests/models/gpt-5.json @@ -85,6 +85,15 @@ "sciCode": 1.5, "liveCodeBench": 28.7 }, + "benchmarkTracking": [ + { + "provider": "swe-bench", + "benchmark": "sweBench", + "leaderboard": "Verified", + "resultId": "20250807_openhands_gpt5", + "modelLabel": "OpenHands + GPT-5" + } + ], "platformUrls": { "huggingface": null, "artificialAnalysis": "https://artificialanalysis.ai/models/gpt-5", diff --git a/manifests/models/grok-4-20.json b/manifests/models/grok-4-20.json index 83051760..4d5a054a 100644 --- a/manifests/models/grok-4-20.json +++ b/manifests/models/grok-4-20.json @@ -57,7 +57,12 @@ "inputModalities", "outputModalities", "capabilities" - ] + ], + "changeTracking": { + "method": "normalized-content-sha256", + "digest": "sha256:ce3ca747e8bec4e13b038be6f1c3ccfafc8a0ec7d70c12ccada9bb27c4fa9ed6", + "observedAt": "2026-07-28" + } } ], "lastVerifiedAt": "2026-07-21", diff --git a/manifests/models/hy3.json b/manifests/models/hy3.json index 7c4420a0..dc9414f5 100644 --- a/manifests/models/hy3.json +++ b/manifests/models/hy3.json @@ -63,10 +63,10 @@ { "url": "https://artificialanalysis.ai/models/hy3", "title": "Artificial Analysis Hy3 model page", - "fields": ["releaseDate", "platformUrls.artificialAnalysis"] + "fields": ["releaseDate", "referenceTokenPricing", "platformUrls.artificialAnalysis"] } ], - "lastVerifiedAt": "2026-07-27", + "lastVerifiedAt": "2026-07-28", "verifiedBy": "codex-agent", "confidence": "high", "websiteUrl": "https://www.tencent.com", @@ -81,6 +81,21 @@ "primaryOffer": null, "offers": [] }, + "referenceTokenPricing": { + "currency": "USD", + "basis": "provider-median", + "rates": { + "input": 0.14, + "output": 0.58, + "cacheRead": 0.035, + "cacheWrite": null + }, + "source": { + "name": "Artificial Analysis", + "url": "https://artificialanalysis.ai/models/hy3", + "observedAt": "2026-07-28" + } + }, "releaseDate": "2026-07-06", "lifecycle": "latest", "knowledgeCutoff": null, diff --git a/manifests/models/kimi-k2-thinking.json b/manifests/models/kimi-k2-thinking.json index d3d40b49..a571c595 100644 --- a/manifests/models/kimi-k2-thinking.json +++ b/manifests/models/kimi-k2-thinking.json @@ -43,7 +43,12 @@ { "url": "https://platform.kimi.ai/docs/models", "title": "Kimi API model availability and K2 retirement notice", - "fields": ["lifecycle", "tokenPricing"] + "fields": ["lifecycle", "tokenPricing"], + "changeTracking": { + "method": "normalized-content-sha256", + "digest": "sha256:50692812b00a1b51ddd80947258f053d2317be53e34384d7421d2e9034d3b60d", + "observedAt": "2026-07-28" + } } ], "lastVerifiedAt": "2026-07-21", diff --git a/manifests/models/minimax-m2-7.json b/manifests/models/minimax-m2-7.json index e8ad7875..d9d9a5dd 100644 --- a/manifests/models/minimax-m2-7.json +++ b/manifests/models/minimax-m2-7.json @@ -53,7 +53,12 @@ { "url": "https://platform.minimax.io/docs/guides/pricing-paygo", "title": "MiniMax pay-as-you-go pricing", - "fields": ["tokenPricing"] + "fields": ["tokenPricing"], + "changeTracking": { + "method": "normalized-content-sha256", + "digest": "sha256:40b4c27c5a485ab71d531141a4f328d3bff0f1c2eb6c9d31103523119aadaae3", + "observedAt": "2026-07-28" + } }, { "url": "https://huggingface.co/MiniMaxAI/MiniMax-M2.7", diff --git a/manifests/models/minimax-m2.json b/manifests/models/minimax-m2.json index c3724ea2..d7b098e1 100644 --- a/manifests/models/minimax-m2.json +++ b/manifests/models/minimax-m2.json @@ -85,6 +85,15 @@ "sciCode": null, "liveCodeBench": null }, + "benchmarkTracking": [ + { + "provider": "swe-bench", + "benchmark": "sweBench", + "leaderboard": "Verified", + "resultId": "20251124_mini-v1.17.0_minimax-m2", + "modelLabel": "mini-SWE-agent + Minimax M2" + } + ], "platformUrls": { "huggingface": "https://huggingface.co/MiniMaxAI/MiniMax-M2", "artificialAnalysis": "https://artificialanalysis.ai/models/minimax-m2", diff --git a/manifests/models/mistral-small-4.json b/manifests/models/mistral-small-4.json index d86fcc4e..ca40d89b 100644 --- a/manifests/models/mistral-small-4.json +++ b/manifests/models/mistral-small-4.json @@ -63,7 +63,12 @@ { "url": "https://mistral.ai/pricing/api/", "title": "Mistral API pricing", - "fields": ["tokenPricing"] + "fields": ["tokenPricing"], + "changeTracking": { + "method": "normalized-content-sha256", + "digest": "sha256:740ecd45540ba01718b7682233cefd2f5b1f4dae7d40a16887e750dc9a0b84f0", + "observedAt": "2026-07-28" + } } ], "lastVerifiedAt": "2026-07-21", diff --git a/manifests/models/qwen3-7-max.json b/manifests/models/qwen3-7-max.json index 6c3f49e6..aacce795 100644 --- a/manifests/models/qwen3-7-max.json +++ b/manifests/models/qwen3-7-max.json @@ -51,15 +51,30 @@ "contextWindow", "capabilities", "inputModalities" - ] + ], + "changeTracking": { + "method": "normalized-content-sha256", + "digest": "sha256:1d3b2eb8b5a808acf23c0f5183039c4fd5056eca009e35c4a896a3661a82c108", + "observedAt": "2026-07-28" + } }, { "url": "https://help.aliyun.com/en/model-studio/model-pricing", "title": "Alibaba Cloud Model Studio model pricing", - "fields": ["docsUrl", "contextWindow", "tokenPricing"] + "fields": ["docsUrl", "contextWindow", "tokenPricing"], + "changeTracking": { + "method": "normalized-content-sha256", + "digest": "sha256:ea84e2dc7741e6a43646a6c2576e6c78384434821fac0d1774a79993cbc85023", + "observedAt": "2026-07-28" + } + }, + { + "url": "https://artificialanalysis.ai/models/qwen3-7-max", + "title": "Artificial Analysis Qwen3.7 Max model page", + "fields": ["referenceTokenPricing", "platformUrls.artificialAnalysis"] } ], - "lastVerifiedAt": "2026-07-21", + "lastVerifiedAt": "2026-07-28", "verifiedBy": "codex-agent", "confidence": "high", "websiteUrl": "https://qwen.ai", @@ -93,6 +108,21 @@ } ] }, + "referenceTokenPricing": { + "currency": "USD", + "basis": "first-party-api", + "rates": { + "input": 2.5, + "output": 7.5, + "cacheRead": 0.25, + "cacheWrite": 3.125 + }, + "source": { + "name": "Artificial Analysis", + "url": "https://artificialanalysis.ai/models/qwen3-7-max", + "observedAt": "2026-07-28" + } + }, "releaseDate": "2026-05-21", "lifecycle": "latest", "knowledgeCutoff": null, @@ -108,5 +138,9 @@ "sciCode": null, "liveCodeBench": null }, - "platformUrls": { "huggingface": null, "artificialAnalysis": null, "openrouter": null } + "platformUrls": { + "huggingface": null, + "artificialAnalysis": "https://artificialanalysis.ai/models/qwen3-7-max", + "openrouter": null + } } diff --git a/manifests/models/qwen3-7-plus.json b/manifests/models/qwen3-7-plus.json index 87059f62..dadd89a4 100644 --- a/manifests/models/qwen3-7-plus.json +++ b/manifests/models/qwen3-7-plus.json @@ -54,9 +54,14 @@ "url": "https://help.aliyun.com/en/model-studio/coding-plan", "title": "Model Studio Coding Plan", "fields": ["lifecycle"] + }, + { + "url": "https://artificialanalysis.ai/models/qwen3-7-plus", + "title": "Artificial Analysis Qwen3.7 Plus model page", + "fields": ["referenceTokenPricing", "platformUrls.artificialAnalysis"] } ], - "lastVerifiedAt": "2026-07-21", + "lastVerifiedAt": "2026-07-28", "verifiedBy": "codex-agent", "confidence": "high", "websiteUrl": "https://www.alibabacloud.com/product/modelstudio", @@ -99,6 +104,21 @@ } ] }, + "referenceTokenPricing": { + "currency": "USD", + "basis": "first-party-api", + "rates": { + "input": 0.4, + "output": 1.6, + "cacheRead": 0.04, + "cacheWrite": 0.5 + }, + "source": { + "name": "Artificial Analysis", + "url": "https://artificialanalysis.ai/models/qwen3-7-plus", + "observedAt": "2026-07-28" + } + }, "releaseDate": "2026-05-26", "lifecycle": "latest", "knowledgeCutoff": null, @@ -114,5 +134,9 @@ "sciCode": null, "liveCodeBench": null }, - "platformUrls": { "huggingface": null, "artificialAnalysis": null, "openrouter": null } + "platformUrls": { + "huggingface": null, + "artificialAnalysis": "https://artificialanalysis.ai/models/qwen3-7-plus", + "openrouter": null + } } diff --git a/package.json b/package.json index fc66800d..1d86b29d 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,12 @@ "refactor:sort-fields": "npx tsx scripts/refactor/index.ts sort-manifest-fields", "fetch": "npx tsx scripts/fetch/index.ts", "fetch:github-stars": "npx tsx scripts/fetch/index.ts github-stars", - "fetch:benchmarks": "npx tsx scripts/fetch/index.ts benchmarks", + "fetch:product-versions": "npx tsx scripts/fetch/fetch-product-versions.ts --write", + "fetch:product-versions:check": "npx tsx scripts/fetch/fetch-product-versions.ts --check", + "fetch:benchmarks": "npx tsx scripts/fetch/fetch-benchmarks.ts --write", + "fetch:benchmarks:check": "npx tsx scripts/fetch/fetch-benchmarks.ts --check", + "fetch:model-sources": "npx tsx scripts/fetch/fetch-model-sources.ts --write", + "fetch:model-sources:check": "npx tsx scripts/fetch/fetch-model-sources.ts --check", "deploy": "npm run build:next && opennextjs-cloudflare build --skipBuild && opennextjs-cloudflare deploy", "preview": "npm run build:next && opennextjs-cloudflare build --skipBuild && opennextjs-cloudflare preview", "cf-typegen": "wrangler types --env-interface CloudflareEnv ./cloudflare-env.d.ts", diff --git a/scripts/README.md b/scripts/README.md index 09de6053..0e2c3d1c 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -11,13 +11,17 @@ Repository automation is written in TypeScript and executed with `tsx`. Prefer t | Generate content metadata | `npm run generate:metadata` | Rebuilds article, docs, FAQ, and manifesto metadata | | Sort manifest fields | `npm run refactor:sort-fields` | Reorders manifest JSON using schema order | | Fetch GitHub stars | `npm run fetch:github-stars` | Updates `data/github-stars.json` | +| Refresh product versions | `npm run fetch:product-versions` | Updates manifest `latestVersion` values from configured package registries | +| Check product versions | `npm run fetch:product-versions:check` | Fails when a configured registry reports a newer stable version | +| Refresh benchmark scores | `npm run fetch:benchmarks` | Updates exact configured entries from official structured leaderboards | +| Check benchmark scores | `npm run fetch:benchmarks:check` | Fails when an exact configured leaderboard score changed | +| Record model source changes | `npm run fetch:model-sources` | Updates only monitored official-source content digests | +| Check model sources | `npm run fetch:model-sources:check` | Fails when monitored pricing or lifecycle source content changed | | Validate manifests and data | `npm run test:validate` | Runs the validation test suite | | Run browser smoke tests | `npm run test:e2e` | Exercises core journeys in Chromium against a local Next.js server | | Audit dependencies | `npm run security:audit` | Fails on high or critical npm advisories in the full dependency tree | | Check data health | `npm run data-health:check` | Fails on invalid health-report data | | Refresh data-health snapshot | `npm run data-health:report` | Writes `data/data-health.json` and `docs/DATA-HEALTH.md` | -| Check manifest changelog | `npm run changelog:check` | Requires manifest diffs to be represented in `data/changelogs.json` | -| Generate manifest changelog | `npm run changelog:generate -- --base= --id= --summary=""` | Adds or replaces one entry from a Git diff | | Validate i18n structure | `npm run validate:i18n` | Checks locale alignment and translation shape | | Validate i18n usage | `npm run validate:i18n-usage` | Checks translation keys referenced by source | | Validate duplicate i18n values | `npm run validate:i18n-duplicates` | Reports duplicated translation content | @@ -44,6 +48,9 @@ Each category with an `index.ts` auto-discovers sibling `.ts` scripts. A filenam npx tsx scripts/generate/index.ts manifest-indexes npx tsx scripts/refactor/index.ts export-vendors npx tsx scripts/fetch/index.ts github-stars +npx tsx scripts/fetch/fetch-product-versions.ts --check +npx tsx scripts/fetch/fetch-benchmarks.ts --check +npx tsx scripts/fetch/fetch-model-sources.ts --check ``` ## Generated files @@ -52,6 +59,12 @@ Generated modules under `src/lib/generated/` are committed. After changing manif `data/github-stars.json` is source data, not generated build output. Update it with `npm run fetch:github-stars`; the dedicated scheduled workflow also opens a pull request when values change. +Product-version synchronization is declarative and runs separately from the generic `npm run fetch` batch. Add `releaseTracking` to a product manifest with an official npm, PyPI, Homebrew, crates.io, GitHub Releases, or Visual Studio Marketplace identifier. The generic version fetcher reads that manifest configuration; product identifiers must not be hardcoded in TypeScript. Failed lookups leave every manifest unchanged, and the scheduled workflow opens a pull request rather than pushing directly to `main`. + +Benchmark synchronization also keeps model-to-result mappings in JSON manifests. An exact upstream result ID and exact displayed label are both required; a renamed or missing result fails closed instead of fuzzy matching another model or evaluation setup. + +Pricing and lifecycle monitoring fingerprints only explicitly configured official source pages. A source-content change updates the source digest in a review pull request; it never modifies `tokenPricing`, `lifecycle`, or other model facts automatically. + ## Adding a script 1. Add a TypeScript file to the relevant category. diff --git a/scripts/fetch/fetch-benchmarks.ts b/scripts/fetch/fetch-benchmarks.ts new file mode 100644 index 00000000..312ed361 --- /dev/null +++ b/scripts/fetch/fetch-benchmarks.ts @@ -0,0 +1,43 @@ +#!/usr/bin/env node + +import { syncBenchmarks } from './lib/benchmark-sync' + +function hasFlag(flag: string): boolean { + return process.argv.slice(2).includes(flag) +} + +async function main(): Promise { + const write = hasFlag('--write') + const check = hasFlag('--check') + if (write && check) { + throw new Error('Use either --write or --check, not both.') + } + + const result = await syncBenchmarks({ + rootDir: process.cwd(), + write, + }) + + console.log(`Checked ${result.checked} exact benchmark mappings.`) + if (result.changes.length === 0) { + console.log('All tracked benchmark scores are current.') + return + } + + for (const change of result.changes) { + console.log( + `${write ? 'Updated' : 'Would update'} models/${change.modelId} ${change.benchmark}: ${change.previousScore} -> ${change.nextScore}` + ) + console.log(` ${change.modelLabel}`) + console.log(` Source: ${change.sourceUrl}`) + } + + if (check) { + process.exitCode = 1 + } +} + +main().catch(error => { + console.error(error instanceof Error ? error.message : error) + process.exit(1) +}) diff --git a/scripts/fetch/fetch-model-sources.ts b/scripts/fetch/fetch-model-sources.ts new file mode 100644 index 00000000..a5cc5c27 --- /dev/null +++ b/scripts/fetch/fetch-model-sources.ts @@ -0,0 +1,52 @@ +#!/usr/bin/env node + +import { syncModelSourceDigests } from './lib/model-source-sync' + +function hasFlag(flag: string): boolean { + return process.argv.slice(2).includes(flag) +} + +function currentShanghaiDate(): string { + return new Intl.DateTimeFormat('en-CA', { + timeZone: 'Asia/Shanghai', + year: 'numeric', + month: '2-digit', + day: '2-digit', + }).format(new Date()) +} + +async function main(): Promise { + const write = hasFlag('--write') + const check = hasFlag('--check') + if (write && check) { + throw new Error('Use either --write or --check, not both.') + } + + const result = await syncModelSourceDigests({ + rootDir: process.cwd(), + write, + observedAt: currentShanghaiDate(), + }) + + console.log(`Checked ${result.checked} monitored model sources.`) + if (result.changes.length === 0) { + console.log('All monitored pricing and lifecycle sources are unchanged.') + return + } + + for (const change of result.changes) { + console.log( + `${write ? 'Recorded' : 'Detected'} source change for models/${change.modelId}: ${change.fields.join(', ')}` + ) + console.log(` ${change.url}`) + } + + if (check) { + process.exitCode = 1 + } +} + +main().catch(error => { + console.error(error instanceof Error ? error.message : error) + process.exit(1) +}) diff --git a/scripts/fetch/fetch-product-versions.ts b/scripts/fetch/fetch-product-versions.ts new file mode 100644 index 00000000..401743a3 --- /dev/null +++ b/scripts/fetch/fetch-product-versions.ts @@ -0,0 +1,42 @@ +#!/usr/bin/env node + +import { syncProductVersions } from './lib/product-version-sync' + +function hasFlag(flag: string): boolean { + return process.argv.slice(2).includes(flag) +} + +async function main(): Promise { + const write = hasFlag('--write') + const check = hasFlag('--check') + if (write && check) { + throw new Error('Use either --write or --check, not both.') + } + + const result = await syncProductVersions({ + rootDir: process.cwd(), + write, + }) + + console.log(`Checked ${result.checked} tracked products.`) + if (result.changes.length === 0) { + console.log('All tracked product versions are current.') + return + } + + for (const change of result.changes) { + console.log( + `${write ? 'Updated' : 'Would update'} ${change.category}/${change.id}: ${change.previousVersion} -> ${change.nextVersion}` + ) + console.log(` Source: ${change.sourceUrl}`) + } + + if (check) { + process.exitCode = 1 + } +} + +main().catch(error => { + console.error(error instanceof Error ? error.message : error) + process.exit(1) +}) diff --git a/scripts/fetch/index.ts b/scripts/fetch/index.ts index d3269053..5a310879 100644 --- a/scripts/fetch/index.ts +++ b/scripts/fetch/index.ts @@ -16,6 +16,7 @@ import { runCategoryScripts } from '../_shared/runner' runCategoryScripts({ categoryName: 'fetch', + excludes: ['benchmarks', 'model-sources', 'product-versions'], }).catch(error => { console.error('Fatal error:', error) process.exit(1) diff --git a/scripts/fetch/lib/benchmark-sync.ts b/scripts/fetch/lib/benchmark-sync.ts new file mode 100644 index 00000000..36596b46 --- /dev/null +++ b/scripts/fetch/lib/benchmark-sync.ts @@ -0,0 +1,199 @@ +import fs from 'node:fs/promises' +import path from 'node:path' + +import type { ManifestBenchmarkTracking } from '../../../src/types/manifests' + +const SWE_BENCH_SOURCE_URL = + 'https://raw.githubusercontent.com/SWE-bench/swe-bench.github.io/master/data/leaderboards.json' + +interface ModelManifest { + id: string + benchmarks: Record + benchmarkTracking?: ManifestBenchmarkTracking[] +} + +interface JsonResponse { + ok: boolean + status: number + statusText: string + json(): Promise +} + +export type BenchmarkFetch = (input: string | URL) => Promise + +interface SweBenchResult { + folder: string + name: string + resolved: number +} + +interface SweBenchLeaderboard { + name: string + results: SweBenchResult[] +} + +export interface BenchmarkChange { + modelId: string + filePath: string + benchmark: ManifestBenchmarkTracking['benchmark'] + previousScore: number | null + nextScore: number + modelLabel: string + sourceUrl: string +} + +export interface BenchmarkSyncResult { + checked: number + changes: BenchmarkChange[] +} + +function isRecord(value: unknown): value is Record { + return Boolean(value) && typeof value === 'object' && !Array.isArray(value) +} + +function escapeRegularExpression(value: string): string { + return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') +} + +function parseSweBenchLeaderboards(value: unknown): SweBenchLeaderboard[] { + if (!isRecord(value) || !Array.isArray(value.leaderboards)) { + throw new Error('SWE-bench returned no leaderboards array') + } + + return value.leaderboards.map((leaderboard, leaderboardIndex) => { + if (!isRecord(leaderboard) || typeof leaderboard.name !== 'string') { + throw new Error(`SWE-bench leaderboard ${leaderboardIndex} has no usable name`) + } + if (!Array.isArray(leaderboard.results)) { + throw new Error(`SWE-bench leaderboard ${leaderboard.name} has no results array`) + } + + return { + name: leaderboard.name, + results: leaderboard.results.map((result, resultIndex) => { + if ( + !isRecord(result) || + typeof result.folder !== 'string' || + typeof result.name !== 'string' || + typeof result.resolved !== 'number' + ) { + throw new Error( + `SWE-bench ${leaderboard.name} result ${resultIndex} is missing folder, name, or resolved` + ) + } + return { + folder: result.folder, + name: result.name, + resolved: result.resolved, + } + }), + } + }) +} + +async function fetchSweBenchLeaderboards( + fetchImpl: BenchmarkFetch +): Promise { + const response = await fetchImpl(SWE_BENCH_SOURCE_URL) + if (!response.ok) { + throw new Error(`${SWE_BENCH_SOURCE_URL} returned ${response.status} ${response.statusText}`) + } + return parseSweBenchLeaderboards(await response.json()) +} + +async function loadTrackedModels(rootDir: string): Promise< + Array<{ + filePath: string + manifest: ModelManifest + }> +> { + const directory = path.join(rootDir, 'manifests', 'models') + const models = [] + for (const fileName of (await fs.readdir(directory)) + .filter(file => file.endsWith('.json')) + .sort()) { + const filePath = path.join(directory, fileName) + const manifest = JSON.parse(await fs.readFile(filePath, 'utf8')) as ModelManifest + if (manifest.benchmarkTracking?.length) { + models.push({ filePath, manifest }) + } + } + return models +} + +export async function syncBenchmarks(options: { + rootDir: string + write: boolean + fetchImpl?: BenchmarkFetch +}): Promise { + const trackedModels = await loadTrackedModels(options.rootDir) + const trackingEntries = trackedModels.flatMap(entry => + (entry.manifest.benchmarkTracking ?? []).map(tracking => ({ entry, tracking })) + ) + const fetchImpl = options.fetchImpl ?? (fetch as BenchmarkFetch) + const leaderboards = trackingEntries.length ? await fetchSweBenchLeaderboards(fetchImpl) : [] + + const changes: BenchmarkChange[] = [] + for (const { entry, tracking } of trackingEntries) { + const leaderboard = leaderboards.find(item => item.name === tracking.leaderboard) + if (!leaderboard) { + throw new Error( + `models/${entry.manifest.id}: SWE-bench leaderboard ${tracking.leaderboard} was not found` + ) + } + const matches = leaderboard.results.filter(result => result.folder === tracking.resultId) + if (matches.length !== 1) { + throw new Error( + `models/${entry.manifest.id}: expected exactly one SWE-bench result ${tracking.resultId}, found ${matches.length}` + ) + } + const result = matches[0] + if (!result) { + throw new Error(`models/${entry.manifest.id}: SWE-bench result disappeared after validation`) + } + if (result.name !== tracking.modelLabel) { + throw new Error( + `models/${entry.manifest.id}: SWE-bench label changed from "${tracking.modelLabel}" to "${result.name}"` + ) + } + + const previousScore = entry.manifest.benchmarks[tracking.benchmark] + if (typeof previousScore !== 'number' && previousScore !== null) { + throw new Error(`models/${entry.manifest.id}: ${tracking.benchmark} must be a number or null`) + } + if (previousScore === result.resolved) continue + changes.push({ + modelId: entry.manifest.id, + filePath: entry.filePath, + benchmark: tracking.benchmark, + previousScore, + nextScore: result.resolved, + modelLabel: result.name, + sourceUrl: SWE_BENCH_SOURCE_URL, + }) + } + + if (options.write) { + const changesByFile = Map.groupBy(changes, change => change.filePath) + for (const [filePath, fileChanges] of changesByFile) { + let source = await fs.readFile(filePath, 'utf8') + for (const change of fileChanges) { + const previousValue = escapeRegularExpression(JSON.stringify(change.previousScore)) + const pattern = new RegExp( + `("${escapeRegularExpression(change.benchmark)}"\\s*:\\s*)${previousValue}`, + 'g' + ) + const matches = [...source.matchAll(pattern)] + if (matches.length !== 1) { + throw new Error( + `models/${change.modelId} must contain exactly one matching ${change.benchmark} field` + ) + } + source = source.replace(pattern, `$1${JSON.stringify(change.nextScore)}`) + } + await fs.writeFile(filePath, source, 'utf8') + } + } + + return { checked: trackingEntries.length, changes } +} diff --git a/scripts/fetch/lib/model-source-sync.ts b/scripts/fetch/lib/model-source-sync.ts new file mode 100644 index 00000000..cd65625f --- /dev/null +++ b/scripts/fetch/lib/model-source-sync.ts @@ -0,0 +1,198 @@ +import { createHash } from 'node:crypto' +import fs from 'node:fs/promises' +import path from 'node:path' + +import type { ManifestSource } from '../../../src/types/manifests' + +interface ModelManifest { + id: string + sources?: ManifestSource[] +} + +interface TextResponse { + ok: boolean + status: number + statusText: string + text(): Promise +} + +export type SourceFetch = ( + input: string | URL, + init?: { headers?: Record } +) => Promise + +interface TrackedSource { + modelId: string + filePath: string + source: ManifestSource & { + changeTracking: NonNullable + } +} + +export interface ModelSourceChange { + modelId: string + filePath: string + url: string + fields: string[] + previousDigest: string | null + nextDigest: string + observedAt: string +} + +export interface ModelSourceSyncResult { + checked: number + changes: ModelSourceChange[] +} + +function escapeRegularExpression(value: string): string { + return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') +} + +function decodeCommonEntities(value: string): string { + return value + .replaceAll(' ', ' ') + .replaceAll('&', '&') + .replaceAll('<', '<') + .replaceAll('>', '>') + .replaceAll('"', '"') + .replaceAll(''', "'") +} + +export function normalizeSourceContent(value: string): string { + return decodeCommonEntities( + value + .replace(//g, ' ') + .replace(/<(script|style|noscript|svg)\b[\s\S]*?<\/\1>/gi, ' ') + .replace(/<[^>]+>/g, ' ') + ) + .replace(/\s+/g, ' ') + .trim() +} + +export function digestSourceContent(value: string): string { + return `sha256:${createHash('sha256').update(normalizeSourceContent(value)).digest('hex')}` +} + +async function loadTrackedSources(rootDir: string): Promise { + const directory = path.join(rootDir, 'manifests', 'models') + const tracked: TrackedSource[] = [] + for (const fileName of (await fs.readdir(directory)) + .filter(file => file.endsWith('.json')) + .sort()) { + const filePath = path.join(directory, fileName) + const manifest = JSON.parse(await fs.readFile(filePath, 'utf8')) as ModelManifest + for (const source of manifest.sources ?? []) { + if (source.changeTracking) { + tracked.push({ + modelId: manifest.id, + filePath, + source: { + ...source, + changeTracking: source.changeTracking, + }, + }) + } + } + } + return tracked +} + +async function fetchDigest(url: string, fetchImpl: SourceFetch): Promise { + const response = await fetchImpl(url, { + headers: { + Accept: 'text/html,application/xhtml+xml,text/plain;q=0.9,*/*;q=0.1', + 'Accept-Language': 'en-US,en;q=0.9', + 'User-Agent': 'aicodingstack-model-source-monitor', + }, + }) + if (!response.ok) { + throw new Error(`${url} returned ${response.status} ${response.statusText}`) + } + const content = await response.text() + const normalized = normalizeSourceContent(content) + if (normalized.length < 100) { + throw new Error(`${url} returned too little usable content`) + } + return digestSourceContent(content) +} + +function replaceTrackedSource(source: string, change: ModelSourceChange): string { + const url = escapeRegularExpression(JSON.stringify(change.url)) + const previousDigest = escapeRegularExpression(JSON.stringify(change.previousDigest)) + const trackingPattern = new RegExp( + `("url"\\s*:\\s*${url}[\\s\\S]*?"changeTracking"\\s*:\\s*\\{[\\s\\S]*?"digest"\\s*:\\s*)${previousDigest}([\\s\\S]*?"observedAt"\\s*:\\s*)(?:"[^"]*"|null)`, + 'g' + ) + const matches = [...source.matchAll(trackingPattern)] + if (matches.length !== 1) { + throw new Error( + `models/${change.modelId} must contain exactly one matching tracked source ${change.url}` + ) + } + return source.replace( + trackingPattern, + `$1${JSON.stringify(change.nextDigest)}$2${JSON.stringify(change.observedAt)}` + ) +} + +export async function syncModelSourceDigests(options: { + rootDir: string + write: boolean + observedAt: string + fetchImpl?: SourceFetch +}): Promise { + const tracked = await loadTrackedSources(options.rootDir) + const fetchImpl = options.fetchImpl ?? (fetch as SourceFetch) + const digestByUrl = new Map>() + for (const entry of tracked) { + if (!digestByUrl.has(entry.source.url)) { + digestByUrl.set(entry.source.url, fetchDigest(entry.source.url, fetchImpl)) + } + } + + const observations = await Promise.allSettled( + tracked.map(async entry => ({ + entry, + digest: await digestByUrl.get(entry.source.url), + })) + ) + const failures = observations.flatMap((result, index) => + result.status === 'rejected' + ? [`models/${tracked[index]?.modelId}: ${String(result.reason)}`] + : [] + ) + if (failures.length > 0) { + throw new Error( + `Model source monitoring failed without writing changes:\n${failures.join('\n')}` + ) + } + + const changes: ModelSourceChange[] = [] + for (const result of observations) { + if (result.status !== 'fulfilled') continue + const { entry, digest } = result.value + if (!digest || digest === entry.source.changeTracking.digest) continue + changes.push({ + modelId: entry.modelId, + filePath: entry.filePath, + url: entry.source.url, + fields: entry.source.fields ?? [], + previousDigest: entry.source.changeTracking.digest, + nextDigest: digest, + observedAt: options.observedAt, + }) + } + + if (options.write) { + const changesByFile = Map.groupBy(changes, change => change.filePath) + for (const [filePath, fileChanges] of changesByFile) { + let source = await fs.readFile(filePath, 'utf8') + for (const change of fileChanges) { + source = replaceTrackedSource(source, change) + } + await fs.writeFile(filePath, source, 'utf8') + } + } + + return { checked: tracked.length, changes } +} diff --git a/scripts/fetch/lib/product-version-sync.ts b/scripts/fetch/lib/product-version-sync.ts new file mode 100644 index 00000000..21551526 --- /dev/null +++ b/scripts/fetch/lib/product-version-sync.ts @@ -0,0 +1,336 @@ +import fs from 'node:fs/promises' +import path from 'node:path' + +import type { ManifestReleaseTracking } from '../../../src/types/manifests' + +const PRODUCT_CATEGORIES = ['ides', 'clis', 'desktops', 'extensions'] as const + +interface ProductManifest { + id: string + latestVersion: string + releaseTracking?: ManifestReleaseTracking + [key: string]: unknown +} + +interface JsonResponse { + ok: boolean + status: number + statusText: string + json(): Promise +} + +export type VersionFetch = ( + input: string | URL, + init?: { + method?: string + headers?: Record + body?: string + } +) => Promise + +export interface VersionObservation { + version: string + sourceUrl: string +} + +export interface VersionChange { + category: (typeof PRODUCT_CATEGORIES)[number] + id: string + filePath: string + previousVersion: string + nextVersion: string + sourceUrl: string +} + +export interface VersionSyncResult { + checked: number + changes: VersionChange[] +} + +function isRecord(value: unknown): value is Record { + return Boolean(value) && typeof value === 'object' && !Array.isArray(value) +} + +function escapeRegularExpression(value: string): string { + return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') +} + +function getRequiredString( + value: unknown, + field: string, + provider: ManifestReleaseTracking['provider'] +): string { + if (typeof value !== 'string' || !value.trim()) { + throw new Error(`${provider} returned no usable ${field}`) + } + return value.trim() +} + +async function fetchJson( + fetchImpl: VersionFetch, + url: string, + init: { + method?: string + headers?: Record + body?: string + } = {} +): Promise { + const response = await fetchImpl(url, init) + if (!response.ok) { + throw new Error(`${url} returned ${response.status} ${response.statusText}`) + } + return response.json() +} + +function githubHeaders(): Record { + const headers: Record = { + Accept: 'application/vnd.github+json', + 'User-Agent': 'aicodingstack-version-sync', + 'X-GitHub-Api-Version': '2022-11-28', + } + if (process.env.GITHUB_TOKEN) { + headers.Authorization = `Bearer ${process.env.GITHUB_TOKEN}` + } + return headers +} + +export async function fetchTrackedVersion( + tracking: ManifestReleaseTracking, + fetchImpl: VersionFetch = fetch as VersionFetch +): Promise { + switch (tracking.provider) { + case 'npm': { + const url = `https://registry.npmjs.org/${encodeURIComponent(tracking.identifier)}` + const data = await fetchJson(fetchImpl, url) + const distTags = isRecord(data) && isRecord(data['dist-tags']) ? data['dist-tags'] : null + const channel = tracking.channel ?? 'latest' + return { + version: getRequiredString(distTags?.[channel], `dist-tags.${channel}`, tracking.provider), + sourceUrl: `https://www.npmjs.com/package/${tracking.identifier}`, + } + } + case 'homebrew-formula': { + const url = `https://formulae.brew.sh/api/formula/${encodeURIComponent(tracking.identifier)}.json` + const data = await fetchJson(fetchImpl, url) + const versions = isRecord(data) && isRecord(data.versions) ? data.versions : null + return { + version: getRequiredString(versions?.stable, 'versions.stable', tracking.provider), + sourceUrl: `https://formulae.brew.sh/formula/${tracking.identifier}`, + } + } + case 'homebrew-cask': { + const url = `https://formulae.brew.sh/api/cask/${encodeURIComponent(tracking.identifier)}.json` + const data = await fetchJson(fetchImpl, url) + return { + version: getRequiredString( + isRecord(data) ? data.version : null, + 'version', + tracking.provider + ), + sourceUrl: `https://formulae.brew.sh/cask/${tracking.identifier}`, + } + } + case 'crates-io': { + const url = `https://crates.io/api/v1/crates/${encodeURIComponent(tracking.identifier)}` + const data = await fetchJson(fetchImpl, url, { + headers: { + Accept: 'application/json', + 'User-Agent': 'aicodingstack-version-sync', + }, + }) + const crate = isRecord(data) && isRecord(data.crate) ? data.crate : null + const stableVersion = crate?.max_stable_version ?? crate?.max_version + return { + version: getRequiredString(stableVersion, 'max_stable_version', tracking.provider), + sourceUrl: `https://crates.io/crates/${tracking.identifier}`, + } + } + case 'pypi': { + const url = `https://pypi.org/pypi/${encodeURIComponent(tracking.identifier)}/json` + const data = await fetchJson(fetchImpl, url) + const info = isRecord(data) && isRecord(data.info) ? data.info : null + return { + version: getRequiredString(info?.version, 'info.version', tracking.provider), + sourceUrl: `https://pypi.org/project/${tracking.identifier}/`, + } + } + case 'vscode-marketplace': { + const url = + 'https://marketplace.visualstudio.com/_apis/public/gallery/extensionquery?api-version=7.2-preview.1' + const data = await fetchJson(fetchImpl, url, { + method: 'POST', + headers: { + Accept: 'application/json;api-version=7.2-preview.1', + 'Content-Type': 'application/json', + 'User-Agent': 'aicodingstack-version-sync', + }, + body: JSON.stringify({ + filters: [ + { + criteria: [{ filterType: 7, value: tracking.identifier }], + }, + ], + flags: 914, + }), + }) + const results = isRecord(data) && Array.isArray(data.results) ? data.results : [] + const firstResult = isRecord(results[0]) ? results[0] : null + const extensions = + firstResult && Array.isArray(firstResult.extensions) ? firstResult.extensions : [] + const firstExtension = isRecord(extensions[0]) ? extensions[0] : null + const versions = + firstExtension && Array.isArray(firstExtension.versions) ? firstExtension.versions : [] + const firstVersion = isRecord(versions[0]) ? versions[0] : null + return { + version: getRequiredString(firstVersion?.version, 'versions[0].version', tracking.provider), + sourceUrl: `https://marketplace.visualstudio.com/items?itemName=${tracking.identifier}`, + } + } + case 'github-release': { + const url = `https://api.github.com/repos/${tracking.identifier}/releases/latest` + const data = await fetchJson(fetchImpl, url, githubHeaders()) + return { + version: getRequiredString( + isRecord(data) ? data.tag_name : null, + 'tag_name', + tracking.provider + ), + sourceUrl: + isRecord(data) && typeof data.html_url === 'string' + ? data.html_url + : `https://github.com/${tracking.identifier}/releases/latest`, + } + } + } +} + +function parseStableNumericVersion(value: string): number[] | null { + const normalized = value.trim().replace(/^v(?=\d)/, '') + if (!/^\d+(?:\.\d+)*$/.test(normalized)) return null + return normalized.split('.').map(segment => Number(segment)) +} + +function compareNumericVersions(left: number[], right: number[]): number { + const length = Math.max(left.length, right.length) + for (let index = 0; index < length; index++) { + const difference = (left[index] ?? 0) - (right[index] ?? 0) + if (difference !== 0) return difference + } + return 0 +} + +function formatObservedVersion(observed: string, current: string): string { + const normalized = observed.trim() + if (/^v\d/.test(current) && !/^v\d/.test(normalized)) return `v${normalized}` + if (!/^v\d/.test(current) && /^v\d/.test(normalized)) return normalized.slice(1) + return normalized +} + +function assertNotDowngrade( + current: string, + observed: string, + tracking: ManifestReleaseTracking +): void { + if (!['npm', 'crates-io', 'pypi', 'vscode-marketplace'].includes(tracking.provider)) return + const currentVersion = parseStableNumericVersion(current) + const observedVersion = parseStableNumericVersion(observed) + if ( + currentVersion && + observedVersion && + compareNumericVersions(observedVersion, currentVersion) < 0 + ) { + throw new Error( + `${tracking.provider} reported ${observed}, which is older than recorded version ${current}` + ) + } +} + +async function loadTrackedManifests(rootDir: string): Promise< + Array<{ + category: (typeof PRODUCT_CATEGORIES)[number] + filePath: string + manifest: ProductManifest + }> +> { + const manifests: Array<{ + category: (typeof PRODUCT_CATEGORIES)[number] + filePath: string + manifest: ProductManifest + }> = [] + + for (const category of PRODUCT_CATEGORIES) { + const directory = path.join(rootDir, 'manifests', category) + const fileNames = (await fs.readdir(directory)).filter(file => file.endsWith('.json')).sort() + for (const fileName of fileNames) { + const filePath = path.join(directory, fileName) + const manifest = JSON.parse(await fs.readFile(filePath, 'utf8')) as ProductManifest + if (manifest.releaseTracking) { + manifests.push({ category, filePath, manifest }) + } + } + } + + return manifests +} + +export async function syncProductVersions(options: { + rootDir: string + write: boolean + fetchImpl?: VersionFetch +}): Promise { + const tracked = await loadTrackedManifests(options.rootDir) + const observations = await Promise.allSettled( + tracked.map(async entry => { + const tracking = entry.manifest.releaseTracking + if (!tracking) throw new Error(`${entry.manifest.id} has no releaseTracking configuration`) + const observation = await fetchTrackedVersion(tracking, options.fetchImpl) + const nextVersion = formatObservedVersion(observation.version, entry.manifest.latestVersion) + assertNotDowngrade(entry.manifest.latestVersion, nextVersion, tracking) + return { entry, observation, nextVersion } + }) + ) + + const failures = observations.flatMap((result, index) => + result.status === 'rejected' + ? [`${tracked[index]?.category}/${tracked[index]?.manifest.id}: ${String(result.reason)}`] + : [] + ) + if (failures.length > 0) { + throw new Error( + `Version synchronization failed without writing changes:\n${failures.join('\n')}` + ) + } + + const changes: VersionChange[] = [] + for (const result of observations) { + if (result.status !== 'fulfilled') continue + const { entry, observation, nextVersion } = result.value + if (nextVersion === entry.manifest.latestVersion) continue + changes.push({ + category: entry.category, + id: entry.manifest.id, + filePath: entry.filePath, + previousVersion: entry.manifest.latestVersion, + nextVersion, + sourceUrl: observation.sourceUrl, + }) + } + + if (options.write) { + for (const change of changes) { + const source = await fs.readFile(change.filePath, 'utf8') + const previousValue = escapeRegularExpression(JSON.stringify(change.previousVersion)) + const pattern = new RegExp(`("latestVersion"\\s*:\\s*)${previousValue}`, 'g') + const matches = [...source.matchAll(pattern)] + if (matches.length !== 1) { + throw new Error( + `${change.category}/${change.id} must contain exactly one matching latestVersion field` + ) + } + const updated = source.replace(pattern, `$1${JSON.stringify(change.nextVersion)}`) + await fs.writeFile(change.filePath, updated, 'utf8') + } + } + + return { checked: tracked.length, changes } +} diff --git a/scripts/validate/data-health.ts b/scripts/validate/data-health.ts index e3624a5c..ac13e768 100644 --- a/scripts/validate/data-health.ts +++ b/scripts/validate/data-health.ts @@ -598,6 +598,21 @@ function getArgument(name: string): string | null { return process.argv.find(argument => argument.startsWith(prefix))?.slice(prefix.length) ?? null } +export function shouldFailDataHealth( + report: DataHealthReport, + failOn: string, + failOnCodes: Set = new Set() +): boolean { + if (!['error', 'warning', 'never'].includes(failOn)) { + throw new Error(`Invalid --fail-on value: ${failOn}`) + } + return ( + (failOn === 'error' && report.summary.errors > 0) || + (failOn === 'warning' && report.summary.errors + report.summary.warnings > 0) || + report.issues.some(issue => failOnCodes.has(issue.code)) + ) +} + async function main(): Promise { const rootDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..') const snapshotPath = path.join(rootDir, 'data', 'data-health.json') @@ -631,13 +646,13 @@ async function main(): Promise { } const failOn = getArgument('fail-on') ?? 'never' - if (!['error', 'warning', 'never'].includes(failOn)) { - throw new Error(`Invalid --fail-on value: ${failOn}`) - } - if ( - (failOn === 'error' && report.summary.errors > 0) || - (failOn === 'warning' && report.summary.errors + report.summary.warnings > 0) - ) { + const failOnCodes = new Set( + (getArgument('fail-on-code') ?? '') + .split(',') + .map(code => code.trim()) + .filter(Boolean) + ) + if (shouldFailDataHealth(report, failOn, failOnCodes)) { process.exitCode = 1 } } diff --git a/src/app/[locale]/model-intelligence-index/page.tsx b/src/app/[locale]/model-intelligence-index/page.tsx index 599425ca..0ac936b6 100644 --- a/src/app/[locale]/model-intelligence-index/page.tsx +++ b/src/app/[locale]/model-intelligence-index/page.tsx @@ -5,8 +5,8 @@ import PageHeader from '@/components/PageHeader' import type { Locale } from '@/i18n/config' import { buildTitle, generateStaticPageMetadata } from '@/lib/metadata' import { + allModelIntelligencePoints, modelIntelligenceMeta, - modelIntelligencePoints, modelIntelligenceSeries, } from '@/lib/model-intelligence-index' import { ModelIntelligenceIndexPage } from './page.client' @@ -46,7 +46,7 @@ export default async function Page({ params }: Props) { diff --git a/src/lib/model-intelligence-index.ts b/src/lib/model-intelligence-index.ts index 506d622f..78c2bac5 100644 --- a/src/lib/model-intelligence-index.ts +++ b/src/lib/model-intelligence-index.ts @@ -2,24 +2,12 @@ import { modelsData } from '@/lib/generated/models' import { vendorsData } from '@/lib/generated/vendors' import { findVendorByName } from '@/lib/vendor-identity' import artificialAnalysisData from '../../data/artificial-analysis-index.json' -import modelIntelligenceData from '../../data/model-intelligence-index.json' const FALLBACK_COLOR: ModelIntelligenceThemeColor = { light: '#6b7280', dark: '#9ca3af', } -export const modelIntelligenceHiddenVendors = modelIntelligenceData.hiddenVendorIds.map( - vendorId => { - const vendor = vendorsData.find(candidate => candidate.id === vendorId) - - if (!vendor) { - throw new Error(`Model intelligence configuration has no matching vendor: ${vendorId}`) - } - - return vendor.name - } -) export const modelIntelligenceLegacyMissingModelIds = artificialAnalysisData.legacyMissingModelIds export interface ModelIntelligenceThemeColor { @@ -135,15 +123,9 @@ export const allModelIntelligencePoints: ModelIntelligencePoint[] = } }) -const hiddenVendorSet = new Set(modelIntelligenceHiddenVendors) - -export const modelIntelligencePoints = allModelIntelligencePoints.filter( - point => !hiddenVendorSet.has(point.vendor) -) - const groupedSeries = new Map() -for (const point of modelIntelligencePoints) { +for (const point of allModelIntelligencePoints) { const id = `${point.vendor}:${point.seriesId}` const existing = groupedSeries.get(id) diff --git a/src/lib/model-price-intelligence-index.ts b/src/lib/model-price-intelligence-index.ts index de623829..0e4a2fed 100644 --- a/src/lib/model-price-intelligence-index.ts +++ b/src/lib/model-price-intelligence-index.ts @@ -4,6 +4,7 @@ import { type ModelIntelligenceThemeColor, modelIntelligenceMeta, } from '@/lib/model-intelligence-index' +import type { ManifestModel } from '@/types/manifests' import modelPriceIntelligenceData from '../../data/model-price-intelligence-index.json' const INPUT_SHARE = modelPriceIntelligenceData.inputShare @@ -19,11 +20,6 @@ interface SelectedModel { linearLabelDx?: number linearLabelDy?: number linearLabelAnchor?: LabelAnchor - usdPriceOverride?: { - input: number - output: number - sourceUrl: string - } } const selectedModels = modelPriceIntelligenceData.models as SelectedModel[] @@ -46,11 +42,58 @@ export interface ModelPriceIntelligencePoint { linearLabelDx?: number linearLabelDy?: number linearLabelAnchor?: LabelAnchor - pricingSource: 'catalog' | 'artificial-analysis' + pricingSource: 'official' | 'reference' pricingSourceUrl: string | null } -const modelById = new Map(modelsData.map(model => [model.id, model])) +interface ComparableUsdPricing { + input: number + output: number + source: ModelPriceIntelligencePoint['pricingSource'] + sourceUrl: string | null +} + +function getComparableUsdPricing(model: ManifestModel): ComparableUsdPricing { + const primaryOffer = + model.tokenPricing.status === 'available' + ? model.tokenPricing.offers.find(offer => offer.id === model.tokenPricing.primaryOffer) + : undefined + const primaryRates = primaryOffer?.tiers[0]?.rates + + if ( + primaryOffer?.currency === 'USD' && + primaryRates?.input !== null && + primaryRates?.input !== undefined && + primaryRates.output !== null && + primaryRates.output !== undefined + ) { + return { + input: primaryRates.input, + output: primaryRates.output, + source: 'official', + sourceUrl: null, + } + } + + const referencePricing = model.referenceTokenPricing + + if ( + referencePricing?.currency === 'USD' && + referencePricing.rates.input !== null && + referencePricing.rates.output !== null + ) { + return { + input: referencePricing.rates.input, + output: referencePricing.rates.output, + source: 'reference', + sourceUrl: referencePricing.source.url, + } + } + + throw new Error(`Price-intelligence selection has no comparable USD pricing: ${model.id}`) +} + +const modelById = new Map((modelsData as ManifestModel[]).map(model => [model.id, model] as const)) const intelligenceByModelId = new Map( allModelIntelligencePoints.map(point => [point.modelId, point]) ) @@ -70,31 +113,7 @@ export const modelPriceIntelligencePoints: ModelPriceIntelligencePoint[] = selec ) } - if (!selection.usdPriceOverride && model.tokenPricing.status !== 'available') { - throw new Error( - `Price-intelligence selection has no available token pricing: ${selection.modelId}` - ) - } - - const primaryOffer = - model.tokenPricing.status === 'available' - ? model.tokenPricing.offers.find(offer => offer.id === model.tokenPricing.primaryOffer) - : undefined - const primaryTier = primaryOffer?.tiers[0] - const inputPrice = selection.usdPriceOverride?.input ?? primaryTier?.rates.input - const outputPrice = selection.usdPriceOverride?.output ?? primaryTier?.rates.output - - if ( - (!selection.usdPriceOverride && primaryOffer?.currency !== 'USD') || - inputPrice === null || - inputPrice === undefined || - outputPrice === null || - outputPrice === undefined - ) { - throw new Error( - `Price-intelligence selection requires comparable USD input and output pricing: ${selection.modelId}` - ) - } + const pricing = getComparableUsdPricing(model) return { name: model.name, @@ -102,13 +121,13 @@ export const modelPriceIntelligencePoints: ModelPriceIntelligencePoint[] = selec score: intelligence.score, estimated: intelligence.estimated, configuration: intelligence.configuration, - inputPrice, - outputPrice, - blendedPrice: inputPrice * INPUT_SHARE + outputPrice * OUTPUT_SHARE, + inputPrice: pricing.input, + outputPrice: pricing.output, + blendedPrice: pricing.input * INPUT_SHARE + pricing.output * OUTPUT_SHARE, currency: 'USD', color: intelligence.color, - pricingSource: selection.usdPriceOverride ? 'artificial-analysis' : 'catalog', - pricingSourceUrl: selection.usdPriceOverride?.sourceUrl ?? null, + pricingSource: pricing.source, + pricingSourceUrl: pricing.sourceUrl, ...selection, } } @@ -140,7 +159,7 @@ export const modelPriceIntelligenceMeta = { point ): point is ModelPriceIntelligencePoint & { pricingSourceUrl: string - } => point.pricingSource === 'artificial-analysis' && point.pricingSourceUrl !== null + } => point.pricingSource === 'reference' && point.pricingSourceUrl !== null ) .map(point => ({ modelId: point.modelId, diff --git a/src/types/manifests.ts b/src/types/manifests.ts index 25a39676..2eb78fca 100644 --- a/src/types/manifests.ts +++ b/src/types/manifests.ts @@ -65,6 +65,11 @@ export interface ManifestSource { url: string title?: string fields?: string[] + changeTracking?: { + method: 'normalized-content-sha256' + digest: string | null + observedAt: string | null + } } /** @@ -131,6 +136,29 @@ export interface ManifestRelatedProduct { productId: string } +/** + * Declarative latest-version source + * Based on: /manifests/$schemas/ref/product.schema.json#$defs/releaseTracking + */ +export type ManifestReleaseTracking = + | { + provider: 'npm' + identifier: string + channel?: string + } + | { + provider: 'homebrew-formula' | 'homebrew-cask' | 'crates-io' | 'pypi' + identifier: string + } + | { + provider: 'vscode-marketplace' + identifier: string + } + | { + provider: 'github-release' + identifier: string + } + /** * Platform installation information * Based on: /manifests/$schemas/ref/app.schema.json @@ -151,6 +179,7 @@ export interface ManifestBaseProduct extends ManifestVendorEntity { /** Stable identifier shared by every surface in the same product family */ familyId?: string latestVersion: string + releaseTracking?: ManifestReleaseTracking githubUrl: string | null license: string pricing: ManifestPricingTier[] @@ -274,6 +303,17 @@ export interface ManifestUnavailableTokenPricing { export type ManifestTokenPricing = ManifestAvailableTokenPricing | ManifestUnavailableTokenPricing +export interface ManifestReferenceTokenPricing { + currency: string + basis: 'first-party-api' | 'provider-median' + rates: ManifestTokenPricingRates + source: { + name: string + url: string + observedAt: string + } +} + /** * Benchmark scores * Based on: /manifests/$schemas/model.schema.json @@ -288,6 +328,18 @@ export interface ManifestBenchmarks { liveCodeBench: number | null } +/** + * Exact upstream benchmark leaderboard entry + * Based on: /manifests/$schemas/model.schema.json#$defs/benchmarkTracking + */ +export interface ManifestBenchmarkTracking { + provider: 'swe-bench' + benchmark: 'sweBench' + leaderboard: 'Verified' + resultId: string + modelLabel: string +} + /** * Lifecycle stage of a model */ @@ -303,6 +355,7 @@ export interface ManifestModel extends ManifestVendorEntity { contextWindow: number maxOutput: number | null tokenPricing: ManifestTokenPricing + referenceTokenPricing?: ManifestReferenceTokenPricing releaseDate: string | null lifecycle: ModelLifecycle knowledgeCutoff: string | null @@ -310,6 +363,7 @@ export interface ManifestModel extends ManifestVendorEntity { outputModalities: ModelOutputModality[] capabilities: ModelCapability[] benchmarks: ManifestBenchmarks + benchmarkTracking?: ManifestBenchmarkTracking[] platformUrls: ManifestPlatformUrls } diff --git a/tests/benchmark-sync.test.ts b/tests/benchmark-sync.test.ts new file mode 100644 index 00000000..555af3a5 --- /dev/null +++ b/tests/benchmark-sync.test.ts @@ -0,0 +1,131 @@ +import fs from 'node:fs/promises' +import os from 'node:os' +import path from 'node:path' + +import { afterEach, describe, expect, it } from 'vitest' + +import { type BenchmarkFetch, syncBenchmarks } from '../scripts/fetch/lib/benchmark-sync' + +const temporaryDirectories: string[] = [] + +function leaderboardFetch(results: unknown[]): BenchmarkFetch { + return async () => ({ + ok: true, + status: 200, + statusText: 'OK', + async json() { + return { + leaderboards: [{ name: 'Verified', results }], + } + }, + }) +} + +async function createModelRoot(model: Record): Promise { + const rootDir = await fs.mkdtemp(path.join(os.tmpdir(), 'benchmark-sync-')) + temporaryDirectories.push(rootDir) + await fs.mkdir(path.join(rootDir, 'manifests', 'models'), { recursive: true }) + await fs.writeFile( + path.join(rootDir, 'manifests', 'models', `${String(model.id)}.json`), + `${JSON.stringify(model, null, 2)}\n` + ) + return rootDir +} + +afterEach(async () => { + await Promise.all( + temporaryDirectories + .splice(0) + .map(directory => fs.rm(directory, { force: true, recursive: true })) + ) +}) + +describe('benchmark synchronization', () => { + it('updates an exact SWE-bench result without reformatting the manifest', async () => { + const rootDir = await createModelRoot({ + id: 'example', + benchmarks: { sweBench: 40 }, + benchmarkTracking: [ + { + provider: 'swe-bench', + benchmark: 'sweBench', + leaderboard: 'Verified', + resultId: 'exact-result', + modelLabel: 'Exact model and scaffold', + }, + ], + description: 'Preserve this value.', + }) + const filePath = path.join(rootDir, 'manifests', 'models', 'example.json') + const sourceBeforeSync = await fs.readFile(filePath, 'utf8') + + const result = await syncBenchmarks({ + rootDir, + write: true, + fetchImpl: leaderboardFetch([ + { + folder: 'exact-result', + name: 'Exact model and scaffold', + resolved: 42.5, + }, + ]), + }) + const sourceAfterSync = await fs.readFile(filePath, 'utf8') + + expect(result.changes).toHaveLength(1) + expect(sourceAfterSync).toBe(sourceBeforeSync.replace('"sweBench": 40', '"sweBench": 42.5')) + }) + + it('rejects a changed upstream label instead of fuzzy matching it', async () => { + const rootDir = await createModelRoot({ + id: 'example', + benchmarks: { sweBench: 40 }, + benchmarkTracking: [ + { + provider: 'swe-bench', + benchmark: 'sweBench', + leaderboard: 'Verified', + resultId: 'exact-result', + modelLabel: 'Expected model', + }, + ], + }) + + await expect( + syncBenchmarks({ + rootDir, + write: true, + fetchImpl: leaderboardFetch([ + { folder: 'exact-result', name: 'Different model', resolved: 42.5 }, + ]), + }) + ).rejects.toThrow('label changed') + }) + + it('does not write when an exact result is missing', async () => { + const rootDir = await createModelRoot({ + id: 'example', + benchmarks: { sweBench: 40 }, + benchmarkTracking: [ + { + provider: 'swe-bench', + benchmark: 'sweBench', + leaderboard: 'Verified', + resultId: 'exact-result', + modelLabel: 'Expected model', + }, + ], + }) + const filePath = path.join(rootDir, 'manifests', 'models', 'example.json') + const sourceBeforeSync = await fs.readFile(filePath, 'utf8') + + await expect( + syncBenchmarks({ + rootDir, + write: true, + fetchImpl: leaderboardFetch([]), + }) + ).rejects.toThrow('expected exactly one SWE-bench result') + expect(await fs.readFile(filePath, 'utf8')).toBe(sourceBeforeSync) + }) +}) diff --git a/tests/data-health.test.ts b/tests/data-health.test.ts index 5ec65daf..52dc26f3 100644 --- a/tests/data-health.test.ts +++ b/tests/data-health.test.ts @@ -4,6 +4,7 @@ import { analyzeDataHealth, type ManifestRecord, renderDataHealthMarkdown, + shouldFailDataHealth, } from '../scripts/validate/data-health' function record( @@ -143,4 +144,22 @@ describe('data health reporting', () => { it('rejects a malformed report date', () => { expect(() => analyzeDataHealth([], '2026-02-30')).toThrow('Invalid --as-of date') }) + + it('can fail on selected issue codes without failing on every warning', () => { + const report = analyzeDataHealth( + [ + record('models', 'stale-model', { + verified: true, + sources: [{ url: 'https://example.com' }], + lastVerifiedAt: '2026-01-01', + verifiedBy: 'test', + confidence: 'high', + }), + ], + '2026-07-28' + ) + + expect(shouldFailDataHealth(report, 'error')).toBe(false) + expect(shouldFailDataHealth(report, 'error', new Set(['stale-verification']))).toBe(true) + }) }) diff --git a/tests/model-intelligence-index.test.ts b/tests/model-intelligence-index.test.ts index 19cde46e..d17d75ce 100644 --- a/tests/model-intelligence-index.test.ts +++ b/tests/model-intelligence-index.test.ts @@ -4,10 +4,8 @@ import { vendorsData } from '@/lib/generated/vendors' import { allModelIntelligencePoints, createTimelineTicks, - modelIntelligenceHiddenVendors, modelIntelligenceLegacyMissingModelIds, modelIntelligenceMeta, - modelIntelligencePoints, modelIntelligenceSeries, } from '@/lib/model-intelligence-index' import { findVendorByName } from '@/lib/vendor-identity' @@ -110,14 +108,6 @@ describe('model intelligence index', () => { expect(missingModelIds).toEqual(legacyMissingModelIds) }) - it('keeps hidden vendors in source data but excludes them from the page', () => { - for (const vendor of modelIntelligenceHiddenVendors) { - expect(allModelIntelligencePoints.some(point => point.vendor === vendor)).toBe(true) - expect(modelIntelligencePoints.some(point => point.vendor === vendor)).toBe(false) - expect(modelIntelligenceSeries.some(series => series.vendor === vendor)).toBe(false) - } - }) - it('keeps a single vendor color while separating model series', () => { const vendorColors = new Map>() const vendorStyles = new Map>() diff --git a/tests/model-price-intelligence-index.test.ts b/tests/model-price-intelligence-index.test.ts index a77492a7..0589167e 100644 --- a/tests/model-price-intelligence-index.test.ts +++ b/tests/model-price-intelligence-index.test.ts @@ -21,6 +21,7 @@ describe('model price-intelligence index', () => { 'gpt-5-6-terra', 'claude-haiku-4-5', 'claude-opus-5', + 'claude-fable-5', 'hy3', ]) ) @@ -41,7 +42,7 @@ describe('model price-intelligence index', () => { it('uses reviewed USD API prices when the catalog offer is not directly comparable', () => { const fallbackPoints = modelPriceIntelligencePoints.filter( - point => point.pricingSource === 'artificial-analysis' + point => point.pricingSource === 'reference' ) expect(fallbackPoints.map(point => point.modelId)).toEqual([ diff --git a/tests/model-source-sync.test.ts b/tests/model-source-sync.test.ts new file mode 100644 index 00000000..c2d17357 --- /dev/null +++ b/tests/model-source-sync.test.ts @@ -0,0 +1,126 @@ +import fs from 'node:fs/promises' +import os from 'node:os' +import path from 'node:path' + +import { afterEach, describe, expect, it } from 'vitest' + +import { + digestSourceContent, + normalizeSourceContent, + type SourceFetch, + syncModelSourceDigests, +} from '../scripts/fetch/lib/model-source-sync' + +const temporaryDirectories: string[] = [] + +function textFetch(content: string): SourceFetch { + return async () => ({ + ok: true, + status: 200, + statusText: 'OK', + async text() { + return content + }, + }) +} + +async function createModelRoot(model: Record): Promise { + const rootDir = await fs.mkdtemp(path.join(os.tmpdir(), 'model-source-sync-')) + temporaryDirectories.push(rootDir) + await fs.mkdir(path.join(rootDir, 'manifests', 'models'), { recursive: true }) + await fs.writeFile( + path.join(rootDir, 'manifests', 'models', `${String(model.id)}.json`), + `${JSON.stringify(model, null, 2)}\n` + ) + return rootDir +} + +afterEach(async () => { + await Promise.all( + temporaryDirectories + .splice(0) + .map(directory => fs.rm(directory, { force: true, recursive: true })) + ) +}) + +describe('model source monitoring', () => { + it('normalizes markup and ignores script content', () => { + const first = '
Price: $2 & active
' + const second = '
Price: $2 & active
' + + expect(normalizeSourceContent(first)).toBe('Price: $2 & active') + expect(digestSourceContent(first)).toBe(digestSourceContent(second)) + }) + + it('records only a source digest and observation date', async () => { + const rootDir = await createModelRoot({ + id: 'example', + lifecycle: 'latest', + tokenPricing: { status: 'available' }, + sources: [ + { + url: 'https://example.com/pricing', + fields: ['tokenPricing', 'lifecycle'], + changeTracking: { + method: 'normalized-content-sha256', + digest: null, + observedAt: null, + }, + }, + ], + }) + const filePath = path.join(rootDir, 'manifests', 'models', 'example.json') + + const result = await syncModelSourceDigests({ + rootDir, + write: true, + observedAt: '2026-07-28', + fetchImpl: textFetch(`
${'Official pricing and lifecycle. '.repeat(8)}
`), + }) + const updated = JSON.parse(await fs.readFile(filePath, 'utf8')) as Record + const sources = updated.sources as Array> + const tracking = sources[0]?.changeTracking as Record + + expect(result.changes).toHaveLength(1) + expect(updated.lifecycle).toBe('latest') + expect(updated.tokenPricing).toEqual({ status: 'available' }) + expect(tracking.digest).toMatch(/^sha256:[a-f0-9]{64}$/) + expect(tracking.observedAt).toBe('2026-07-28') + }) + + it('does not write any digest when a monitored source fails', async () => { + const rootDir = await createModelRoot({ + id: 'example', + sources: [ + { + url: 'https://example.com/pricing', + changeTracking: { + method: 'normalized-content-sha256', + digest: null, + observedAt: null, + }, + }, + ], + }) + const filePath = path.join(rootDir, 'manifests', 'models', 'example.json') + const before = await fs.readFile(filePath, 'utf8') + const failingFetch: SourceFetch = async () => ({ + ok: false, + status: 503, + statusText: 'Unavailable', + async text() { + return '' + }, + }) + + await expect( + syncModelSourceDigests({ + rootDir, + write: true, + observedAt: '2026-07-28', + fetchImpl: failingFetch, + }) + ).rejects.toThrow('failed without writing changes') + expect(await fs.readFile(filePath, 'utf8')).toBe(before) + }) +}) diff --git a/tests/product-version-sync.test.ts b/tests/product-version-sync.test.ts new file mode 100644 index 00000000..613b3f2d --- /dev/null +++ b/tests/product-version-sync.test.ts @@ -0,0 +1,223 @@ +import fs from 'node:fs/promises' +import os from 'node:os' +import path from 'node:path' + +import { afterEach, describe, expect, it } from 'vitest' + +import { + fetchTrackedVersion, + syncProductVersions, + type VersionFetch, +} from '../scripts/fetch/lib/product-version-sync' + +const temporaryDirectories: string[] = [] + +function jsonFetch(payload: unknown): VersionFetch { + return async () => ({ + ok: true, + status: 200, + statusText: 'OK', + async json() { + return payload + }, + }) +} + +async function createManifestRoot(manifests: Record[]): Promise { + const rootDir = await fs.mkdtemp(path.join(os.tmpdir(), 'product-version-sync-')) + temporaryDirectories.push(rootDir) + for (const category of ['ides', 'clis', 'desktops', 'extensions']) { + await fs.mkdir(path.join(rootDir, 'manifests', category), { recursive: true }) + } + for (const manifest of manifests) { + await fs.writeFile( + path.join(rootDir, 'manifests', 'clis', `${String(manifest.id)}.json`), + `${JSON.stringify(manifest, null, 2)}\n` + ) + } + return rootDir +} + +afterEach(async () => { + await Promise.all( + temporaryDirectories + .splice(0) + .map(directory => fs.rm(directory, { force: true, recursive: true })) + ) +}) + +describe('product version sources', () => { + it('reads npm dist-tags', async () => { + const observation = await fetchTrackedVersion( + { provider: 'npm', identifier: '@example/tool', channel: 'latest' }, + jsonFetch({ 'dist-tags': { latest: '2.3.4' } }) + ) + + expect(observation).toEqual({ + version: '2.3.4', + sourceUrl: 'https://www.npmjs.com/package/@example/tool', + }) + }) + + it('reads Homebrew formula and cask versions', async () => { + const formula = await fetchTrackedVersion( + { provider: 'homebrew-formula', identifier: 'example' }, + jsonFetch({ versions: { stable: '3.2.1' } }) + ) + const cask = await fetchTrackedVersion( + { provider: 'homebrew-cask', identifier: 'example-app' }, + jsonFetch({ version: '4.5.6' }) + ) + + expect(formula.version).toBe('3.2.1') + expect(cask.version).toBe('4.5.6') + }) + + it('reads crates.io and GitHub stable release versions', async () => { + const crate = await fetchTrackedVersion( + { provider: 'crates-io', identifier: 'example' }, + jsonFetch({ crate: { max_stable_version: '1.9.0', max_version: '2.0.0-beta.1' } }) + ) + const release = await fetchTrackedVersion( + { provider: 'github-release', identifier: 'example/tool' }, + jsonFetch({ + tag_name: 'v5.0.0', + html_url: 'https://github.com/example/tool/releases/tag/v5.0.0', + }) + ) + + expect(crate.version).toBe('1.9.0') + expect(release).toEqual({ + version: 'v5.0.0', + sourceUrl: 'https://github.com/example/tool/releases/tag/v5.0.0', + }) + }) + + it('reads PyPI and Visual Studio Marketplace versions', async () => { + const pypi = await fetchTrackedVersion( + { provider: 'pypi', identifier: 'example-tool' }, + jsonFetch({ info: { version: '1.4.0' } }) + ) + let marketplaceRequest: + | { + input: string + method?: string + body?: string + } + | undefined + const marketplaceFetch: VersionFetch = async (input, init) => { + marketplaceRequest = { + input: String(input), + method: init?.method, + body: init?.body, + } + return jsonFetch({ + results: [ + { + extensions: [{ versions: [{ version: '2.7.1' }] }], + }, + ], + })(input, init) + } + const marketplace = await fetchTrackedVersion( + { provider: 'vscode-marketplace', identifier: 'publisher.extension' }, + marketplaceFetch + ) + + expect(pypi).toEqual({ + version: '1.4.0', + sourceUrl: 'https://pypi.org/project/example-tool/', + }) + expect(marketplace.version).toBe('2.7.1') + expect(marketplaceRequest?.method).toBe('POST') + expect(JSON.parse(marketplaceRequest?.body ?? '{}')).toMatchObject({ + filters: [{ criteria: [{ filterType: 7, value: 'publisher.extension' }] }], + }) + }) +}) + +describe('product version synchronization', () => { + it('writes only latestVersion after every configured source succeeds', async () => { + const rootDir = await createManifestRoot([ + { + id: 'example', + latestVersion: '1.0.0', + releaseTracking: { provider: 'npm', identifier: 'example' }, + lastVerifiedAt: '2026-01-01', + description: 'Preserve this value.', + }, + ]) + const filePath = path.join(rootDir, 'manifests', 'clis', 'example.json') + const sourceBeforeSync = await fs.readFile(filePath, 'utf8') + + const result = await syncProductVersions({ + rootDir, + write: true, + fetchImpl: jsonFetch({ 'dist-tags': { latest: '1.1.0' } }), + }) + const sourceAfterSync = await fs.readFile(filePath, 'utf8') + const manifest = JSON.parse(sourceAfterSync) as Record + + expect(result.changes).toHaveLength(1) + expect(manifest.latestVersion).toBe('1.1.0') + expect(manifest.lastVerifiedAt).toBe('2026-01-01') + expect(manifest.description).toBe('Preserve this value.') + expect(sourceAfterSync).toBe( + sourceBeforeSync.replace('"latestVersion": "1.0.0"', '"latestVersion": "1.1.0"') + ) + }) + + it('does not write partial changes when a source fails', async () => { + const rootDir = await createManifestRoot([ + { + id: 'first', + latestVersion: '1.0.0', + releaseTracking: { provider: 'npm', identifier: 'first' }, + }, + { + id: 'second', + latestVersion: '1.0.0', + releaseTracking: { provider: 'npm', identifier: 'second' }, + }, + ]) + const fetchImpl: VersionFetch = async input => { + if (String(input).endsWith('second')) { + return { + ok: false, + status: 503, + statusText: 'Unavailable', + async json() { + return {} + }, + } + } + return jsonFetch({ 'dist-tags': { latest: '1.1.0' } })(input) + } + + await expect(syncProductVersions({ rootDir, write: true, fetchImpl })).rejects.toThrow( + 'failed without writing changes' + ) + const first = JSON.parse( + await fs.readFile(path.join(rootDir, 'manifests', 'clis', 'first.json'), 'utf8') + ) as Record + expect(first.latestVersion).toBe('1.0.0') + }) + + it('rejects npm version downgrades', async () => { + const rootDir = await createManifestRoot([ + { + id: 'example', + latestVersion: '2.0.0', + releaseTracking: { provider: 'npm', identifier: 'example' }, + }, + ]) + + await expect( + syncProductVersions({ + rootDir, + write: true, + fetchImpl: jsonFetch({ 'dist-tags': { latest: '1.9.0' } }), + }) + ).rejects.toThrow('older than recorded version') + }) +}) diff --git a/tests/validate/manifests.schema.test.ts b/tests/validate/manifests.schema.test.ts index c36aa14b..20f211c4 100644 --- a/tests/validate/manifests.schema.test.ts +++ b/tests/validate/manifests.schema.test.ts @@ -132,6 +132,7 @@ function validateAllManifests(rootDir: string): string[] { const manifestSchemaMap: Record = { clis: 'cli.schema.json', + desktops: 'desktop.schema.json', ides: 'ide.schema.json', extensions: 'extension.schema.json', providers: 'provider.schema.json', diff --git a/tests/validate/ranking-data.schema.test.ts b/tests/validate/ranking-data.schema.test.ts index 1f7ffe9c..32b0d573 100644 --- a/tests/validate/ranking-data.schema.test.ts +++ b/tests/validate/ranking-data.schema.test.ts @@ -5,11 +5,9 @@ import addFormats from 'ajv-formats' import { describe, expect, it } from 'vitest' describe('validate: ranking data schemas', () => { - it.each([ - 'model-intelligence-index', - 'model-price-intelligence-index', - ])('validates the %s configuration', dataName => { + it('validates the model-price-intelligence-index configuration', () => { const rootDir = path.resolve(__dirname, '../..') + const dataName = 'model-price-intelligence-index' const schema = JSON.parse( fs.readFileSync(path.join(rootDir, `data/$schemas/${dataName}.schema.json`), 'utf8') ) diff --git a/tests/validate/typesAlignment.test.ts b/tests/validate/typesAlignment.test.ts index 958370dc..6d30beca 100644 --- a/tests/validate/typesAlignment.test.ts +++ b/tests/validate/typesAlignment.test.ts @@ -144,6 +144,11 @@ function validateTypesAlignment(rootDir: string): string[] { iface: 'ManifestCLI', name: 'CLI', }, + { + schema: path.join(schemasDir, 'desktop.schema.json'), + iface: 'ManifestDesktop', + name: 'Desktop', + }, ] as const for (const check of checks) { From 6a703f2fcbe119a982e12a02f3d03670dde4b8f8 Mon Sep 17 00:00:00 2001 From: Pan YANG Date: Wed, 29 Jul 2026 00:30:10 +0800 Subject: [PATCH 4/8] fix(deps): pin secure node-minify core --- package-lock.json | 775 ++++++++++------------------------------------ package.json | 1 + 2 files changed, 159 insertions(+), 617 deletions(-) diff --git a/package-lock.json b/package-lock.json index b1451476..09485b45 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3764,106 +3764,43 @@ } }, "node_modules/@node-minify/core": { - "version": "8.0.6", - "resolved": "https://registry.npmmirror.com/@node-minify/core/-/core-8.0.6.tgz", - "integrity": "sha512-/vxN46ieWDLU67CmgbArEvOb41zlYFOkOtr9QW9CnTrBLuTyGgkyNWC2y5+khvRw3Br58p2B5ZVSx/PxCTru6g==", + "version": "10.5.0", + "resolved": "https://registry.npmmirror.com/@node-minify/core/-/core-10.5.0.tgz", + "integrity": "sha512-duptyliRQY+fXszqbm5CP+NauASUwkOlx/c4bwlT7tj5AQWhG9F26D3bfU/okKto9RDTGJy3cLwPvJC/j9lCkA==", "license": "MIT", "dependencies": { - "@node-minify/utils": "8.0.6", - "glob": "9.3.5", - "mkdirp": "1.0.4" + "@node-minify/utils": "10.5.0" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" } }, - "node_modules/@node-minify/core/node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "license": "MIT" - }, - "node_modules/@node-minify/core/node_modules/brace-expansion": { - "version": "2.1.3", - "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.1.3.tgz", - "integrity": "sha512-DRdx5neNsG/QXbniLFWi2YmC/68oeOOmKz6zOjVk6ZS1ZLXgLIKqVEc6hWsmkjBbgii0SwaBTcJ5XKj5gzY/4A==", + "node_modules/@node-minify/core/node_modules/@node-minify/utils": { + "version": "10.5.0", + "resolved": "https://registry.npmmirror.com/@node-minify/utils/-/utils-10.5.0.tgz", + "integrity": "sha512-3DZEYgersSgia5V/cee35sw6B7TTZlcCKyAGiuhT274/r1obMEtHt1lRmyCd52uX5QlZqDOTrD4bqHCxKzIYLg==", "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@node-minify/core/node_modules/glob": { - "version": "9.3.5", - "resolved": "https://registry.npmmirror.com/glob/-/glob-9.3.5.tgz", - "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==", - "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "minimatch": "^8.0.2", - "minipass": "^4.2.4", - "path-scurry": "^1.6.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@node-minify/core/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "license": "ISC" - }, - "node_modules/@node-minify/core/node_modules/minimatch": { - "version": "8.0.7", - "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-8.0.7.tgz", - "integrity": "sha512-V+1uQNdzybxa14e/p00HZnQNNcTjnRJjDxg2V8wtkjFctq4M7hXFws4oekyTP0Jebeq7QYtpFyOeBAjc88zvYg==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" + "fast-glob": "^3.3.3", + "gzip-size": "7.0.0" }, "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@node-minify/core/node_modules/minipass": { - "version": "4.2.8", - "resolved": "https://registry.npmmirror.com/minipass/-/minipass-4.2.8.tgz", - "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", - "license": "ISC", - "engines": { - "node": ">=8" + "node": ">=20.0.0" } }, - "node_modules/@node-minify/core/node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmmirror.com/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "license": "BlueOak-1.0.0", + "node_modules/@node-minify/core/node_modules/gzip-size": { + "version": "7.0.0", + "resolved": "https://registry.npmmirror.com/gzip-size/-/gzip-size-7.0.0.tgz", + "integrity": "sha512-O1Ld7Dr+nqPnmGpdhzLmMTQ4vAsD+rHwMm1NLUmoUFFymBOMKxCCrtDxqdBRYXdeEPEi3SyoR4TizJLQrnKBNA==", + "license": "MIT", "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + "duplexer": "^0.1.2" }, "engines": { - "node": ">=16 || 14 >=14.18" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@node-minify/core/node_modules/path-scurry/node_modules/minipass": { - "version": "7.1.3", - "resolved": "https://registry.npmmirror.com/minipass/-/minipass-7.1.3.tgz", - "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=16 || 14 >=14.17" + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@node-minify/terser": { @@ -3891,6 +3828,41 @@ "node": ">=16.0.0" } }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmmirror.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmmirror.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/@opennextjs/aws": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/@opennextjs/aws/-/aws-4.1.0.tgz", @@ -6863,7 +6835,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, "license": "MIT", "dependencies": { "fill-range": "^7.1.1" @@ -8618,6 +8589,34 @@ "node": ">=6.0.0" } }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmmirror.com/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -8650,6 +8649,15 @@ ], "license": "BSD-3-Clause" }, + "node_modules/fastq": { + "version": "1.20.1", + "resolved": "https://registry.npmmirror.com/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, "node_modules/fault": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", @@ -8699,7 +8707,6 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" @@ -8880,12 +8887,6 @@ "node": ">= 0.8" } }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "license": "ISC" - }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -9599,7 +9600,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.12.0" @@ -10691,6 +10691,15 @@ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "license": "MIT" }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmmirror.com/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, "node_modules/micromark": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", @@ -11464,7 +11473,6 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dev": true, "license": "MIT", "dependencies": { "braces": "^3.0.3", @@ -11478,7 +11486,6 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", - "dev": true, "license": "MIT", "engines": { "node": ">=8.6" @@ -11578,18 +11585,6 @@ "node": ">=16 || 14 >=14.17" } }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "license": "MIT", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/mnemonist": { "version": "0.38.3", "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.3.tgz", @@ -11791,17 +11786,6 @@ } } }, - "node_modules/next-intl/node_modules/@swc/helpers": { - "version": "0.5.23", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.23.tgz", - "integrity": "sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==", - "license": "Apache-2.0", - "optional": true, - "peer": true, - "dependencies": { - "tslib": "^2.8.0" - } - }, "node_modules/node-addon-api": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", @@ -12167,7 +12151,6 @@ "version": "2.3.2", "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, "hasInstallScript": true, "license": "MIT", "optional": true, @@ -12274,6 +12257,26 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, "node_modules/range-parser": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.3.0.tgz", @@ -12746,6 +12749,16 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, "node_modules/rfdc": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", @@ -12813,6 +12826,29 @@ "url": "https://opencollective.com/express" } }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -13485,7 +13521,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, "license": "MIT", "dependencies": { "is-number": "^7.0.0" @@ -14517,460 +14552,10 @@ } } }, - "node_modules/vitest/node_modules/@esbuild/aix-ppc64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz", - "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/android-arm": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz", - "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/android-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz", - "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/android-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz", - "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/darwin-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz", - "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/darwin-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz", - "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/freebsd-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz", - "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/freebsd-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz", - "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/linux-arm": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz", - "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/linux-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz", - "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/linux-ia32": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz", - "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/linux-loong64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz", - "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/linux-mips64el": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz", - "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/linux-ppc64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz", - "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/linux-riscv64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz", - "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/linux-s390x": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz", - "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/linux-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz", - "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/netbsd-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz", - "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/netbsd-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz", - "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/openbsd-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz", - "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/openbsd-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz", - "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/sunos-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz", - "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/win32-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz", - "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/win32-ia32": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz", - "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@esbuild/win32-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz", - "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/vitest/node_modules/@vitest/mocker": { - "version": "4.1.10", - "resolved": "https://registry.npmmirror.com/@vitest/mocker/-/mocker-4.1.10.tgz", - "integrity": "sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==", + "node_modules/vitest/node_modules/@vitest/mocker": { + "version": "4.1.10", + "resolved": "https://registry.npmmirror.com/@vitest/mocker/-/mocker-4.1.10.tgz", + "integrity": "sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==", "dev": true, "license": "MIT", "dependencies": { @@ -14994,50 +14579,6 @@ } } }, - "node_modules/vitest/node_modules/esbuild": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz", - "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "peer": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.28.1", - "@esbuild/android-arm": "0.28.1", - "@esbuild/android-arm64": "0.28.1", - "@esbuild/android-x64": "0.28.1", - "@esbuild/darwin-arm64": "0.28.1", - "@esbuild/darwin-x64": "0.28.1", - "@esbuild/freebsd-arm64": "0.28.1", - "@esbuild/freebsd-x64": "0.28.1", - "@esbuild/linux-arm": "0.28.1", - "@esbuild/linux-arm64": "0.28.1", - "@esbuild/linux-ia32": "0.28.1", - "@esbuild/linux-loong64": "0.28.1", - "@esbuild/linux-mips64el": "0.28.1", - "@esbuild/linux-ppc64": "0.28.1", - "@esbuild/linux-riscv64": "0.28.1", - "@esbuild/linux-s390x": "0.28.1", - "@esbuild/linux-x64": "0.28.1", - "@esbuild/netbsd-arm64": "0.28.1", - "@esbuild/netbsd-x64": "0.28.1", - "@esbuild/openbsd-arm64": "0.28.1", - "@esbuild/openbsd-x64": "0.28.1", - "@esbuild/openharmony-arm64": "0.28.1", - "@esbuild/sunos-x64": "0.28.1", - "@esbuild/win32-arm64": "0.28.1", - "@esbuild/win32-ia32": "0.28.1", - "@esbuild/win32-x64": "0.28.1" - } - }, "node_modules/vitest/node_modules/vite": { "version": "8.1.5", "resolved": "https://registry.npmmirror.com/vite/-/vite-8.1.5.tgz", diff --git a/package.json b/package.json index 1d86b29d..901242a2 100644 --- a/package.json +++ b/package.json @@ -117,6 +117,7 @@ "node": "^22.0.0" }, "overrides": { + "@node-minify/core": "10.5.0", "next": { "sharp": "0.35.2" }, From 7d2f1b229d6de8d38d1206801e118ced81d9de1c Mon Sep 17 00:00:00 2001 From: Pan YANG Date: Wed, 29 Jul 2026 00:30:22 +0800 Subject: [PATCH 5/8] fix(data): preserve Continue release version --- manifests/clis/continue-cli.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/manifests/clis/continue-cli.json b/manifests/clis/continue-cli.json index 6b643f9b..8abf3bdb 100644 --- a/manifests/clis/continue-cli.json +++ b/manifests/clis/continue-cli.json @@ -78,10 +78,6 @@ "vendor": "Continue Dev", "familyId": "continue", "latestVersion": "2.0.0", - "releaseTracking": { - "provider": "npm", - "identifier": "@continuedev/cli" - }, "githubUrl": "https://github.com/continuedev/continue", "license": "Apache-2.0", "pricing": [], From cd5a8d523ca8ea807a591b559dc73d94f482ec39 Mon Sep 17 00:00:00 2001 From: Pan YANG Date: Wed, 29 Jul 2026 00:30:31 +0800 Subject: [PATCH 6/8] chore(data): refresh health snapshot --- data/data-health.json | 2 +- docs/DATA-HEALTH.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/data/data-health.json b/data/data-health.json index 04df5675..534f249d 100644 --- a/data/data-health.json +++ b/data/data-health.json @@ -1,5 +1,5 @@ { - "asOf": "2026-07-28", + "asOf": "2026-07-29", "thresholds": { "models": 30, "providers": 30, diff --git a/docs/DATA-HEALTH.md b/docs/DATA-HEALTH.md index 9c82ec80..243cf0c4 100644 --- a/docs/DATA-HEALTH.md +++ b/docs/DATA-HEALTH.md @@ -1,6 +1,6 @@ # Data Health Report -Snapshot date: 2026-07-28. Regenerate with `npm run data-health:report`. +Snapshot date: 2026-07-29. Regenerate with `npm run data-health:report`. ## Scorecard From b049cf7c145e9c891833b8cd9a5405630a6aba05 Mon Sep 17 00:00:00 2001 From: Pan YANG Date: Wed, 29 Jul 2026 00:34:38 +0800 Subject: [PATCH 7/8] fix(ci): synchronize npm 10 lockfile --- package-lock.json | 506 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 506 insertions(+) diff --git a/package-lock.json b/package-lock.json index 09485b45..f118a38e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11786,6 +11786,17 @@ } } }, + "node_modules/next-intl/node_modules/@swc/helpers": { + "version": "0.5.23", + "resolved": "https://registry.npmmirror.com/@swc/helpers/-/helpers-0.5.23.tgz", + "integrity": "sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==", + "license": "Apache-2.0", + "optional": true, + "peer": true, + "dependencies": { + "tslib": "^2.8.0" + } + }, "node_modules/node-addon-api": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", @@ -12151,6 +12162,7 @@ "version": "2.3.2", "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, "hasInstallScript": true, "license": "MIT", "optional": true, @@ -14552,6 +14564,456 @@ } } }, + "node_modules/vitest/node_modules/@esbuild/aix-ppc64": { + "version": "0.28.1", + "resolved": "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz", + "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/android-arm": { + "version": "0.28.1", + "resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.28.1.tgz", + "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/android-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz", + "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/android-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.28.1.tgz", + "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/darwin-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz", + "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/darwin-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz", + "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/freebsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz", + "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/freebsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz", + "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-arm": { + "version": "0.28.1", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz", + "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz", + "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-ia32": { + "version": "0.28.1", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz", + "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-loong64": { + "version": "0.28.1", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz", + "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-mips64el": { + "version": "0.28.1", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz", + "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-ppc64": { + "version": "0.28.1", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz", + "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-riscv64": { + "version": "0.28.1", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz", + "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-s390x": { + "version": "0.28.1", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz", + "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz", + "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/netbsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz", + "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/netbsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz", + "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/openbsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz", + "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/openbsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz", + "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/sunos-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz", + "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/win32-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz", + "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/win32-ia32": { + "version": "0.28.1", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz", + "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/vitest/node_modules/@esbuild/win32-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz", + "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, "node_modules/vitest/node_modules/@vitest/mocker": { "version": "4.1.10", "resolved": "https://registry.npmmirror.com/@vitest/mocker/-/mocker-4.1.10.tgz", @@ -14579,6 +15041,50 @@ } } }, + "node_modules/vitest/node_modules/esbuild": { + "version": "0.28.1", + "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.28.1.tgz", + "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "peer": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.28.1", + "@esbuild/android-arm": "0.28.1", + "@esbuild/android-arm64": "0.28.1", + "@esbuild/android-x64": "0.28.1", + "@esbuild/darwin-arm64": "0.28.1", + "@esbuild/darwin-x64": "0.28.1", + "@esbuild/freebsd-arm64": "0.28.1", + "@esbuild/freebsd-x64": "0.28.1", + "@esbuild/linux-arm": "0.28.1", + "@esbuild/linux-arm64": "0.28.1", + "@esbuild/linux-ia32": "0.28.1", + "@esbuild/linux-loong64": "0.28.1", + "@esbuild/linux-mips64el": "0.28.1", + "@esbuild/linux-ppc64": "0.28.1", + "@esbuild/linux-riscv64": "0.28.1", + "@esbuild/linux-s390x": "0.28.1", + "@esbuild/linux-x64": "0.28.1", + "@esbuild/netbsd-arm64": "0.28.1", + "@esbuild/netbsd-x64": "0.28.1", + "@esbuild/openbsd-arm64": "0.28.1", + "@esbuild/openbsd-x64": "0.28.1", + "@esbuild/openharmony-arm64": "0.28.1", + "@esbuild/sunos-x64": "0.28.1", + "@esbuild/win32-arm64": "0.28.1", + "@esbuild/win32-ia32": "0.28.1", + "@esbuild/win32-x64": "0.28.1" + } + }, "node_modules/vitest/node_modules/vite": { "version": "8.1.5", "resolved": "https://registry.npmmirror.com/vite/-/vite-8.1.5.tgz", From 20f690b07b1be3c06c2b53c97a20ad812ba98e4e Mon Sep 17 00:00:00 2001 From: Pan YANG Date: Wed, 29 Jul 2026 00:46:40 +0800 Subject: [PATCH 8/8] fix(deps): restore OpenNext-compatible minifier --- package-lock.json | 137 ++++++++++++++++++++++++++++++++-------------- package.json | 2 +- 2 files changed, 98 insertions(+), 41 deletions(-) diff --git a/package-lock.json b/package-lock.json index f118a38e..e3b21873 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3763,46 +3763,6 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/@node-minify/core": { - "version": "10.5.0", - "resolved": "https://registry.npmmirror.com/@node-minify/core/-/core-10.5.0.tgz", - "integrity": "sha512-duptyliRQY+fXszqbm5CP+NauASUwkOlx/c4bwlT7tj5AQWhG9F26D3bfU/okKto9RDTGJy3cLwPvJC/j9lCkA==", - "license": "MIT", - "dependencies": { - "@node-minify/utils": "10.5.0" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@node-minify/core/node_modules/@node-minify/utils": { - "version": "10.5.0", - "resolved": "https://registry.npmmirror.com/@node-minify/utils/-/utils-10.5.0.tgz", - "integrity": "sha512-3DZEYgersSgia5V/cee35sw6B7TTZlcCKyAGiuhT274/r1obMEtHt1lRmyCd52uX5QlZqDOTrD4bqHCxKzIYLg==", - "license": "MIT", - "dependencies": { - "fast-glob": "^3.3.3", - "gzip-size": "7.0.0" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@node-minify/core/node_modules/gzip-size": { - "version": "7.0.0", - "resolved": "https://registry.npmmirror.com/gzip-size/-/gzip-size-7.0.0.tgz", - "integrity": "sha512-O1Ld7Dr+nqPnmGpdhzLmMTQ4vAsD+rHwMm1NLUmoUFFymBOMKxCCrtDxqdBRYXdeEPEi3SyoR4TizJLQrnKBNA==", - "license": "MIT", - "dependencies": { - "duplexer": "^0.1.2" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@node-minify/terser": { "version": "8.0.6", "resolved": "https://registry.npmjs.org/@node-minify/terser/-/terser-8.0.6.tgz", @@ -3894,6 +3854,32 @@ "next": ">=15.5.21 <16 || >=16.2.11" } }, + "node_modules/@opennextjs/aws/node_modules/@node-minify/core": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/@node-minify/core/-/core-8.0.5.tgz", + "integrity": "sha512-uiK27SlEWq4bGRWOprXMwCTEa+fuVQdLehHMTAwGtHeqvE3i6XjKpYLFI7/ecWiGbDzDB1Gcf1NCiVyiVXfajw==", + "license": "MIT", + "dependencies": { + "@node-minify/utils": "8.0.5", + "globby": "11.1.0", + "mkdirp": "1.0.4" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@opennextjs/aws/node_modules/@node-minify/utils": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/@node-minify/utils/-/utils-8.0.5.tgz", + "integrity": "sha512-hBetTLSmbXmNF11A11AkfYeTxhPt83HY2oNNIwGSkv7C9V/beHZ0HbqFOmfRBudCc1hpiKZcTshUk7hbG0/XIQ==", + "license": "MIT", + "dependencies": { + "gzip-size": "6.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/@opennextjs/cloudflare": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/@opennextjs/cloudflare/-/cloudflare-1.20.2.tgz", @@ -6696,6 +6682,15 @@ "integrity": "sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==", "license": "MIT" }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/assertion-error": { "version": "2.0.1", "resolved": "https://registry.npmmirror.com/assertion-error/-/assertion-error-2.0.1.tgz", @@ -7842,6 +7837,18 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/dotenv": { "version": "16.6.1", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", @@ -9052,6 +9059,26 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", @@ -11585,6 +11612,18 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/mnemonist": { "version": "0.38.3", "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.3.tgz", @@ -12089,6 +12128,15 @@ "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", "license": "MIT" }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/pathe": { "version": "2.0.3", "resolved": "https://registry.npmmirror.com/pathe/-/pathe-2.0.3.tgz", @@ -13115,6 +13163,15 @@ "node": ">= 10" } }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/slice-ansi": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", diff --git a/package.json b/package.json index 901242a2..70a9067c 100644 --- a/package.json +++ b/package.json @@ -117,7 +117,7 @@ "node": "^22.0.0" }, "overrides": { - "@node-minify/core": "10.5.0", + "@node-minify/core": "8.0.5", "next": { "sharp": "0.35.2" },