shopify-theme-harness
v0.1.4
Published
Installable CLI overlay for fixed-path Shopify theme harness workflows.
Readme
Shopify Theme Harness Starter
AI-native starter scaffold for restoring Shopify theme pages from Figma bundle inputs.
Goal
Make the harness reusable across theme projects:
- the harness owns workflow, contracts, inspect, verify, and starter generation
- each project swaps in different Figma bundle inputs
- the repository does not depend on designer naming discipline beyond the exported bundle contract
Architecture Overview
This repository is a harness source repo, not a finished Shopify theme.
The intended mental model has three layers:
figma/*This is the input contract. Eachfigma/<page-key>bundle is an exported page or shared surface coming from Figma.starter/theme/*This is the generated harness workspace. It is where the harness writes starter section stubs, delivery templates, review manifests, runtime capture plans, and the machine-readable agent files used to implement and verify a page.Real Shopify theme files These are the actual delivery files in a real theme project such as
sections/*,templates/*,snippets/*,assets/*, and runtime previews served by Shopify. The harness helps generate and verify work for those files, but it is not itself the final theme.
If a developer initializes the harness into a project and sees starter/theme/*, the important point is:
- it is not just cache
- it is not the final theme
- it is the generated working surface that makes the restore loop deterministic and inspectable
The harness is designed so agents and humans can work from files instead of chat memory:
figma/*tells the harness what should existstarter/theme/*tells agents what to build, assemble, verify, and hand off- the real theme files are where the final implementation lands
One-Shot Page Generation Model
The target workflow is “generate one full page from one Figma bundle with explicit verification”.
At a high level:
- Put a bundle under
figma/<page-key>/... - Compile the harness to generate starter outputs under
starter/theme/* - Use the generated section tasks to implement each section
- Return one
section-resultper section, includingtemplateContribution - Assemble those section results into a full delivery template and a shared preview template
- Run browser preview verification and write
page.<page-key>.preview.json - Aggregate section results plus preview evidence into final page verification
That means the harness is trying to answer one question in files:
Given a Figma bundle, can we deterministically produce a full page surface, preview it, and prove what is still missing?
Core Model
The harness treats each exported Figma page bundle as a standard input slot:
figma/<page-key>/page.jsonfigma/<page-key>/sections/*.jsonfigma/<page-key>/previews/*.png
For Kik-initialized projects, page.json may also declare designSystem metadata. That metadata is expected to stay in parity with the current project token source recorded in harness/config/kik-token-source.json.
The starter then provides a generic loop:
- inspect bundle coverage
- verify bundle contract
- compile starter theme stubs
- review generated section, template, and agent-task outputs
- plug the starter into a real Shopify theme project for final runtime capture and iteration
What starter/theme/ Is For
starter/theme/ exists so the harness has a stable place to write generated artifacts before they become final theme code.
It contains four kinds of things:
- starter implementation surfaces
Generated section stubs and delivery templates such as
sections/generated-*.liquidandtemplates/page.*.json - agent orchestration files
page.*.task.json,sections/*.task.json, dispatch files, run summaries, preview summaries, and final verification summaries - review and acceptance metadata Review manifests, capture plans, and runtime profile files
- restore-loop integration files Runtime capture expectations and theme-project binding files
So when a developer asks “why is the harness writing into starter/theme/ instead of straight into my theme?”, the answer is:
- because this directory is the harness-owned staging and orchestration layer
- it keeps generated output deterministic and reviewable
- it gives agents a stable handoff surface
- it lets the real theme stay project-owned while the harness stays generic
Commands
make inspect-harnessmake inspect-runtimemake sync-runtime-capturesmake verify-harnessmake verify-runtimemake compile-startermake test
CLI overlay commands:
node ./bin/shopify-theme-harness init <target-dir>node ./bin/shopify-theme-harness init-kik --project-root <dir> --store <domain> [--variables-table-html <path>]node ./bin/shopify-theme-harness upgrade --project-root <dir>node ./bin/shopify-theme-harness status --project-root <dir>node ./bin/shopify-theme-harness inspect-harness --project-root <dir>node ./bin/shopify-theme-harness inspect-runtime --project-root <dir>node ./bin/shopify-theme-harness compile-starter --project-root <dir>node ./bin/shopify-theme-harness sync-runtime-captures --project-root <dir>node ./bin/shopify-theme-harness verify-harness --project-root <dir>node ./bin/shopify-theme-harness verify-runtime --project-root <dir>
The CLI installs only the harness layer into a project. It does not generate project-specific Shopify theme files and it does not ask for project-background prompt context.
Install The CLI
Local install during development:
npm install
npm link
shopify-theme-harness --helpTarball smoke path:
npm run package:smokeInstalled package usage:
npm install -D shopify-theme-harness
npx shopify-theme-harness init .Installed Project Workflow
After init, the target project receives fixed harness-owned paths such as:
harness/*harness/contracts/agent/*scripts/agent/*scripts/inspect/*scripts/verify/*scripts/runtime/*scripts/kik/*skills/*skills/theme/profiles/*docs/ai/*Makefiletemplates/kik-theme-init/*
Theme implementation files still remain manual and project-owned. The harness does not generate or overwrite:
sections/*templates/*snippets/*assets/*layout/*config/*
The harness now distinguishes four surface types:
page: ordinary route-owned pagesproduct: product-route surfacescart: cart-route surfacesglobal: shared surfaces such as header and footer
global surfaces are compiled and orchestrated, but they are not page-owned delivery templates and are excluded from runtime screenshot ownership. They are accepted indirectly through the page, product, or cart routes that consume them.
Typical usage inside an installed project:
- add exported bundles under
figma/<page-key>/... - if the project follows the Kik baseline, run
make init-kik-theme STORE=<store-domain> [VARIABLES_TABLE_HTML=<path-to-figma-variables-table-html>] [STOREFRONT_PASSWORD=<password>]orshopify-theme-harness init-kik --project-root . --store <store-domain> [--variables-table-html <path-to-figma-variables-table-html>] [--storefront-password <password>]this also writesharness/config/kik-token-source.jsonso later inspect and verify surfaces know whether the project is using real Figma variables or the fallback Kik token baseline and it writesharness/config/browser-verification.jsonso preview verification has a runnable local config - run
make inspect-projectorshopify-theme-harness status --project-root . - run
make compile-starter - review
starter/theme/*especiallystarter/theme/agent/page.<page-key>.task.jsonandstarter/theme/agent/sections/*.task.jsonnote that the page task now carriessurfaceTypeandsharedSurfaceKeysthen ensure each completedsection-resultincludes atemplateContributionthen runmake assemble-page-templates PAGE=<page-key>to write the full delivery page and the shared preview template then runmake verify-page-preview PAGE=<page-key>to execute the Playwright CLI-only preview verifier and writestarter/theme/agent/page.<page-key>.preview.jsonthen runscripts/agent/prepare-page-dispatch.mjsto buildstarter/theme/agent/page.<page-key>.dispatch.jsonthen runscripts/agent/run-page-dispatch.mjswhile section results are arriving to keepstarter/theme/agent/page.<page-key>.run.jsoncurrent then usescripts/agent/build-page-verification.mjsto aggregate collected section results plus the written preview artifact intostarter/theme/agent/page.<page-key>.verification.jsonor use the stable make surfaces:make assemble-page-templates PAGE=<page-key> PROJECT_ROOT=.make verify-page-preview PAGE=<page-key> PROJECT_ROOT=.make prepare-page-dispatch PAGE=<page-key>make run-page-dispatch PAGE=<page-key> PAGE_DISPATCH_FLAGS="--theme-check-passed --runtime-inspect-passed --runtime-verify-passed"make build-page-verification PAGE=<page-key> PAGE_VERIFICATION_FLAGS="--theme-check-passed --runtime-inspect-passed --runtime-verify-passed"for browser verification, fillharness/config/browser-verification.jsonfromharness/config/browser-verification.example.jsonand use the Playwright CLI-only verifier to resolve the correct preview URL forpage,product, orcartsurfaces with optional storefront password submission
- wire or sync runtime captures from the real theme project
- run
make inspect-runtimeandmake verify-runtime
If your goal is to generate one full page, the shortest practical loop is:
- add
figma/<page-key>/... - run
make compile-starter - implement all generated section tasks for that page
- run
make assemble-page-templates PAGE=<page-key> - run
make verify-page-preview PAGE=<page-key> - run
make prepare-page-dispatch PAGE=<page-key> - run
make run-page-dispatch PAGE=<page-key> PAGE_DISPATCH_FLAGS="--theme-check-passed --runtime-inspect-passed --runtime-verify-passed" - inspect
starter/theme/agent/page.<page-key>.verification.json
When that final verification file says passed, the harness has enough structured evidence to say the page-generation loop is complete for that surface.
make verify-harness is now a real page-generation gate: it fails when no Figma page bundles are present, and it evaluates generated delivery ownership according to surfaceType instead of assuming every surface owns templates/page.<page-key>.json.
For Kik initialization, a real Figma variables table HTML is preferred because it gives src/input.css the actual shared token inventory for the project. If it is missing, init-kik-theme and init-kik now fall back to a repo-owned Kik token baseline so the theme can still be initialized and built. In that fallback mode, the project is bootstrapped successfully, but you should plan to replace the fallback token values with the real Figma variables export when it becomes available.
For Kik page generation, the variables source is now part of verification truth:
- if a bundle declares
designSystem.tokenSourceType: "figma-variables-html"but the project token source is stillfallback,make verify-harnessfails - if both the bundle and the project declare a
variablesHashand those hashes differ,make verify-harnessfails - fallback bootstrap is acceptable for initialization, but it is not allowed to silently satisfy a bundle that explicitly expects real Figma variables
For browser verification bootstrap, the storefront password is optional:
- pass
STOREFRONT_PASSWORD=<password>tomake init-kik-themeor--storefront-password <password>toinit-kikwhen the storefront preview is password-gated - the value is written to
harness/config/browser-verification.json - this password is only for storefront preview access during
make verify-page-preview - it is not a replacement for Shopify CLI authentication
Upgrade Safety
shopify-theme-harness upgrade treats installed harness files as scaffold-owned, but it preserves local edits by default.
- if an installed harness-owned file still matches the last installed scaffold hash, upgrade will refresh it
- if a harness-owned file has local modifications, upgrade will skip it and report the path in
skippedModifiedFiles - project-owned theme files remain outside the overlay and are never managed by the harness CLI
Skipped files require manual reconciliation when you want both the local customization and the newer scaffold change.
Status Surface
Use the aggregated status surface when you want one JSON entrypoint for:
- installed overlay metadata
- locally modified harness-owned files
- harness bundle coverage
- runtime capture status
Use the narrower inspect commands when you only need one subsystem, and use verify-* commands when you want deterministic pass/fail gates.
Publish Workflow
The repository root is the npm package for the CLI.
npm run pack:dry-runchecks the publish surface quicklynpm run package:smokeverifiesnpm packoutput can be installed and used to runinitnpm run release:check-versionsverifies release version statenpm run release:build-manifestemits a scaffold-owned release manifestnpm run release:publish-harness:dry-runpreviews npm publish using the root packagenpm run release:tag:dry-runpreviews the Git tag step- the published package only includes CLI runtime and overlay assets required for installed project workflows
- sample source inputs and generated starter outputs are intentionally excluded from the publish tarball
Detailed release notes: scripts/release/README.md
Maintainer checklist: docs/release-checklist.md
Repository Contract
Read first:
AGENTS.mddocs/ai/README.mddocs/ai/agent-workflow.mddocs/ai/repo-map.mddocs/ai/skills.md
For reusable section implementation work, use:
skills/theme/execute-page-from-figma/SKILL.mdfor main-agent page orchestrationskills/theme/implement-section-from-figma/SKILL.mdfor one-section subagent executionskills/theme/implement-figma-section/SKILL.mdskills/theme/kik-shopify-theme-init/SKILL.mdwhen the project needs the Kik baselineskills/theme/kik-shopify-figma-section/SKILL.mdwhen the project uses the Kik baseline for section implementationskills/theme/profiles/kik/SKILL.mdfor the current project-rule profile
Current Input
The current repo snapshot includes one page bundle under figma/home, but the starter is designed to scan any figma/<page-key> bundle that matches the contract.
External Theme Integration
- generate starter output
- copy
starter/theme/runtime/theme-project.binding.example.jsontostarter/theme/runtime/theme-project.binding.json - point
captureSourceDirat the external theme project's screenshot output directory - run
make sync-runtime-captures - run
make inspect-runtimeandmake verify-runtime
