Components Seeds Pipeline (Phase 2 closed)
Clean local path for first-gen seeds and shipping them into Netlify Blobs. Runtime Export / Preview / regenerate never write seeds via Gemini; they only read Blobs.
Related:
- Components Cache Workflow — Gemini first-gen details
- Components API CDN PRD — Phase 2 closed
- Components Generation Prompting — seed vs regenerate prompts
Mental model
| Step | Where | Command |
|---|---|---|
| 1. Generate seed TSX | Local (public/components/code/) | publish:content → build:artifacts / build:components |
| 2. Upload seed to Blobs | Local → Netlify CLI → Blobs | publish:content → components:seeds:upload |
| 3. Runtime | Netlify Blobs | Export / Preview / Reimagine / Fix |
Default publish path: npm run publish:content runs generation and uploads new seeds (existing Blobs seeds are skipped). Use the standalone upload command only for targeted/ops recovery.
- Default upload uses Netlify CLI (
netlify login+netlify link) — same approach as meta enrich. - Seeds are immutable. Existing Blobs seeds are skipped (
seed_exists), not overwritten. - Regenerates (
vN) are click-only on/debugand do not replaceseed/v0. out/components/codeis stripped on publish. Do not rely on the live site serving TSX.
Prerequisites (once per machine)
netlify login
netlify link # selects the PATTTTERNS site; writes .netlify/state.json
Or set NETLIFY_AUTH_TOKEN + NETLIFY_SITE_ID.
One-liner recipes
Full publish (new patterns included)
# search → content/shell → artifacts → upload new seeds to Blobs
npm run publish:content
# then commit public/search-index.json, .notion-cache/, components/
New or rebuilt seed for one pattern
# 1) Gemini first-gen → public/components/code/<id>.tsx
npm run build:components -- --ids=<patternId> --force --promote=all
# 2) Ship into Blobs via Netlify CLI (no Supabase token)
npm run components:seeds:upload -- --ids=<patternId>
Full local cache → Blobs bootstrap
npm run build:components -- --force --promote=all # or use existing code/ files
npm run components:seeds:upload
Manifest only (no upload)
npm run components:seeds:manifest
npm run components:seeds:manifest -- --ids=<id[,id…]>
Dry-run upload plan
npm run components:seeds:upload -- --dry-run
npm run components:seeds:upload -- --ids=<id> --dry-run
Optional: upload via Components API instead
export COMPONENTS_MIGRATE_TOKEN=<supabase-access-token>
export COMPONENTS_API_BASE=https://patttterns.com/.netlify/functions/components-api
npm run components:seeds:upload -- --via-api --ids=<patternId>
npm scripts
| Script | What it does |
|---|---|
build:components | Gemini first-gen into public/components/code/ |
build:components:dry | Dry-run first-gen |
components:seeds:manifest | Write public/components/seeds-manifest.json |
components:seeds:upload | Manifest + write seeds to Blobs (Netlify CLI by default) |
components:seeds:enrich | Backfill title/slug/cover on existing Blobs meta (Netlify CLI) |
strip:components-out | Remove out/components/code + history after next build (also part of npm run build) |
Environment
| Var | Required | Purpose |
|---|---|---|
| Netlify CLI auth | Upload (default) | netlify login + netlify link, or NETLIFY_AUTH_TOKEN + NETLIFY_SITE_ID |
COMPONENTS_MIGRATE_TOKEN | Only with --via-api | Supabase access token for op=put-seed |
COMPONENTS_API_BASE | Only with --via-api | Function base URL |
COMPONENTS_SEEDS_BASE_URL | Optional / transitional | Function may still fetch /components/code/{id}.tsx when Blobs seed is missing |
GEMINI_API_KEY | First-gen only | build:components |
COMPONENTS_STRIP_OUT | Optional | Set 0 to skip publish strip (escape hatch) |
Upload behavior (Netlify CLI)
- Reads
public/components/code/*.tsx(optionally filtered by--ids=). - Attaches
title/slug/coverImagefrompublic/search-index.jsonwhen present. - Writes Blobs keys:
code/<id>/seed.tsxmeta/<id>.json(index with immutable seed version)
- Already has seed →
SKIP (seed_exists) - Created →
OK - Error →
FAIL; process exits non-zero if any fail
Replacing a bad seed
Not supported via API/CLI upload (immutable). Ops path:
- Rebuild local:
npm run build:components -- --ids=<id> --force --promote=all - Delete Blobs keys
meta/<id>.jsonandcode/<id>/seed.tsx(Netlify UI/CLI) - Re-upload:
npm run components:seeds:upload -- --ids=<id> - Hide or keep existing
vNregenerates as needed; set active back toseedif required
Phase 2 close checklist
- Production loads TSX from Components API (not published
out/TSX) - Postbuild strips
out/components/code+history - Local first-gen + Netlify CLI Blobs upload documented above
publish:contentuploads new seeds to Blobs (no extra step for brand-new patterns)- Ops: run a full (or filtered)
components:seeds:uploadagainst the linked prod site once for any seeds created before this wire-up
After that bootstrap upload (if needed), Phase 2 ops is complete. Ongoing: npm run publish:content covers generate + Blobs for new seeds.