Skip to content

Sites and upstream

cfpuck-cms is the upstream. Each site is its own repository with cfpuck-cms as its upstream remote. Its history starts from the core’s, with a commit that swaps the example src/site/ for its own.

After cloning:

Terminal window
git remote rename origin upstream
git remote add origin git@github.com:<you>/my-site.git

Then make it your site:

  • Replace src/site/ with your own (see Site configuration).
  • Replace AGENTS.md with your site’s own notes, keeping its first line, @CORE.md, which brings in the core’s reference. The core’s AGENTS.md is about working on the core itself.
  • CORE.md documents the core and belongs to upstream: sites don’t edit it.

Merges stay clean as long as the site only changes:

  • src/site/
  • its own database migrations, db/migrations/*_site_*.sql (wrangler reads only that folder)
  • AGENTS.md, README.md
  • its env and its wrangler.jsonc (names and ids of its Worker, database, bucket and queue)
Terminal window
git fetch upstream
git merge upstream/main
npx wrangler d1 migrations apply DB --remote # if there are new migrations
npx tsx --env-file=.env scripts/migrate-content.ts # if stored content needs migrating

On a conflict, a site keeps its own AGENTS.md, README.md, .env.example and wrangler.jsonc.

Migrations (core and site) are named with the time they were written: YYYYMMDDHHMMSS_name.sql. wrangler d1 migrations apply applies every one not yet applied, in order, so a core migration written earlier than one a site already applied still goes in:

Terminal window
npx wrangler d1 migrations apply DB --remote # deployed
npx wrangler d1 migrations apply DB --local # local

A core bug found while working on a site can be fixed there: commit the fix on its own, touching core files only, then git cherry-pick it into cfpuck-cms.

  • Never import from src/site/ in core code except through src/lib/site (the CSS imports of the site’s styles/tokens.css and styles/theme.css in src/styles/site.css aside).
  • New core code must not hard-code a site’s types, URLs, names, palette names or classes. If a site needs something general (a filter, a map, a menu), build it as a core feature with settings and move the site onto it.