Status: ✅ Complete Updated: January 6, 2026
This document summarizes the schema refactoring work done to improve the design of manifest JSON schemas, following DRY (Don't Repeat Yourself) principles and ensuring proper inheritance relationships.
Problem: collections.schema.json was redefining its own translations structure instead of reusing the standard translations.schema.json.
Solution:
- Made
translations.schema.jsonmore flexible by removing therequiredconstraint ondescription - Updated
collections.schema.jsonto reference./ref/translations.schema.jsoninstead of inline definitions - Both
collectionCardandcollectionItemnow use the standard i18n schema
Problem: The pricing field had different meanings:
- In
product.schema.json: Array of pricing tiers (for products) - In
models.schema.json: Object with token pricing (input/output/cache)
Solution:
- Renamed
pricingtotokenPricinginmodels.schema.json - Updated all references in
models.jsondata file - Updated React components that display model pricing (
models/[slug]/page.tsx,models/page.tsx)
Problem: entity.schema.json used additionalProperties: true while other schemas used unevaluatedProperties: false, creating inconsistency.
Solution:
- Removed
additionalProperties: truefromentity.schema.json - All schemas now consistently use
unevaluatedProperties: falseat the top level
Problem: Multiple schemas were duplicating field definitions:
githubStars,githubUrlrepeated across schemaslatestVersionduplicated in multiple places
Solution:
-
Created new
vendor-entity.schema.jsonas an intermediate schema- Extends
entity.schema.json - Adds:
vendor(only field at this level) - Only
vendoris required
- Extends
-
Moved product-specific fields to appropriate schemas:
product.schema.jsondefines:latestVersion,githubUrl,githubStars(all required, nullable where applicable)models.schema.jsondefines its own:latestVersion,githubUrl,githubStars(all nullable, not required)providers.schema.jsondefines its own:latestVersion(nullable),githubUrl,githubStars(nullable but required)
-
Updated schema hierarchy:
entity.schema.json └── vendor-entity.schema.json ├── product.schema.json │ ├── app.schema.json │ │ ├── clis.schema.json │ │ ├── ides.schema.json │ │ └── terminals.schema.json │ └── extensions.schema.json ├── models.schema.json ├── providers.schema.json -
Each schema now only defines fields specific to its type
-
MCPs require
githubUrlandgithubStars(since all integration servers should be open source) -
Providers require
githubUrlandgithubStarsbut allow null values -
Products (CLIs/IDEs/Terminals) require
latestVersionviaproduct.schema.json -
Models and providers override
latestVersionto be nullable (versions are less applicable)
Problem: relatedProducts was defined in $defs but never used in properties.
Solution:
- Added
relatedProductstoproduct.schema.jsonproperties - Added
relatedProductstoapp.schema.jsonfor proper inheritance withunevaluatedProperties - Migrated IDE
clifield torelatedProductsstructure- vscode:
cli: "code"→relatedProducts: [{"type": "cli", "productId": "code"}] - cursor:
cli: "cursor-agent"→relatedProducts: [{"type": "cli", "productId": "cursor-agent"}] - droid:
cli: "factory"→relatedProducts: [{"type": "cli", "productId": "factory"}] - zed:
cli: "zed"→relatedProducts: [{"type": "cli", "productId": "zed"}] - intellij-idea:
cli: "idea"→relatedProducts: [{"type": "cli", "productId": "idea"}]
- vscode:
- Removed standalone
clifield fromapp.schema.json - Added empty
relatedProducts: []to all products without related products
Problem: clis.schema.json and ides.schema.json directly inherited product.schema.json, missing the platforms field that applications need.
Solution:
- Updated
clis.schema.jsonandides.schema.jsonto inherit fromapp.schema.jsoninstead - Added top-level
installCommandandlaunchCommandas optional fields (legacy support, prefer platform-specific values) - Added
relatedProductssupport toapp.schema.json
Note: The validation tests in tests/validate/ load vendor-entity.schema.json in the correct order (after entity, before product)
- Reduced Duplication: Field definitions are now centralized in base schemas
- Improved Maintainability: Changes to common fields only need to be made once
- Better Type Safety: More consistent validation rules across all manifests
- Clearer Semantics: Field names now accurately reflect their purpose (e.g.,
tokenPricingvspricing) - Flexible Inheritance: Schemas can override inherited fields when needed (e.g., MCPs making GitHub fields required)
All manifest files now pass validation:
- ✅ clis.json (18 items)
- ✅ ides.json (11 items)
- ✅ terminals.json (8 items)
- ✅ extensions.json (10 items)
- ✅ providers.json (5 items)
- ✅ models.json (5 items)
- ✅ collections.json
- ✅ vendors.json (11 items)
manifests/$schemas/ref/entity.schema.jsonmanifests/$schemas/ref/vendor-entity.schema.json(NEW)manifests/$schemas/ref/product.schema.jsonmanifests/$schemas/ref/app.schema.jsonmanifests/$schemas/ref/translations.schema.jsonmanifests/$schemas/clis.schema.jsonmanifests/$schemas/ides.schema.jsonmanifests/$schemas/models.schema.jsonmanifests/$schemas/providers.schema.jsonmanifests/$schemas/collections.schema.json
manifests/models.json(renamedpricing→tokenPricing)manifests/providers.json(addedgithubUrlandgithubStars)manifests/ides.json(migratedcli→relatedProducts, addedgithubUrl)manifests/clis.json(addedrelatedProducts: [], addedgithubUrl)manifests/terminals.json(addedrelatedProducts: [], addedgithubUrl)manifests/extensions.json(addedrelatedProducts: [], addedgithubUrl)
src/app/[locale]models/[slug]/page.tsxsrc/app/[locale]models/page.tsx
- Consistent Naming: Always use descriptive field names that reflect the specific use case
- Schema Composition: Prefer composition over duplication - create reusable schema fragments
- Documentation: Keep this summary updated when making future schema changes
- Validation: Always run
pnpm test:validatebefore committing schema changes