shopify-theme-harness
v0.2.4
Published
Installable CLI overlay for fixed-path Shopify theme harness workflows.
Downloads
257
Readme
Shopify Theme Harness
An installable CLI that overlays an AI-native workflow onto a real Shopify theme project, then drives an agent to restore Figma designs one section at a time.
This repo is not a finished theme. It is a toolkit you install into a theme project; the agent then reads Figma, writes real theme code section by section, and verifies each section against its Figma measurements.
Architecture in plain language:
docs/architecture-overview.md. Step-by-step developer flow and prompt templates:docs/ai/figma-agent-prompts.md.
Install
npm install -D shopify-theme-harness
npx shopify-theme-harness init .init copies a fixed set of harness files (skills, scripts, contracts, configs, Kik scaffold) into the project and records what it wrote in .shopify-theme-harness/scaffold.json so a later upgrade won't clobber your edits.
By default, init also guides you through the required Shopify Admin token setup. It can read an existing shopify.theme.toml, ask for a store domain, write [environments.this].store when needed, run shopify store auth, materialize the ignored project token file at harness/config/shopify-admin.local.json, write harness/config/agent-tools.json, and verify /v1/shop-context through the configured tool server. Store Auth is only a temporary acquisition step: the target store's user-global Shopify CLI cache entry is restored afterward, or removed when it was expired/left by an older harness. Use --no-auth-token only when you intentionally want to install the harness without authorizing the store yet; use --skip-shop-context only for intentional offline or tool-server-maintenance setup.
Local development against this repo:
npm install && npm link
shopify-theme-harness --helpThe workflow
The agent never generates a whole page at once. The loop is:
- Initialize — the agent reads desktop + mobile Figma links via Figma MCP and writes a thin
figma/<page-key>/source-manifest.json(a page "table of contents": section order, ids, and which skill implements each). Usesskills/theme/workflows/initialize-page-from-figma/SKILL.md. - Implement, one section at a time — for each section the agent measures Figma, writes the section into the real theme files, and authors
agent/sections/<page>.<section>.task.json+agent/results/<page>.<section>.result.json. Static vs. data-backed routing comes from the manifest'ssection.skillRouting. - Verify each section —
make verify-section-preview-iteratefor fast feedback while implementing, thenmake verify-section-previewonce for acceptance. Each completed section keeps its own preview template (templates/index.kik-section-<page>-<section>.json).
Acceptance is section-scoped — it proves the section mounts, its measured regions land within tolerance of the Figma geometry, and the rendered structure matches coarsely. It is deliberately not pixel-1:1; the developer reviews the screenshots for the last mile. See docs/architecture-overview.md §4 for what's compared and why.
Section work is driven by machine-readable artifacts at the project root (agent/sections/*.task.json, agent/results/*.result.json) — agent-authored, not generated by any compiler. They are the stable file-based handoff surface; the real theme files stay project-owned.
Kik baseline
For projects on the Kik baseline:
make bootstrap-kik-theme STORE=<store-domain> [VARIABLES_TABLE_HTML=<path>] [STOREFRONT_PASSWORD=<password>]
make sync-kik-tokens # after maintaining design-tokens/kik.tokens.cssbootstrap-kik-theme is one-time setup (Tailwind/Vite config, Kik asset entrypoints, browser-verification config, preview scaffold). sync-kik-tokens regenerates src/input.css and harness/generated/kik.tokens.json from design-tokens/kik.tokens.css. src/input.css builds to assets/kik-theme.css; run pnpm build before judging a section preview.
Static assets & the tool server
When a section needs durable image/icon files, a developer (not the agent) runs the Figma REST extractor, which writes design-assets/manifest.json for the agent to consume:
make figma-extract-assets PAGE=<page-key>Section agents can also call a Shopify tool server for shop context and image upload. init and auth-token write the real harness/config/agent-tools.json; harness/config/agent-tools.example.json is reference material only. The server itself lives under server/. Requests authenticate to the tool server with a per-person bearer token from the env var named by toolServer.auth.tokenEnv, then send the current project's Shopify Admin access token in request headers.
For customer theme projects, the server can use the local Shopify CLI-derived Admin token file created during init instead of a public app install. To rotate or create it later, run:
npx shopify-theme-harness auth-token --project-root .The command reads or helps write shopify.theme.toml, runs shopify store auth for the narrow Admin scopes needed by the harness, writes harness/config/shopify-admin.local.json with mode 0600, refreshes harness/config/agent-tools.json, and verifies /v1/shop-context. It never leaves the newly acquired session in the user-global Store Auth cache.
Before a tool-server or direct Admin API call, refresh/check the local session without printing either token:
npx shopify-theme-harness auth-refresh --project-root .auth-refresh uses the store token endpoint, serializes concurrent refreshes with a local lock, atomically rotates the file, and returns metadata only. If Shopify rejects the refresh token, rerun auth-token and complete browser authorization. The supported theme-dev surfaces are pnpm dev (foreground) and make storefront-dev-start (background). They deliberately use Shopify CLI's normal account session, strip SHOPIFY_CLI_THEME_TOKEN, the local Admin-token path, verbose mode, and tool-server bearer variables from the child environment, and manage the preview PID/port/health state. This separation is required because direct Admin tokens do not support every Theme Dev feature, including password-protected storefront previews and HMR. A raw shopify theme dev -e this also uses ordinary Shopify CLI account auth, but bypasses the harness lifecycle and health management.
Commands
make inspect-bootstrap # environment readiness gate
make inspect-project | inspect-harness # status / overlay + contract inspection
make verify-harness # overlay + contract sanity gate
make create-section-preview PAGE=<k> SECTION=<s>
make verify-section-preview PAGE=<k> SECTION=<s> # acceptance
make verify-section-preview-iterate PAGE=<k> SECTION=<s> # fast feedback
make verify-section-preview-offline PAGE=<k> SECTION=<s> # offline triage
make notes-init PAGE=<k> # bootstrap human-override notes
make figma-extract-assets PAGE=<k> # developer-run asset extraction
make auth-token # materialize ignored Shopify Admin token file
make auth-refresh # safely refresh/check it; metadata-only output
make storefront-dev-start | -stop | -status
make bootstrap-kik-theme STORE=<domain>
make sync-kik-tokens [TOKENS=<path>]
make testCLI commands: init, upgrade, status, inspect-harness, verify-harness, verify-section-preview-offline, notes-init, auth-token, auth-refresh, bootstrap-kik-theme, sync-kik-tokens (all --project-root <dir> where applicable). init installs the harness layer and defaults into Admin token setup plus tool-server shop-context verification; pass --no-auth-token to skip setup or --skip-shop-context to skip only the final tool-server verification.
Upgrade safety
shopify-theme-harness upgrade refreshes harness-owned files that still match their last-installed hash, and skips any you've locally modified (reported in skippedModifiedFiles). Project-owned theme files are never touched. Skipped files need manual reconciliation if you want both your edit and the newer scaffold change.
The skip is sticky: a skipped path keeps its stale recorded hash, so every later upgrade sees the same mismatch and skips it again — left alone, a file that drifts once stops receiving upstream changes for good. To reconcile one, take whatever you want from your version, then force-write it from the overlay:
shopify-theme-harness upgrade --reset-file scripts/agent/verify-section-preview.mjs--reset-file is repeatable, takes repo-relative paths, and discards the local edit at those paths — the rewritten files come back in resetFiles. It rehashes them too, so they follow upstream again from then on. Everything else keeps its protection: this is deliberately per-file rather than a blanket --force, because some overlay-seeded files are meant to diverge (src/kik-component.js is your behaviour entry; design-tokens/figma.variables2css.css is an empty placeholder you fill by hand — resetting it would destroy the token handoff). A path the overlay doesn't own is a usage error, not a silent no-op.
Publish
The repo root is the npm package.
npm run package:smoke— verify the packed tarball installs andinitrunsnpm run release:check-versions— verify version statenpm run release:publish-harness:dry-run/release:tag:dry-run— preview publish/tag
Details: scripts/release/README.md. Maintainer checklist: docs/release-checklist.md.
Where things live
Read first: AGENTS.md → docs/ai/README.md → docs/ai/agent-workflow.md → docs/ai/repo-map.md → docs/ai/figma-agent-prompts.md.
Skills:
skills/theme/workflows/initialize-page-from-figma— Figma links →source-manifest.jsonskills/theme/workflows/implement-section-from-figma— implement one sectionskills/theme/workflows/implement-shopify-data-section-from-figma— product/collection/article/metaobject sectionsskills/theme/workflows/verify-section-preview— section preview evidenceskills/theme/workflows/kik-shopify-theme-init— the Kik baselineskills/theme/project-conventions— local conventions;skills/theme/patterns/swiper-carouselfor carousels
The repo ships no sample Figma input — the harness scans any figma/<page-key>/source-manifest.json matching the contract.
