How to Refresh the Model Metadata Catalog in Apache Maka

Use npm run sync:model-metadata -- --refresh to fetch the latest models.dev API data, validate it against shrinkage rules, and regenerate the TypeScript catalog files atomically.

The Apache Maka project maintains a synchronized catalog of AI model metadata to ensure accurate provider information and pricing data across its core and runtime packages. This catalog lives in packages/core/src/model-metadata.generated.ts and is derived from the public models.dev API. Refreshing this catalog requires executing a specialized synchronization script that handles data projection, validation, and atomic file replacement.

Understanding the Model Metadata Architecture

Maka's catalog system relies on a snapshot-based workflow that bridges upstream API changes with version-controlled TypeScript source files. The scripts/sync-model-metadata.mjs driver orchestrates the entire pipeline, converting raw JSON from models.dev into four internal data structures: metadata, pricing, providerFacts, and providerOverrides.

The generated outputs include:

Executing a Standard Refresh

To update the catalog with the latest live upstream data, run the npm script with the refresh flag. This invokes the main() function in scripts/sync-model-metadata.mjs, which fetches data from the SOURCE_URL, projects it into internal maps, and writes new snapshot and TypeScript files.

npm run sync:model-metadata -- --refresh

This command executes six distinct phases: fetching upstream data via readUpstream(), projecting raw JSON through buildProjection(), validating against shrinkage with assertProjectionDoesNotShrink(), digesting the snapshot with SHA-256, generating TypeScript modules, and performing atomic file replacement via replaceFilesTransactionally().

Handling Edge Cases and Variations

Refreshing from a Local File

When testing changes or working offline, bypass the live API by providing a local JSON file that mimics the models.dev response structure using the --refresh-input flag.

npm run sync:model-metadata -- \
  --refresh \
  --refresh-input path/to/local/models-dev.json

Accepting Upstream Removals

By default, the refresh fails if any provider or model present in the previous snapshot disappears from the new data. This shrinkage protection prevents accidental data loss. To deliberately remove discontinued providers, pass the --accept-upstream-removals flag:

npm run sync:model-metadata -- \
  --refresh \
  --accept-upstream-removals

The validation logic checks if (!options.acceptUpstreamRemovals) before calling assertProjectionDoesNotShrink() against the previous projection loaded via loadSnapshotIfPresent().

Verification Without Writing

Use the --check flag to validate that existing generated files match the committed snapshot without fetching new data or writing files. This is ideal for CI pipelines ensuring repository consistency.

npm run sync:model-metadata -- --check

Alternatively, use --drift to report differences without failing or writing:

const report = await main(['node', 'sync-model-metadata.mjs', '--drift']);

Programmatic Integration

Import the main function directly from scripts/sync-model-metadata.mjs to refresh catalogs within Node.js applications or test suites.

import { main } from './scripts/sync-model-metadata.mjs';

// Full refresh with writes
await main(['node', 'sync-model-metadata.mjs', '--refresh']);

// Read-only drift detection
const driftReport = await main(['node', 'sync-model-metadata.mjs', '--drift']);

Critical Implementation Files

Understanding these source files helps debug refresh failures or extend functionality:

Summary

  • Refresh the model metadata catalog by running npm run sync:model-metadata -- --refresh to fetch models.dev data and regenerate TypeScript sources
  • Prevent data loss through default shrinkage protection that rejects removals unless --accept-upstream-removals is specified
  • Test locally using --refresh-input with a local JSON file to avoid hitting the live API
  • Validate consistency via --check for CI workflows or --drift for reporting
  • Atomic writes ensure packages/core/src/model-metadata.generated.ts and related files are never partially updated

Frequently Asked Questions

Why does my refresh fail with a shrinkage error?

The refresh aborts when providers or models from the previous snapshot are missing in the new upstream data. This prevents accidental deletion of metadata. Run with --accept-upstream-removals only if you intentionally want to remove discontinued models from the catalog.

Can I refresh the catalog without internet access?

Yes. Save a local copy of the models.dev API response as JSON, then run npm run sync:model-metadata -- --refresh --refresh-input ./local-file.json. The script reads from this path instead of fetching SOURCE_URL, making it suitable for air-gapped environments or reproducible CI builds.

How do I verify the generated files match the repository state?

Execute npm run sync:model-metadata -- --check. This compares the current snapshot against the generated TypeScript files without fetching new data or writing to disk, returning a non-zero exit code if they differ. This ensures the committed generated files are synchronized with the snapshot.

What happens if the refresh is interrupted mid-process?

The replaceFilesTransactionally() function stages temporary copies and only swaps them after all writes succeed. If the process crashes during generation, the original model-metadata.generated.ts and snapshot files remain intact, preventing corruption or half-written states.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →