Skip to main content

Overview

The catalog system manages the public-facing collection of entries. The dex catalog command provides tools for:
  • Manifest management: Add, edit, retire, and remove catalog entries
  • Staging: Preview changes before committing
  • Validation: Ensure linkage integrity and schema compliance
  • Publishing: Deploy catalog updates to test and production

Catalog File Structure

data/
├── catalog.editorial.json    # Local staging manifest
├── catalog.entries.json      # Full entry metadata
└── catalog.snapshot.json     # Published snapshot (auto-generated)

Manifest Operations

The manifest tracks which entries appear in the public catalog.

List Manifest Entries

View staged entries:
dex catalog manifest list
Output:
catalog:manifest staged=3 full=8 (use --all for full view)
entry-123    LOOKUP-0042    S2    active    /entry/tim-feeney/
entry-124    LOOKUP-0043    S2    draft     /entry/jane-doe/
entry-125    LOOKUP-0044    S1    archived  /entry/old-entry/
View all entries (including published snapshot):
dex catalog manifest list --all

Add Entry to Manifest

1

Resolve the entry

Add by slug, href, or ID:
dex catalog manifest add \
  --entry tim-feeney \
  --lookup LOOKUP-0042 \
  --season S2 \
  --instrument "Percussion" \
  --performer "Tim Feeney"
2

Verify linkage

Dex will validate that:
  • Entry page exists in entries/<slug>/
  • Entry has valid entry.json and index.html
  • Lookup number is unique
3

Review staged manifest

dex catalog manifest list
Dex auto-resolves entries from catalog.entries.json by slug, href, or ID. If metadata exists there, you only need --entry:
dex catalog manifest add --entry tim-feeney

Edit Manifest Entry

Update existing manifest metadata:
dex catalog manifest edit \
  --entry tim-feeney \
  --lookup LOOKUP-0099 \
  --status active
Supported fields:
  • --lookup: Lookup number
  • --season: Season identifier (e.g., S2)
  • --instrument: Primary instrument
  • --performer: Performer name
  • --status: draft, active, or archived
  • --title: Override title

Retire Entry

Mark an entry as archived (safe operation):
dex catalog manifest retire --entry tim-feeney
This sets status: "archived" without removing linkage.

Remove Entry

Destructive operation: This removes the entry from the manifest entirely.Dex blocks removal if the entry page still exists. Use retire instead, or force removal:
dex catalog manifest remove --entry tim-feeney --force-remove
Safe removal (fails if entry page exists):
dex catalog manifest remove --entry tim-feeney
Error if linked:
catalog manifest remove blocked: linked entry page exists.
Use `dex catalog manifest retire --entry ...` or pass --force-remove.

Staging Workflow

Stage from Catalog Entries

Quickly stage an entry from catalog.entries.json:
dex catalog stage --entry tim-feeney
This:
  1. Looks up metadata in catalog.entries.json
  2. Validates entry page linkage
  3. Adds to staged manifest with status active
Override metadata:
dex catalog stage --entry tim-feeney --lookup LOOKUP-0100 --status draft

Spotlight Management

Set the catalog spotlight (featured entry):
dex catalog spotlight set \
  --entry tim-feeney \
  --headline "ARTIST SPOTLIGHT" \
  --cta-label "VIEW COLLECTION" \
  --body "Tim Feeney" \
  --subhead "Percussion Solo"
If the entry exists in catalog.entries.json, Dex auto-populates defaults from entry metadata:
dex catalog spotlight set --entry tim-feeney

Validation

Validate the catalog before publishing:
dex catalog validate
Checks:
  • Schema compliance: All manifest rows match schema
  • Linkage integrity: All entries have valid page files
  • Spotlight consistency: Spotlight entry exists in manifest
  • Home featured cross-check: Featured entries exist in manifest
  • Snapshot generation: Creates local snapshot for comparison
Output:
catalog:validate passed (3 manifest rows).

Validation Errors

Warning:
catalog:validate warning spotlight entry entry-123 is not staged in manifest.
Solution: Add the spotlight entry to the manifest:
dex catalog manifest add --entry entry-123
Warning:
catalog:validate warning home featured entry missing from catalog manifest: entry-124
Solution: Either:
  1. Add the entry to the catalog manifest
  2. Remove it from home featured: dex home featured set --entries entry-123,entry-125
Error:
Error: Entry page does not exist: entries/tim-feeney/
Solution: Ensure the entry was created:
ls entries/tim-feeney/
dex entry audit --slug tim-feeney

Diff and Publishing

Compare Local vs Remote

Before publishing, check differences: Test environment:
dex catalog diff --env test
Output:
catalog:diff (test) local=a3f2d1b8 remote=b4e5c6f9
  manifest +2 -0 ~1
  spotlight changed=yes
Legend:
  • +2: 2 entries added
  • -0: 0 entries removed
  • ~1: 1 entry changed
Production environment:
dex catalog diff --env prod

Publish to Test

1

Validate locally

dex catalog validate
2

Review diff

dex catalog diff --env test
3

Publish

dex catalog publish --env test
Output:
catalog:publish (test) manifest=3 dryRun=no hash=a3f2d1b8 -> https://test-api.example.com

Publish to Production

Production publish requires admin token: Ensure DEX_CATALOG_ADMIN_TOKEN_PROD is set in your environment.
1

Validate locally

dex catalog validate
2

Diff against production

dex catalog diff --env prod
3

Dry run (recommended)

dex catalog publish --env prod --dry-run
4

Publish for real

dex catalog publish --env prod

Pull Remote Catalog

Pull the current remote catalog to local (overwrites catalog.editorial.json): From test:
dex catalog pull --env test
From production:
dex catalog pull --env prod
Output:
catalog:pull (test) wrote data/catalog.editorial.json -> https://test-api.example.com
This overwrites your local catalog.editorial.json. Commit or backup local changes first.

Season Management

Manage catalog seasons (groupings of entries):

List Seasons

dex catalog seasons list

Get Season Details

dex catalog seasons get --season S2

Set Season Metadata

dex catalog seasons set \
  --season S3 \
  --label "season 3 ('26-)" \
  --order 3

Season Teaser Mode

Hide unreleased entries with teasers: Enable teaser:
dex catalog seasons teaser enable --season S3
Configure teaser:
dex catalog seasons teaser set \
  --season S3 \
  --count 1 \
  --message "this artist has not been announced yet" \
  --tokens "???,!!!,***,@@@" \
  --style redacted
Disable teaser:
dex catalog seasons teaser disable --season S3

Custom API Endpoints

Override default API base and tokens:
dex catalog publish --env test \
  --api-base https://custom-api.example.com \
  --token my-custom-token

TUI Catalog Manager

For interactive management, use the dashboard:
dex
Select Catalog and use keybindings:
  • m: Toggle full/staged rows view
  • a: Stage manifest entry
  • s: Set spotlight
  • v: Validate + snapshot
  • d/f: Diff test/prod
  • p: Publish to test
  • o: Publish to prod (requires typed confirmation)
  • l/k: Pull test/prod
  • r: Reload
  • Esc: Back to dashboard

Troubleshooting

Error:
Publish/diff auth failures against Worker admin endpoints.
Solution:
  1. Confirm you’re using the correct env (test vs prod)
  2. Export the correct token:
    export DEX_CATALOG_ADMIN_TOKEN_TEST="your-test-token"
    export DEX_CATALOG_ADMIN_TOKEN_PROD="your-prod-token"
    
  3. Verify the secret exists in Worker environment (Wrangler)
Error:
catalog manifest entry not found: tim-feeney
Solution: The entry doesn’t exist in the staged manifest. Add it first:
dex catalog manifest add --entry tim-feeney
Error:
catalog manifest patch requires resolvable entry_id.
Solution: Provide a valid entry identifier:
dex catalog manifest add --entry tim-feeney --entry-id entry-123
Or ensure the entry exists in catalog.entries.json.

Best Practices

Always Validate First

Run dex catalog validate before every publish operation

Use Dry Run

Test with --dry-run before publishing to production

Diff Before Publish

Always run dex catalog diff --env prod to review changes

Retire vs Remove

Prefer retire over remove to preserve historical linkage

Next Steps

Build docs developers (and LLMs) love