SKILL.md
name: theme-forge description: > Shopify Theme Migration Toolkit: AI-assisted visual migration from any Shopify theme to any target theme. Orchestrates section-by-section comparison, mapping, and pixel-perfect pulling. Commands: onboard, scan, map-section, map-page, pull-section, pull-page, pull-header, pull-footer, refine-section, refine-page, find-variances, verify-section, verify-page, review, cutover, status, upgrade.
- MANDATORY TRIGGERS: theme-forge, theme pull, migrate theme, pull section, pull page, pull header, pull footer, refine section, refine page, find variances, extract variances, compare styles, fix variances, close FAILs, scan theme, map section, map page, theme migration, theme status, theme review, verify section, verify page, regression test, check assertions, run regression, rebaseline
theme-forge — Shopify Theme Migration Toolkit
Not installed? Clone into your Claude Code skills directory:
git clone https://github.com/cfagerlin/theme-forge.git ~/.claude/skills/theme-forgeThen restart Claude Code. No setup script needed — cloning is the install.
AI-assisted visual migration from any Shopify theme to any target theme. Think of it as git pull for theme visuals — you point it at a live site and a target theme, and it systematically matches every section.
Quick Start
/theme-forge onboard — Configure a project for migration
/theme-forge scan — Inventory all pages, sections, and settings
/theme-forge map-section <name> — Assess compatibility of a single section
/theme-forge map-page [path] — Map all sections on a page
/theme-forge reconcile [--page <template>] — Detect work already done, create report stubs
/theme-forge pull-section <name> [--page <template>] — Execute compare→fix→verify on a section
/theme-forge pull-page [path] — Pull all sections on a page
/theme-forge pull-header — Pull the site header
/theme-forge pull-footer — Pull the site footer
/theme-forge review [path] — Post-work variance review
/theme-forge status — Human-readable migration progress report
/theme-forge status --page <t> — List all sections on a page with pull commands
/theme-forge status --next — Show the next section to pull
/theme-forge refine-section <name> [--page <template>] [--variances "el:prop, ..."] — Close variances with experiment loop
/theme-forge refine-page [path] [--variances "el:prop, ..."] — Refine all sections on a page
/theme-forge find-variances <name> [--page <template>] [--force] [--add "desc"] — Extract + compare computed styles, write variance array
/theme-forge verify-section <name> --page <t> [--print-example] [--rebaseline] — Run saved regression assertions (read-only)
/theme-forge verify-page <t> — Run assertions across every section on a template
/theme-forge env start — Start dev server (safe: blocks live themes, isolates sessions)
/theme-forge env restart — Restart dev server (same port + theme, cache invalidation)
/theme-forge env stop — Stop dev server, clear config
/theme-forge env status — Check if dev server is running
/theme-forge env cleanup — Stop + delete unpublished theme + orphan scan
/theme-forge capture <url> --section <sel> — Section-scoped screenshot at all breakpoints
/theme-forge cutover — Show cutover checklist for production go-live
/theme-forge upgrade — Check for and apply updates
/theme-forge --debug on — Enable debug mode globally (persists in config.json)
/theme-forge --debug off — Disable debug mode globally
How It Works
theme-forge is a multi-skill repo. Each command above maps to a subdirectory with its own SKILL.md. This orchestrator routes commands to the right sub-skill.
Command Routing
When invoked as /theme-forge <command> [args]:
- Parse the command name from the first argument
- Load the sub-skill SKILL.md from the corresponding directory
- Pass remaining arguments to the sub-skill
- If no command is given, show the quick start reference above
- Natural language shortcuts — route these to
status:- "what's next?" / "next section" / "what should I pull?" →
status --next - "list sections on [page]" / "show me the [page] sections" / "what's on the homepage?" →
status --page <template> - "what's left?" / "what sections are remaining?" →
status --detail
- "what's next?" / "next section" / "what should I pull?" →
env(alias:dev-server) routes to the shell script, not a sub-skill SKILL.md:
Whereeval "$(scripts/dev-server.sh <action>)"<action>isstart,restart,stop,status, orcleanup. Present the output variables (DEV_PORT,DEV_URL, etc.) to the user. If the script doesn't exist atscripts/dev-server.sh, try~/.claude/skills/theme-forge/scripts/dev-server.sh --path ..- "restart the server" / "dev server is down" / "server got clobbered" → route to
env restart. Do NOT runshopify theme devdirectly. Ever. - Verify / regression shortcuts — route these to
verify-sectionorverify-page:- "regression test [section]" / "check assertions [section]" / "verify [section]" →
verify-section <section> --page <template> - "regression test the page" / "check the [template] page" / "verify page" →
verify-page <template> - "rebaseline [section]" / "selector changed" / "fix stale assertions" →
verify-section <section> --page <template> --rebaseline - "show me an example assertion" / "what does an assertion look like?" →
verify-section <section> --print-example - Never confuse
verifywithrefine. verify is read-only (reports regressions). refine mutates code (closes variances). If the user says "fix this regression," invokeverify-sectionfirst to confirm the FAIL, then invokerefine-sectionusing thenext:command from the verify output.
- "regression test [section]" / "check assertions [section]" / "verify [section]" →
Pipeline Flags
These flags modify pipeline behavior for batch operations (pull-page, pull-header, pull-footer, or --full):
--full Run pull on ALL sections across all mapped pages
--globals-only Run scan→map→globals→header→footer, commit, then stop
--retry-failed Retry sections with failed reports
--debug Save full transcript, screenshots, and diffs to .theme-forge/debug/
--no-debug Disable debug for this run (overrides global setting)
--debug Mode
Debug mode can be activated three ways (highest priority first):
--no-debugflag — disables debug for this run, overrides everything--debugflag — enables debug for this run- Global setting in
.theme-forge/config.json→"debug": true— applies to all runs
To toggle the global setting:
/theme-forge --debug on — sets "debug": true in config.json
/theme-forge --debug off — sets "debug": false in config.json
When handling /theme-forge --debug on or /theme-forge --debug off:
- Read
.theme-forge/config.json - Set or update the
"debug"key (trueorfalse) - Write back the file
- Confirm: "Debug mode is now on globally. All runs will save transcripts and artifacts to
.theme-forge/debug/. Use--no-debugon any command to skip it for one run."
When debug is active (by any method), thread it through to every sub-skill invocation. Each pull-section call creates its own debug directory at .theme-forge/debug/{timestamp}-{section-key}/ with a transcript, screenshots, computed style diffs, and a summary.
After all sections complete, the debug directory contains a full audit trail. A human or another agent can review .theme-forge/debug/ to diagnose issues without having watched the session live.
.theme-forge/debug/
├── 20260409-142000-featured-collection-1:index/
│ ├── transcript.md
│ ├── summary.json
│ ├── base-settings.json
│ ├── target-settings-before.json
│ ├── target-settings-after.json
│ ├── computed-values.json
│ ├── variances.json
│ ├── screenshots/
│ │ ├── step4-live.png
│ │ ├── step4-dev.png
│ │ └── step8-verify.png
│ └── diffs/
│ ├── computed-live.json
│ ├── computed-dev.json
│ ├── computed-dev-after.json
│ └── delta-table.md
├── 20260409-143500-slideshow-1:index/
│ └── ...
└── ...
--full Workflow
When --full is passed, run the complete migration pipeline from zero to finished site. This is a one-shot command — it handles its own prerequisites. The user should be able to install theme-forge, open a target theme, and run /theme-forge --full with no prior setup.
Do not skip steps. Do not improvise. Each step checks whether it's already been done and skips if so.
Phase 1: Project Setup (auto-onboard)
-
Check for config: Read
.theme-forge/config.json.- If it exists: Project is already onboarded. Load config and continue.
- If it doesn't exist: Run the
onboardsub-skill workflow automatically. This collects the dev store domain, resolves the live URL, detects capabilities, writes config, and sets up.gitignore. The onboard skill asks interactive questions (dev store domain, extension prefix) — let it run its full interactive flow.
-
Commit onboard artifacts (if onboard just ran):
git add .theme-forge/config.json .theme-forge/mapping-rules.json \ .theme-forge/conventions.json .theme-forge/learnings/ .gitignore git commit -m "theme-forge: onboard project" git push
Phase 2: Base Pull + Global Settings
-
Targeted base pull: Pull templates, config, sections, snippets, blocks, layout, and code assets from the live theme. See "Targeted Base Pull" below for the full command. Always run this — it's fast (~10-15 sec) and ensures fresh data.
-
Check for global maps: Look for
.theme-forge/settings-map.jsonand.theme-forge/class-map.json.- If both exist: Global maps are ready. Continue.
- If either is missing: Run
scan --apply-globalsautomatically. This inventories the site, generates the settings cross-reference map (settings-map.json), CSS class map (class-map.json), inventories app embeds (app-embeds.json), audits layouts for third-party scripts, and applies global settings (logo, favicon, fonts, colors, body text size) to the target theme'ssettings_data.json. Commit the results:git add .theme-forge/settings-map.json .theme-forge/class-map.json \ .theme-forge/app-embeds.json .theme-forge/template-map.json \ .theme-forge/site-inventory.json .theme-forge/plan.json \ .theme-forge/mappings/ \ config/settings_data.json layout/ snippets/ git commit -m "scan: global settings, app embeds, template map, layout audit" git push
Phase 3: Dev Server
-
Start the dev server using the deterministic script. Run it from the project root:
eval "$(scripts/dev-server.sh start)"If the script is installed globally (e.g.,
~/.claude/skills/theme-forge/scripts/), pass--path:eval "$(~/.claude/skills/theme-forge/scripts/dev-server.sh start --path .)"This outputs
DEV_PORT,DEV_THEME_ID,DEV_URL,DEV_PREVIEW_URL,DEV_EDITOR_URL,DEV_MODE, andDEV_STATUSas environment variables. The script handles everything:- Pre-flight safety check (blocks live themes)
- Reconnects to existing session if still running
- Detects parallel sessions and auto-creates unpublished theme
- Finds open port, starts server, captures URLs
- Writes all
dev_*fields to config
If the script fails (non-zero exit or
DEV_STATUS=error): STOP. Do NOT continue the workflow without a running dev server. Fix the error first. Common issues:config_not_found: Run from the project root or pass--path- Missing
dev_storeortarget_theme_id: Run/theme-forge onboardfirst
Present the preview and editor URLs to the user after the script runs. The user needs these to interact with the dev theme.
Other script commands (always pass
--pathif not running from the project root):scripts/dev-server.sh status # Check if running scripts/dev-server.sh restart # Cache invalidation (same port + theme) scripts/dev-server.sh stop # Stop server, clear config scripts/dev-server.sh cleanup # Stop + delete unpublished theme + orphan scanOn section/page approval (Step 12): Run
scripts/dev-server.sh cleanupto delete the unpublished theme if this session created one. Shopify has a 99-theme limit.
Phase 4: Globals (Header + Footer)
-
Pull header: Check
.theme-forge/reports/sections/header.json.- If it exists with
status: "completed": Skip. - Otherwise: Run
pull-header. Commit changes:git add sections/ snippets/ assets/ config/ templates/ \ .theme-forge/reports/sections/header.json \ .theme-forge/learnings/ .theme-forge/mapping-rules.json git commit -m "pull: header — completed" git push
- If it exists with
-
Pull footer: Check
.theme-forge/reports/sections/footer.json.- If it exists with
status: "completed": Skip. - Otherwise: Run
pull-footer. Commit changes:git add sections/ snippets/ assets/ config/ templates/ \ .theme-forge/reports/sections/footer.json \ .theme-forge/learnings/ .theme-forge/mapping-rules.json git commit -m "pull: footer — completed" git push
- If it exists with
Phase 5: Template Migration
Enumerate from the base theme, not the target. The base theme (live site) has all the templates that need migrating. The target theme starts mostly empty. Use .theme-forge/template-map.json (from scan Step 4.5) as the source of truth.
-
Migrate functional/redirect templates first: These are simple copies that don't need section-by-section pulling.
For each template classified as
functional,redirect, orapp-artifactin the template map:- Copy the
.liquidtemplate file from.theme-forge/base-cache/templates/to the target theme'stemplates/ - Copy any referenced snippets from base-cache to target
snippets/ - Copy any referenced assets from base-cache to target
assets/ - Commit:
git add templates/ snippets/ assets/ git commit -m "migrate: functional templates and dependencies" git push -u origin $(git branch --show-current)
- Copy the
-
Pull page templates in order: For each template classified as
pagein the template map, ordered:index(homepage — highest traffic, best first test)product(product pages — revenue-critical)collection(collection pages — discovery path)page(generic pages)cart,search,blog,article404,password,gift_cardcustomers/*(account pages)
For each, run
pull-page <template>. The pull-page sub-skill handles:- Creating the
.jsontemplate in the target theme if it doesn't exist - Scoped scan + map (if mappings don't exist for this page)
- Section-by-section pull with compare→fix→verify loops
- Per-section commits and pushes
- Full-page comparison at the end
- Page report written to
.theme-forge/reports/pages/
Between pages,
git pullto pick up any changes from parallel sessions. -
Pull template alternates: For each template classified as
alternatein the template map (e.g.,page.about.json,product.featured.json). These share most sections with their base template, so they're fast — mostly content/settings differences and a few unique sections.
Phase 6: Review + Report
-
Run
reviewon each completed page to catch cross-section issues (inter-section spacing, color continuity, header/footer interaction). -
Final summary: Print a migration status report:
MIGRATION COMPLETE ================== Pages pulled: 8/8 Sections pulled: 42/42 Sections skipped: 0 Sections failed: 0 Cutover items: 3 Run /theme-forge cutover for the full go-live checklist.
Every section must go through pull-section with its full compare→fix→verify loop. Do not skip the visual comparison. Do not mark sections complete without verification. Do not write section reports without actually running the pull-section workflow on that section.
Resume after interruption: Re-running --full checks existing artifacts at every step. Onboard is skipped if config exists. Scan is skipped if maps exist. Header/footer are skipped if their reports exist. Each page's sections are skipped if their reports exist. This means --full is idempotent — you can safely re-run it after a crash, context limit, or network interruption and it picks up where it left off.
--globals-only Workflow
When --globals-only is passed, run Phases 1-4 of the --full workflow (project setup, base pull, global settings, dev server, header, footer), commit all results, then stop:
"Globals, header, and footer are complete. You can now run
pull-pagefor individual pages in parallel sessions:"/theme-forge pull-page index /theme-forge pull-page product /theme-forge pull-page collection
This is useful for CI pipelines or explicit first-step workflows. In most cases, pull-page handles globals automatically (see Git Coordination below).
Configuration
All project state lives in .theme-forge/ in the target theme's root. Most files are committed to the repo so parallel sessions share the same foundation.
.theme-forge/
├── config.json # Project configuration (created by onboard) — COMMITTED
├── mapping-rules.json # Global mapping registry (base X → target Y) — COMMITTED
├── conventions.json # Global standards (CSS-first, prefix, thresholds) — COMMITTED
├── learnings/ # Per-section learning files (one per section, merge-friendly) — COMMITTED
├── site-inventory.json # Full site inventory (created by scan) — COMMITTED (optional)
├── settings-map.json # Global settings cross-reference base→target (created by scan) — COMMITTED
├── class-map.json # CSS class/property/component cross-reference (created by scan) — COMMITTED
├── app-embeds.json # App embeds inventory and migration status (created by scan) — COMMITTED
├── template-map.json # Every base template classified with dependency cascade (created by scan) — COMMITTED
├── plan.json # Migration plan (created by scan) — COMMITTED (optional)
├── base-cache/ # Targeted base theme pull (templates, config, sections, snippets, blocks, layout, CSS/JS) — GITIGNORED
├── mappings/
│ ├── sections/ # Per-section compatibility reports — COMMITTED
│ │ ├── header.json
│ │ ├── footer.json
│ │ └── ...
│ └── pages/ # Per-page mapping summaries — COMMITTED
│ ├── index.json
│ ├── product.json
│ └── ...
├── reports/
│ ├── sections/ # Per-section pull reports — COMMITTED on completion
│ │ ├── header.json
│ │ └── ...
│ └── pages/ # Per-page pull reports — COMMITTED on completion
│ └── ...
├── references/ # Live site reference screenshots (all breakpoints) — COMMITTED
│ ├── hero-index/
│ │ ├── desktop.png
│ │ ├── tablet.png
│ │ ├── mobile.png
│ │ └── meta.json
│ └── ...
├── cutover.json # Items requiring manual action during production go-live
└── debug/ # Debug artifacts — GITIGNORED
.gitignore for theme-forge projects:
.theme-forge/base-cache/
.theme-forge/debug/
.theme-forge/tmp/
.theme-forge/references/
.playwright-cli/
.playwright-mcp/
.gstack/
/*.png
Everything else in .theme-forge/ is committed. This is how parallel sessions share mappings, learnings, and see each other's completed work. The /*.png catch-all prevents screenshot artifacts from being committed (the agent sometimes saves them to the repo root instead of .theme-forge/ subdirectories).
Git Coordination (Parallel Sessions)
Multiple sessions can work on different pages simultaneously. Git is the coordination layer. No locks. No state files. No coordination protocol.
How it works:
-
Committed config = onboarding done. A session reads
.theme-forge/config.jsonfrom the repo. If it exists, the project is onboarded. No setup commands needed. -
Committed reports = section done. A section is complete when its report exists at
.theme-forge/reports/sections/{name}.jsonwithstatus: "completed". Before pulling a section, check if its report is already committed. If so, skip it. -
Committed mappings = scan done for that page. Before pulling a page, check
.theme-forge/mappings/pages/{page}.json. If it exists, the page has been scanned and mapped. If not, run a scoped scan for just that page. -
Committed header/footer reports = globals done. Before pulling page sections, check if
.theme-forge/reports/sections/header.jsonandfooter.jsonexist with completed status. If not, ask: "Globals not done yet. Run them now?"
Session lifecycle:
1. git pull # Get latest state from repo
2. Read config.json # Onboarded? ✓
3. Targeted base pull # Fresh templates + settings (~5 sec)
4. Read mapping-rules.json # Apply global mapping conventions
5. Read learnings/*.json # Apply accumulated patterns
6. Check reports/sections/header.json # Globals done? If not, ask.
7. Scoped scan + map for this page # Only if mappings don't exist
8. Pull sections one by one # Skip if report exists
9. After each section:
- Commit code changes + report + any new learnings/mapping rules
- git push
10. Final page comparison + page report
11. Commit + push
Resume after crash: If a session crashes, it never committed the in-progress section's report. Re-running pull-page sees no report for that section and re-attempts it. No staleness detection needed. No locks to go stale.
Duplicate work prevention: Two sessions assigned to the same page will both start pulling. Before each section, they git pull and check for a committed report. The second session to finish a section sees the first session already committed a report and skips. At most one section gets duplicated.
Targeted Base Pull
Sessions do NOT need a full base theme export. The agent needs templates, config, sections, snippets, blocks, and layout from the live theme for mapping, code analysis, and comparison.
The base-cache directory must be a git repo (Shopify CLI requires it):
mkdir -p .theme-forge/base-cache && git -C .theme-forge/base-cache init 2>/dev/null
shopify theme pull --theme <live_theme_id> \
--only 'templates/*' --only 'config/*' \
--only 'sections/*' --only 'snippets/*' \
--only 'blocks/*' --only 'layout/*' \
--only 'assets/*.css' --only 'assets/*.js' \
--path .theme-forge/base-cache/
Why all these directories:
templates/*+config/*— section composition and configured valuessections/*— base section Liquid code, schemas, CSS, HTML structure. Without these, the agent cannot see how the base theme implements forms, JS handlers, conditional logic, or custom blocks.snippets/*— shared components the sections reference (form handlers, tracking scripts, utility includes)blocks/*— block type definitions and schemaslayout/*— theme layout structure, global includes, script/style referencesassets/*.css+assets/*.js— stylesheets and JavaScript (needed to understand form handlers, AJAX patterns, tracking code). Excludes images and fonts to keep the pull fast.
Note on --only patterns: Use quoted globs ('templates/*'), not directory paths (templates/). The Shopify CLI --only flag uses glob matching, not directory filtering.
Legacy themes (liquid-only templates): If the base theme uses .liquid templates instead of .json templates, the pull will still work — but section composition lives in config/settings_data.json under the current key, not in template JSON files. See "Legacy Theme Support" in the scan skill.
This takes ~10-15 seconds and is always fresh. Each session runs it independently. The results are gitignored (session-local).
Scoped Scan
Instead of scanning the entire site before any work, sessions scan only the page they need:
- Read
templates/{page}.jsonfrom the target theme - Read
templates/{page}.jsonfrom.theme-forge/base-cache/ - Cross-reference sections, apply
mapping-rules.json - Write
mappings/pages/{page}.jsonandmappings/sections/*.json - Commit the mappings
The full scan command still exists for when you want a complete inventory, but it's not a prerequisite.
Mapping Rules (mapping-rules.json)
Global registry of base→target section mappings. Ensures all sessions use the same mappings for the same section types.
{
"rules": [
{
"base_type": "slideshow",
"target_type": "hero-banner",
"notes": "Use hero-banner for all carousel/slideshow sections"
},
{
"base_type": "testimonials",
"target_type": "custom-testimonial-carousel",
"notes": "Custom section, no direct equivalent in target theme"
}
],
"updated_at": "2026-04-10T12:00:00Z"
}
Workflow:
- During scoped scan, the agent checks mapping-rules.json first. Known mappings are applied instantly.
- When a new section type is encountered with no rule, the agent creates a mapping and adds a rule.
- New rules are committed so other sessions benefit.
Conventions (conventions.json)
Global standards that all sessions follow:
{
"css_first": true,
"extension_prefix": "custom-",
"never_modify_core_files": true,
"max_retry_attempts": 3,
"accepted_variance_threshold_px": 1,
"commit_after_each_section": true
}
Created during onboard. Committed to repo.
Resume Protocol
Resume is report-based. No state machine.
When pull-page starts:
git pullto get latest committed state- Read
.theme-forge/reports/sections/*.jsonfor this page's sections - Skip sections with a report where
statusiscompletedorcompleted_code_only - Skip sections with
status: "skipped" - Skip sections with
status: "failed"(use--retry-failedto delete failed reports first) - Pull all remaining sections (no report = not started)
Kill a run and restart it. It picks up where it left off.
Platform Detection
theme-forge works across Claude Code, Cowork, and OpenClaw. It detects available capabilities on first run:
| Capability | Claude Code | Cowork | OpenClaw |
|---|---|---|---|
| File read/write | ✓ | ✓ | ✓ |
| Bash/shell | ✓ | ✓ (sandboxed) | ✓ |
| Browse tool | Maybe | Maybe | Maybe |
| Computer use | ✗ | ✓ | ✗ |
| Subagents | ✓ | ✓ | ? |
When no browse tool is available, visual comparison falls back to code-only analysis. When Shopify CLI is unavailable, dev preview is skipped with instructions for manual verification.
Architecture Principles
- Theme-agnostic: Works for any base→target Shopify theme migration, not just legacy→Horizon. Extension layer prefix is configurable.
- Visual-first, code-capable: Playwright CLI (
scripts/screenshot.sh) enables pixel-level comparison at 2560px desktop resolution; without it, falls back to schema/CSS/settings analysis. - Non-destructive:
map-*andscannever modify files.pull-*modifies only the target theme, never the base theme. - Git-native coordination: The repo is the single source of truth. Committed reports = done. Committed mappings = scanned. No locks, no state machine. Parallel sessions coordinate through git commits.
- Zero-ceremony sessions: A new session reads config.json, pulls fresh base data (~5 sec), and starts working. No setup commands, no prerequisites beyond onboard.
- Composable: Each command works independently.
scancomposes them into a pipeline, but you canmap-sectionone section without a full migration.
Extension Layer Convention
All customizations in the target theme go in namespaced files. The default prefix is custom- (configurable in config.json):
sections/{prefix}*.liquidsnippets/{prefix}*.liquidassets/{prefix}*.css,assets/{prefix}*.jsblocks/{prefix}*.liquid
NEVER modify the target theme's core files. This preserves upstream upgradability.
Safety Rules
- NEVER run
shopify theme devdirectly. Always use/theme-forge env start(which runsscripts/dev-server.sh start). This includes when the user asks you to "restart the server," "start on a new port," or "the server got clobbered." The script enforces safety checks (blocks live themes), handles parallel session isolation (unpublished themes for concurrent agents), discovers open ports, and captures session URLs. Runningshopify theme devmanually bypasses all of these safeguards and risks syncing to the wrong theme or colliding with another session. If you find yourself typingshopify theme dev, STOP and use the script instead. - NEVER run
shopify theme pushorshopify theme publishwithout explicit user approval. All theme work happens locally. Theshopify theme devserver hot-reloads local files, so pushing is unnecessary during development. When the user is ready to push, they will tell you. This is a bright red line — no exceptions, no "just pushing config", no "only pushing one file". - When you DO push or delete a theme, route through
scripts/shopify-safe.sh, not rawshopify. The wrapper queries the currently-live theme id at execution time and refuses anytheme push/theme deletewhose--theme <id>matches the live theme, refusestheme publishoutright, and refuses--live/--allow-liveflags. This is a deterministic guardrail that runs regardless of which AI tool invoked it. Example:scripts/shopify-safe.sh theme push --theme 12345 --store mystore.myshopify.com. If you find yourself typingshopify theme pushorshopify theme deletedirectly, STOP and prependscripts/shopify-safe.sh. - NEVER access the production store's Shopify admin. The live site is read-only (public storefront only).
- NEVER modify the base theme files. The base theme export is a read-only reference.
- NEVER change content copy (headings, body text, button labels) without explicit instruction. The live site is the source of truth for content.