Skip to content

Setting Up AI Rules (AGENTS.md)

TL;DR: One source of truth for Cursor, Claude Code, and GitHub Copilot, originally generated by Shopify’s own CLI, then reshaped by our team into something specific to Solis.

Imagine three coworkers on the same team, each keeping their own notebook titled “How We Do Things Here.” Every time a rule changes, someone has to walk over to each notebook and copy the update in by hand. Skip one, and that coworker keeps working off an old rule without even knowing it.

That was the old reality for AI coding tools. Cursor, Claude Code, and GitHub Copilot each read their own separate rules file, and someone had to keep all three in sync by hand.

The good news is that problem is mostly solved now. With a current version of the Shopify CLI, you barely have to think about it. Cursor doesn’t need its own file at all anymore, it just reads the shared file directly. Claude Code and Copilot still have their own file names sitting in your project, but those files aren’t separate notebooks anymore. Think of them as name tags stuck onto the exact same notebook. Write in the real notebook, and every name tag “shows” the update instantly, because there was only ever one notebook to begin with.

Solis already has this in place: AGENTS.md at the repo root, with CLAUDE.md and .github/copilot-instructions.md as name tags pointing at it. You don’t generate or set up any of it, it arrives the moment you clone. What follows explains how it got there and what’s in it, so you understand the file you’re about to read, not because you need to build it.

Running shopify theme init and saying yes to AI agent support is what created AGENTS.md in the first place (this already happened for Solis; you’d only do this yourself if you were starting a brand-new theme, see Setting it up below). A freshly generated file is thorough: how a theme’s folders should be organized, the rules for writing a good {% schema %} block, a full reference for Liquid (every delimiter, operator, filter, object, and tag), how translation and localization should work, and complete worked examples of a snippet, a block, and a section.

That’s the baseline every fresh shopify theme init produces, and it’s identical across every Shopify theme, not just ours. Solis’s own AGENTS.md has since moved past that baseline. The team deliberately trimmed the generic reference material back out of it, for reasons covered in the next section, so don’t be surprised that the file you actually read in this repo looks shorter and more specific than what a brand-new scaffold would generate.

The CLI also does something clever: it creates two more files, CLAUDE.md and .github/copilot-instructions.md, but not as copies. It creates them as name tags (the technical word for this is “symlinks”) pointing at that same AGENTS.md file. Nothing gets duplicated. Cursor, Claude Code, and Copilot all end up reading the exact same words, every single time, with nothing for a human to keep in sync. Cursor doesn’t even need a name tag, current versions read AGENTS.md straight from the project root. You can confirm both name tags are real (not broken) by running ls -la CLAUDE.md .github/copilot-instructions.md from the repo root and checking that each shows an -> pointing at AGENTS.md.

What’s actually inside Solis’s AGENTS.md

Section titled “What’s actually inside Solis’s AGENTS.md”

It’s worth reading the whole thing at least once, it’s short now, not a wall of reference material. Three things make up the current file:

  • One mandatory instruction, right at the top. Call learn_shopify_api once before writing any Liquid, every time you work on this theme. Think of this as telling the AI to check today’s news before writing anything, instead of relying only on what it happened to learn during training. See Shopify’s Official AI Toolkit for exactly what that connects to.
  • A note explaining what’s deliberately not here anymore. This file used to also carry the full generic Liquid/Shopify reference described above, every delimiter, filter, tag, and object, plus the {% schema %} rules, folder layout, and translation standards. The team removed that on purpose, not moved it anywhere else in this file. A frozen copy goes stale the moment Shopify ships a new filter or object; a live tool doesn’t. For that reference now, use the shopify-liquid skill from the shopify-ai-toolkit plugin (already enabled for this project) and the learn_shopify_api / search_docs_chunks MCP tools, or Shopify’s own docs at shopify.dev/docs/api/liquid for anything those don’t cover. This handbook’s own Liquid Style Guide, CSS, and Reference pages exist for the same reason: they’re the Solis-specific judgment calls on top, not a copy of the generic reference, which now only lives in the live tools above.
  • ## Building a feature from a Figma design. If someone hands an AI tool a Figma link and asks for a section, block, or feature, this section is what tells it to run /figma-to-feature <url> instead of building it by hand, a command that reads the design, writes a plan for a human to approve, builds the feature step by step with checkpoints, and tests it in a browser. See the AI-Assisted Development section for the fuller walkthrough. Two things worth knowing: while a run is in progress, a hook blocks any AI tool from writing to sections/, blocks/, snippets/, or assets/ until the plan file says Status: approved, and when no run is in progress, that hook does nothing, you can edit the theme by hand as normal.
  • ## Project conventions. Everything theme-specific lives here: code style and readability rules, Web Components written as separate assets/*.js files, CSS organized with {% stylesheet %} and BEM, schema rules for translations, presets, and visible_if, the settings-into-variables pattern, CSS custom properties exposed on each component’s outer element, accessibility requirements, documentation conventions ({% doc %}, {% comment %}, {% # %}), running validate_theme after every file, the sol naming prefix, spacing settings, the color palette system, reusing existing snippets and blocks before writing new ones, and the QA checklist. This handbook covers each of these in more depth across the CSS, JavaScript, and Design System sections, think of those pages as the long-form version of the short rules written here.

The one rule for changing it: project-wide rules go under ”## Project conventions”

Section titled “The one rule for changing it: project-wide rules go under ”## Project conventions””

## Project conventions is the one section of AGENTS.md you’ll actually touch day to day. It’s where every theme-specific rule lives, naming, spacing, colors, accessibility, code style, and it’s the only section this handbook asks you to treat as “yours to edit” when a rule changes.

The file’s other two parts, the learn_shopify_api instruction (plus the note about what’s deliberately not in this file anymore) and ## Building a feature from a Figma design, change far less often. When they do, that’s usually a decision about how the AI tooling or the Figma pipeline itself works, not a day-to-day project rule, so treat those as maintained by whoever owns that setup rather than something you add to on a random Tuesday.

Download our current ## Project conventions content to see exactly what Solis’s section contains. That download still matches the full Shopify baseline above its own ## Project conventions section, since it’s meant as a drop-in starting point for a brand-new theme (see Setting it up below), not a copy of Solis’s own, already-trimmed file.

Joining Solis as a contributor? There’s nothing to set up. AGENTS.md, CLAUDE.md, and .github/copilot-instructions.md all arrive the moment you git clone the repo. Read AGENTS.md once, top to bottom (see What’s actually inside above), and confirm the two name tags are real, not broken (ls -la CLAUDE.md .github/copilot-instructions.md, checking for an -> pointing at AGENTS.md). That’s the entire process for you.

The sections below are for two situations that don’t apply to a normal Solis clone, kept here for reference, not as something you need to act on:

Starting a brand new theme? Run shopify theme init and choose AI agent support when it asks. AGENTS.md, CLAUDE.md, and .github/copilot-instructions.md (as name tags pointing at AGENTS.md) all get created automatically. Paste our ## Project conventions content (from the template) into the ## Project conventions section the CLI already created.

Adding this to an older theme repo that wasn’t scaffolded with AI agent support? Maybe it’s a theme built before AI agent support existed. Here’s the walkthrough:

  1. Download AGENTS.md, a drop-in copy of what shopify theme init would generate, with our ## Project conventions section already filled in.
  2. Put it at the root of your repo.
  3. Create CLAUDE.md and .github/copilot-instructions.md as name tags (symlinks) pointing at AGENTS.md, matching what Shopify’s own CLI does:
Terminal window
ln -s AGENTS.md CLAUDE.md
mkdir -p .github && ln -s ../AGENTS.md .github/copilot-instructions.md

Cursor needs nothing extra, it reads AGENTS.md on its own.

  1. Commit AGENTS.md and the two name tag files. Git tracks symlinks natively, so you commit them just like any other file.

Some tools, like “Save As” in certain editors, a zip extract, or a Windows checkout with Git’s core.symlinks setting turned off, can quietly replace a name tag with a real, separate, frozen-in-time file. When that happens, CLAUDE.md stops reflecting new edits to AGENTS.md, the same way a broken shortcut icon stops opening the real file.

Fix it by deleting the stale file and recreating the symlink:

Terminal window
rm CLAUDE.md && ln -s AGENTS.md CLAUDE.md
rm .github/copilot-instructions.md && ln -s ../AGENTS.md .github/copilot-instructions.md

If you’re on Windows, also check that git config core.symlinks is set to true, and that Developer Mode (or “Run as Administrator”) is turned on for your clone. Otherwise, Git might check out CLAUDE.md and .github/copilot-instructions.md as plain text files that just contain the target’s file path written out as text, instead of a real, working name tag.

Because CLAUDE.md and .github/copilot-instructions.md are name tags, not separate copies, there’s no “regenerate” step to remember. Edit the ## Project conventions section of AGENTS.md, and every tool sees the change immediately, the same way relabeling the one real notebook instantly updates what every name tag “shows.”

  1. Edit the ## Project conventions section of AGENTS.md. Leave the file’s other two parts (the learn_shopify_api instruction and ## Building a feature from a Figma design) alone unless you’re deliberately changing how the AI tooling or the Figma pipeline itself works.
  2. Commit. That’s genuinely the whole process. No build step, no script to re-run, nothing to keep in sync, because there was only ever one real file.
  3. Mention the rule change in your pull request description, the same way you’d describe any other change in behavior. See Managing & Amending AI Rules for the fuller guide on doing this well.
✅ Do❌ Don’t
Edit the ## Project conventions section for day-to-day rule changesEdit the learn_shopify_api instruction or the Figma workflow section for an ordinary project rule. Those are about the tooling itself, not naming, spacing, or CSS conventions
Trust the name tags to stay in sync automaticallyGo looking for a “regenerate” command. It doesn’t exist anymore, editing AGENTS.md is the entire workflow
Only recreate a name tag (rm + ln -s) if it actually breaks (say, CLAUDE.md got replaced with a real file by some tool)Assume a broken name tag will somehow fix itself

Some older Cursor versions, and some teams who specifically want rules to load only when they’re relevant (a rule that only shows up while editing a .liquid file, say, instead of loading the whole AGENTS.md every single time), can still use .cursor/rules/*.mdc files. This isn’t part of Shopify’s generated scaffold. It’s something you add and maintain by hand, and it comes with a real trade-off: you get that scoped loading, but you lose the “one file, always in sync” benefit, because .mdc content has to be kept matching AGENTS.md manually instead of through a name tag.

Stick with plain AGENTS.md (which current Cursor reads directly, no setup needed) unless you have a specific, real reason to want that scoped loading badly enough to accept the extra manual work.

Whether it’s inside Shopify’s generated content or in our own ## Project conventions section, the same test applies: a good rule is specific enough to check, not just something that sounds nice.

❌ A vague, low-value rule✅ A specific, checkable rule
”Write good, clean Liquid code""A section either defines blocks locally OR accepts theme blocks via @theme, never both"
"Follow accessibility best practices""Every interactive element must be keyboard operable with a visible :focus-visible state"
"Use good naming""File names: kebab-case. Schema ids: snake_case”

Notice the difference. The vague version could mean almost anything, so an AI tool (or a new teammate) can “follow” it while still doing the wrong thing. The specific version gives you a yes-or-no test you can actually run against real code.

Testing whether your rules are actually working

Section titled “Testing whether your rules are actually working”

A rule nobody has ever checked against real output is just wishful thinking written down. So every so often, put it to the test:

  1. Ask your AI tool to build something the “wrong,” old fashioned way on purpose (Dawn-era, meaning the older pattern this handbook has moved on from), like a section with blocks written inline instead of as separate theme blocks.
  2. See what actually comes back. Did it use the current pattern (blocks living in /blocks, targeted with @theme), or did it quietly fall back to the old habit?
  3. If it fell back to the old pattern, that’s your answer: the relevant rule in ## Project conventions needs to be more specific, not longer.
✅ Do❌ Don’t
On Solis, treat AGENTS.md as something you read and extend, not something you generate. (Only run shopify theme init yourself if you’re starting an actual new theme from zero.)Editing the learn_shopify_api instruction or the Figma workflow section for an ordinary project rule change. Those two parts are about how the tooling itself works, not naming, spacing, or CSS conventions.
Edit ## Project conventions for day-to-day rule changes, that’s the section this handbook and the rest of the team expect to change over time.Looking for a “regenerate” step that doesn’t exist anymore. Editing AGENTS.md is the entire workflow now, there’s nothing left to run afterward.
Trust the name tags. There’s no regeneration step to remember, which quietly removes an entire category of “oops, forgot to sync that” bugs the old three-separate-files approach used to cause. If one ever breaks, rm and re-ln -s it.Assuming .cursor/rules/*.mdc is still the main approach. It’s optional and old fashioned now that Cursor reads AGENTS.md directly. Only bring it back for a specific, deliberate reason.
Re-test your rules from time to time against a known “wrong pattern” case, instead of just assuming they still work as the tool and the codebase both keep changing.Writing rules that are technically true but useless, like “be accessible” or “write clean code.” These almost never change what the model actually produces.
  • Solis already has AGENTS.md, plus CLAUDE.md and .github/copilot-instructions.md as name tags pointing at it. It arrives with the clone; you read it, you don’t generate it. Cursor reads AGENTS.md directly, no extra file needed.
  • Solis’s AGENTS.md isn’t a fresh, untouched scaffold. The team has already trimmed the generic Liquid/Shopify reference out of it, so the file today holds just the learn_shopify_api instruction, ## Building a feature from a Figma design, and ## Project conventions.
  • Edit ## Project conventions for day-to-day rule changes. The file’s other two parts change rarely, and only alongside a real change to the AI tooling or the Figma pipeline.
  • There’s no regeneration step. The name tags always reflect whatever the real file currently says. If one breaks, rm and re-ln -s it, no script needed.
  • .cursor/rules/*.mdc is optional and old fashioned, meant for teams that specifically want rules to load only for certain file types. Solis doesn’t use it.