Site Editor Bake & Sync (rig:bake)

Site Editor work — custom templates, template parts, user-created patterns, Global Styles, Font Library activations — lives in the WordPress database, not in your repo. Without a round-trip, that work is invisible to git, unreviewable, and lost when the site dies. rig:bake (shipped in WP Rig 3.5) closes the loop: it bakes database state into version-controlled theme files, then verifies and scrubs the database records.

Availability & requirements

  • Paradigm: active for universal and block-based themes — classic themes refuse with guidance (exit 1).
  • Requirements: Node 18+, WP-CLI 2.12+, writable active block theme.
  • Origin: a Node port of bacoords/wp-theme-control by Brian Coords, pinned to an upstream SHA, with WP Rig-specific forks.

Commands

npm run rig:bake            # all scopes: fonts → templates → styles → patterns
npm run rig:bake:plan       # read-only inventory + collision report
npm run rig:bake:clean -- .wp-theme-control/runs/<run>/manifest.tsv
npm run rig:bake -- <scope> [flags]   # one scope + upstream flags passthrough
ScopeWrites
planNothing — inventory, collisions, “nothing to bake” report.
patternspatterns/<slug>.php from published unsynced wp_block posts.
templatestemplates/*.html, parts/*.html — runtime-URL content patternizes to patterns/hidden-*.php with Inserter: no.
fontsassets/fonts/<slug>/ + the overlay’s fonts block.
stylesThe overlay’s settings/styles blocks (raw user Global Styles).
cleanDeletes only DB records whose exported files still match the manifest sha256; also removes the overlay.

Passthrough flags: --path=, --url=, --user=, --state-dir=, --dry-run, --clean, --force.

What ships where

ArtifactPathGit
Baked patternspatterns/*.php, patterns/hidden-*.phptracked
Baked templates/partstemplates/*.html, parts/*.htmltracked
Baked font filesassets/fonts/<slug>/**tracked
Global Styles overlayconfig/user-styles.jsontracked
Generated theme.jsontheme.jsongitignored — tokens.js is the sole writer
Run manifests/backups.wp-theme-control/**gitignored

The safety model

Every write appends kind / record_id / slug / target / sha256 to a per-run manifest under .wp-theme-control/runs/ (gitignored), with backups per run. Cleanup is conservative by design: rig:bake:clean deletes only records whose exported files still match the manifest hash, only for the expected post type, and only while the pattern is still unsynced or the Global Styles post is unchanged. --force bypasses the hash check only. Each baked pattern file carries an idempotent Baked: yes header so lint tooling can recognize it.

Runtime URLs

Content that references local absolute URLs (your dev site’s uploads, theme assets) is rewritten in PHP — via wp eval, so WordPress’ own parse_blocks() semantics stay byte-identical — to the three sanctioned runtime expressions: get_stylesheet_directory_uri(), wp_get_upload_dir()['baseurl'], and home_url(). Anything else containing PHP syntax is refused.

The user-styles overlay (SPEC-016)

Baked Global Styles and font activations never write theme.json directly — rig:tokens is the sole theme.json writer and would clobber them. Instead they land in config/user-styles.json, a git-tracked overlay that the tokens generator merges last:

  • Objects deep-merge; arrays replace wholesale.
  • Fonts collapse — custom definitions win on duplicate slugs.
  • SSOT keys (version, $schema, settings.viewport, settings.blockVisibility, isGlobalStylesUserThemeJSON) never merge.
  • Regeneration is deterministic: two rig:tokens runs after a bake are byte-identical.
  • The PHP runtime is overlay-blind — it is a build-time input only, guarded by a PHPUnit parity test.

The usage loop

git status                        # must be clean — a bake is reviewed as a diff
npm run rig:bake:plan             # inventory + collisions (writes nothing)
npm run rig:bake                  # writes files; does NOT clean the DB
npm run lint:patterns && npm run lint:blocks && npm run lint:css
git add -p && git commit          # review the diff
npm run rig:bake:clean -- .wp-theme-control/runs/<run>/manifest.tsv

The bake is a review-first workflow: nothing leaves the database until you have read the diff and committed it.

Lint integration for baked files

Patterns marked Baked: yes keep their Title/Slug/Categories and markup-validity checks but get a tolerance profile: scaffold-placeholder content downgrades to a warning, and hidden runtime patterns get a Categories warning. The three sanctioned runtime-URL PHP expressions are neutralized in block-comment attributes — any other PHP still fails lint:patterns.

Known boundaries

  • Synced patterns are not migrated; distribution packaging, localization, Media Library moves, and remote SSH targets are upstream boundaries, inherited.
  • The overlay never carries PHP expressions — local absolute URLs in captured styles are flagged (report-only), and media belongs in block markup instead.
  • Baked font families replace the token-derived fontFamilies list in editor presets (the user layer wins) — see Font Management.
  • Font asset files survive clean for recoverability; the overlay is removed with the styles/fonts clean.

Pair this with Design Tokens v2 (the merge contract), Font Management (the fonts boundary), and Theme Paradigms (why this is gated to block-capable themes).

Doc Categories:

The rig CLI: Complete Command Reference

Every WP Rig workflow runs through npm/Bun scripts (plus a few Composer and WP-CLI commands). This is the canonical command reference — the same list lives in the repo at docs/commands.md, and npm run with no arguments lists everything available in your checkout.

Development & build

CommandPurpose
npm run devWatch source files and rebuild on changes (all-in-one dev loop with live reload).
npm run dev:modernVite-like dev server without BrowserSync (opt-in).
npm run buildOne-time build of source files without watching.
npm run build:css / build:jsBuild only CSS (Lightning CSS) or JS/TS (esbuild).
npm run build:blocksBuild all blocks in assets/blocks/.
npm run bundleProduction-ready theme: minified assets, string replacement, translations, WebP + AVIF images.
npm run bundle:wporgProduction bundle prepped for WordPress.org submission.

Initialization & setup

CommandPurpose
npm run rig-initInstall dependencies and run the interactive theme initializer (paradigm choice, dev URL, etc.).
npm run rig-init:bunSame, with bun install.
npm run setup-childrig-init + childify in one command (paradigm-aware child themes).
npm run block-basedConvert the theme toward a strictly block-based (FSE) setup.
npm run theme:enable-blocksEnable block compilation (enableBlocks: true).
npm run generateCertGenerate local SSL certificates.
npm run get-dev-urlPrint the resolved dev URL.

Quality & linting

CommandPurpose
npm run lint:jsESLint on assets/js/src/**.
npm run lint:cssStylelint with the WP Rig budget: nesting ≤ 3 levels, specificity ≤ (0,4,1), no !important, var()-required custom properties, no descending specificity. Also regenerates tokens first.
npm run fix:cssAuto-fix stylelint violations.
npm run lint:blocksValidate block markup in templates/ + parts/ against live core block schemas.
npm run lint:patternsValidate block patterns (metadata + markup) in patterns/ and component patterns/ dirs.
npm run ai:checkFull pre-flight gate: e2e + screenshots + all linters. Run before submitting work.

Design tokens

CommandPurpose
npm run rig:tokensRegenerate CSS variables + theme.json (+ Tailwind when enabled) from config/tokens.json. Merges any baked overlay last.
npm run rig:tokens:setupOne-time v1→v2 token upgrade + legacy-name codemod. Dry-run by default; --apply writes (with backups).
npm run rig:tokens:importImport a W3C DTCG / Figma (Tokens Studio) JSON. Dry-run by default.
npm run rig:tokens:exportExport tokens.json to a DTCG document for Figma round-trips.

See Design Tokens v2 for the full system.

WordPress blocks

CommandPurpose
npm run block:new <slug>Scaffold a block (apiVersion: 3). Flags: --title, -d/--dynamic, --ts, --php (PHP-only block), --category, --icon, --description, --keywords, --no-style, --no-editor-style, --view.
npm run block:new:dynamicShortcut for a dynamic (render.php) block.
npm run block:list / block:removeList or remove theme blocks.
npm run block:promote-pluginPromote a theme block into a plugin.
npm run block:schemaFetch active core block schemas from your local site (WP-CLI bridge).
npm run block:compileCompile a block IR payload to Gutenberg markup via the WP-CLI bridge.

Component registry

CommandPurpose
npm run rig:listList installed components (bundled vs registry) with versions.
npm run rig:search [keyword]Discover community components.
npm run rig:add [slug] / rig:remove [slug]Install or remove a component (assets, AI context, manifest entry — no orphans).
npm run rig:update [slug]Pull framework-level component updates, preserving local customizations.
npm run rig:test-component [slug]Pre-flight check before sharing (manifest, files, security).
npm run rig:prepare [slug]Package a component for submission via GitHub PR.
npm run rig:compareCompare installed components against registry versions.
npm run create-rig-component "Name"Scaffold a new theme component (registry-ready files included).

Full lifecycle docs: The Open Component Registry.

Site Editor bake & sync

CommandPurpose
npm run rig:bakeBake Site Editor DB changes (patterns, templates/parts, fonts, Global Styles) into theme files.
npm run rig:bake:planRead-only inventory + collision report. Run before every bake.
npm run rig:bake:cleanDelete only DB records whose exported files match the manifest sha256; removes the overlay.

Full workflow docs: Site Editor Bake & Sync.

Patterns, testing, audits

  • npm run rig:pattern — scaffold a block pattern with i18n-aware headers + config-seeded categories.
  • npm run rig:localize — generate the .pot translation file in languages/.
  • npm run test:e2e — full Playwright suite (chromium + firefox + webkit).
  • npm run test:e2e:spatial — spatial & visual regression (deterministic geometry checks).
  • npm run test:e2e:screenshot — capture/update regression screenshots.
  • npm run test:scripts — Jest unit tests for build tooling.
  • npm run test:prod-build — full production-bundle verification.
  • npm run audit:theme-review (and the other audit:* commands) — WordPress.org-style theme review checks.

Composer & WP-CLI

  • Testing: composer test:unit, test:integration, test:all (unit + integration + PHPStan).
  • Quality: composer phpstan, composer phpcs-dev, composer fix (Rector + PHP-CS-Fixer + PHPCBF).
  • Environment: composer setup-wp-tests, composer install-codestandards.
  • WP-CLI: wp rig test-setup and wp rig import-test-data set up the Theme Unit Test environment.
Doc Categories:

The Open Component Registry (OCR)

The Open Component Registry (OCR, shipped in WP Rig v3.4) is a federated ecosystem for sharing performant, agent-ready theme components. Instead of copy-pasting feature code between projects, you search a registry of verified components, add them with one command, and pull framework-level updates later without losing your customizations.

Why a component registry

Every registry component ships with more than code: a manifest.json declaring its assets and paradigm, a SPEC.md with its technical contract, and a SKILL.md with implementation recipes. That makes components both performance-verified (scored, with conditional asset loading) and agent-ready (AI tools can read the same docs you do).

The component lifecycle

CommandWhat it does
npm run rig:listList installed components (bundled vs registry) with versions and status.
npm run rig:search [keyword]Discover community components; inspect performance ratings and Agent-Ready flags.
npm run rig:add [slug]Install a component: PHP into inc/, assets into the build pipeline, AI context linked into .ai/skills/, registration in inc/components-manifest.json.
npm run rig:update [slug]Pull framework-level updates via a diff-based merge that preserves your local edits.
npm run rig:remove [slug]Remove a component and clean up files, assets, and the manifest entry — no orphans.
npm run rig:test-component [slug]Pre-flight validation (manifest, files, security, namespaces) before sharing.
npm run rig:prepare [slug]Package a component and get instructions for submitting it via GitHub pull request.
npm run rig:check [slug]Lightweight structure/manifest audit.
npm run rig:compareCompare installed components against current registry versions.

Adding your first component

Before building a feature from scratch, check whether a verified component already exists:

npm run rig:search related-posts
npm run rig:add related-posts

When choosing, prefer components with a performance score of 95+ and the Agent-Ready badge (meaning SPEC.md and SKILL.md ship with the component). After adding, the component docs land in .ai/skills/ — read them (or let your AI assistant read them) before wiring the component into templates.

The manifest and scoped assets

Manifest v2 requires a paradigm field matching the component PARADIGM constant, and supports scoped assets: an asset_mapping entry marked scoped: true is compiled into the theme pipeline but enqueued conditionally by the component own PHP — a block component never adds global CSS to pages that do not use it. Components build through the same Bun/Lightning/esbuild pipeline as core theme assets: no extra HTTP requests, no separate build config.

Paradigm-aware components

A component that serves only one theme-dev paradigm declares it and uses the trait — the theme class skips inactive components automatically during discovery:

// inc/My_Feature/Component.php
class Component implements Component_Interface {
	use Paradigm_Component_Trait;

	const PARADIGM = 'block-based';

	public static function is_active(): bool {
		return self::paradigm_active();
	}
}

Bundled patterns/ directories inside a component are registered by the inc/Block_Patterns component in block-capable themes.

Contributing a component

  • Scaffold the structure: npm run create-rig-component "My Feature" --templating --tests — it generates Component.php, manifest.json, SPEC.md, and SKILL.md registry-ready by default.
  • Implement the feature and keep everything inside the component directory under inc/.
  • Validate locally: npm run rig:test-component my-feature.
  • Package and submit: npm run rig:prepare my-feature — it produces exactly what the GitHub PR needs.

Updates are “starter” semantics: after rig:add, the code is yours to modify. rig:update later pulls upstream fixes with a diff-based merge, preserving local customizations.

Private and team registries

The registry is federated: organizations can point a theme at their own GitHub-backed registry (via the inc/Registry_Config component) to serve a private set of curated components alongside the public one — useful for agencies maintaining vetted in-house features.

See Theme Paradigms for the gating model, Building Custom Blocks for block components, and WP Rig Node Scripts for the full rig:* command reference.

Doc Categories: