Working on the core
Keep the docs current
Section titled “Keep the docs current”Update the docs in the same commit as the change:
CORE.md: what the core does and where. Sites read it, so describe the core, never a particular site.AGENTS.md: how to work on the core.README.md: setting up a new site and taking core updates.docs-site/: this site.
Where things go
Section titled “Where things go”- Nothing site-specific in core code. Core code reads a site only through
src/lib/site. - Sites keep their own blocks, patterns and templates where those are their design; only general features belong in the core.
- The example site follows the same layout as every site and must keep working with every change.
- Styles use role tokens only, never a site’s palette names.
- Name code, data, URLs and classes for what they are here, not after another system’s names.
Adding a block
Section titled “Adding a block”- Renderer in
src/render/c/: a string of HTML withc-*classes, added tosrc/render/blocks/index.ts. - Data it needs: a
caseinwalk()insrc/render/prepare.ts. Load intoctx.data; add page scripts toctx.scripts/ctx.headScripts, vendor CSS throughctx.assets. - Editor: a panel in
CONTENT_PANELSand a label inCONTENT_LABELS(src/puck/panels.tsx), its category inbuildConfig(src/puck/config.tsx). Containers go inCONTENT_CONTAINERS. - Browser behaviour: a script in
public/assets/js/that enhances the server markup. - Styles in
src/styles/site.css, and a section inCORE.mdand these docs.
Changing stored content
Section titled “Changing stored content”Content changes the core needs (renamed props, moved settings) ship as a core content migration
(scripts/migrate-content.ts; migrateCollectionLayout in src/lib/content/collections.ts is one)
or a SQL migration that edits the JSON.
- Walk the JSON properly (PL/pgSQL or TypeScript). The key order of stored blocks varies, so text patterns miss some.
- Keep updated dates: disable the
*_touchtriggers around the update. - Name migrations with the time they are written (
YYYYMMDDHHMMSS_name.sql).
When a site migration switches block types or settings, the site’s code and its database change must
land together: push the code, wait for the deploy, then npx supabase db push --linked at once.
Workflow
Section titled “Workflow”- Change and commit in
supapuck-cms.npm run checkmust pass. - Test on the example site and, for anything real content exercises, in a site: merge the core change there without committing and test.
- Push
supapuck-cms(it deploys nothing), then in each sitegit fetch upstream && git merge upstream/mainand commit. The site’s owner pushes the site, which deploys it.
Checking changes
Section titled “Checking changes”- Render the affected pages before and after and diff the HTML (ignore cache-busting
?v=values and shuffled collections). Screenshot intended changes on desktop and phone. Lazy-loaded images need the page scrolled before a full-page screenshot. - Browser tests use Playwright from a script inside the project, signing in as
LOCAL_ADMIN_EMAIL/LOCAL_ADMIN_PASSWORD. POSTs to Astro need anOriginheader (CSRF check). The editor canvas isiframe#preview-frame; blocks that can’t be dragged report as disabled, so tests click them withforce. - Checks that need one site’s content live in that site’s
src/site/scripts/.