Push / Pull Guide
How workspace data flows to the registry and back. Understanding this model is the key to debugging sync issues.
Data flow
Figma
↓ handoff-app fetch
Workspace: public/api/tokens/{color,typography,effect}.json
↓ scripts/tokens-to-dtcg.js (Phase 0 — DTCG conversion)
Workspace: design-system/tokens/{primitive,semantic}/*.tokens.json
↓ scripts/tokens-transform.js (Phase 1 — Style Dictionary)
Workspace: design-system/dist/{css,scss,tailwind,dtcg}/
↓ handoff-app push:all
Registry API (HTTP POST to /api/registry/*)
↓ stored in Postgres
Registry pages (read via DynamicDataProvider)Workspace
A client project repo (e.g. handlebars-registry-next/handoff/). Contains component source files, page markdown, handoff.config.js, and the DTCG token pipeline. The workspace never deploys itself — it uses handoff-app as a CLI tool.
Registry
A clean, standalone deployment of the handoff-app Next.js server (e.g. on Vercel). Contains no client-specific data at deploy time. All tenant data arrives via push:all and is stored in Postgres.
push:all in detail
handoff-app push:all calls these endpoints in sequence. Each uses a Bearer token obtained via handoff-app login.
POST /api/registry/configClient identity, Figma project key, attribution settings
← handoff.config.js app block
POST /api/registry/themeCustom CSS overrides for the registry UI
← theme.css
POST /api/registry/navigationPage tree and sidebar structure
← pages/ directory tree
POST /api/registry/pagesAll markdown content with frontmatter
← pages/**/*.md
POST /api/registry/tokensRaw Figma token snapshot
← public/api/tokens.json
POST /api/registry/dtcgDTCG manifest and compiled CSS/SCSS/Tailwind/JSON
← design-system/manifest.json + dist/
POST /api/registry/iconsIcon catalog — flat array of IconCatalogEntry objects
← icons/catalog.json
POST /api/registry/logosLogo set with variants and inline SVG content
← logos/logo-set.json
Component sync (push / pull)
push sends individual component files via POST /api/sync/upload. Each upload includes declaration metadata, build artifacts (Vite dist), source files (.tsx, .css), and screenshots. Unchanged files are skipped based on a content hash.
pull calls GET /api/sync/changes and writes the changeset back to the workspace — updated pages, component declarations, build artifacts, and source files.
Common issues
500 on push (relation does not exist)
The DB migration hasn't run yet. Trigger a new Vercel deploy or call /setup to force migration.
Icons push skips with "must be a JSON array"
icons/catalog.json must be a flat array of IconCatalogEntry objects — not wrapped in an object.
413 FUNCTION_PAYLOAD_TOO_LARGE
DTCG payload is too large for one request. Check that design-system/dist/ isn't including source maps or vendor files.
push:all succeeds but icons/logos still show "No data"
Check Vercel function logs for auto-migrate errors. If migration 0012 isn't in the journal, it won't run.