# shopify-upgrade — AI agent skill

> Find every Shopify API version your repo actually pins, check each call site against the live schema, and show you the risk before touching a file — the version string moves last.

- Category: Shopify
- Version: 1.0.0 (updated July 2026)
- License: MIT
- Author: Alex Kharchenko — Mavens Tech Lab (https://mavenslab.tech/)
- Tested on: Claude Code
- Also compatible with: Cursor, Codex, GitHub Copilot, Windsurf, dozens more via skills.sh
- Source: https://github.com/Mavens-Tech-Lab/skills/tree/main/shopify-upgrade
- Human-readable page: https://mavenslab.tech/skills/shopify-upgrade

## Install

Claude Code (plugin):

```
/plugin install shopify-upgrade@mavens-skills
```

Any other agent (Cursor, Codex, and 70+ more) — via the skills.sh CLI:

```
npx skills add Mavens-Tech-Lab/skills --skill shopify-upgrade
```

Or add the whole Mavens Tech Lab marketplace once, then pull any skill on demand:

```
/plugin marketplace add Mavens-Tech-Lab/skills
```

> If Claude Code says the plugin isn't found, your copy of the marketplace is out of date — `/plugin marketplace add` doesn't re-fetch one you already added. Run `/plugin marketplace update mavens-skills`, then install again.

## What it does

Shopify ships a new API version every quarter and supports each one for about a year, so upgrading is a recurring tax rather than a one-off project. This skill treats it as a migration with a proof obligation, not a find-and-replace.

It starts by finding what your codebase *actually* pins — which is usually more than you think. Detection is deliberately language-agnostic: a Shopify version is always `YYYY-MM` with the month in `{01, 04, 07, 10}`, so a single sweep catches a TypeScript constant, a TOML key, a `.env` value, a Python positional argument, and a raw URL string hardcoded in one webhook handler, across **JS/TS, PHP, Python, Ruby, Go, .NET** or anything speaking raw HTTP. A repo running four different versions across Admin, Storefront, webhooks and Functions is the normal case, and the plan prices each one separately instead of quietly normalising them.

Then it establishes what actually breaks. Every claim traces to something fetched that day — each operation validated against the target version's schema through Shopify's own Dev MCP, plus the versioned docs and the full changelog archive. Model recall of which fields exist in a given Shopify version is training data, stale by construction, and it never announces itself as wrong. So it isn't used: a call site with no sourced ledger row doesn't get edited at all.

> The version string is the **last** edit, never the first — and it only moves for surfaces whose findings are all resolved. Change `2024-10` to `2026-07` in a config constant and everything goes green: GraphQL is validated server-side at request time, and REST returns `200` with a quietly different body. Nothing in your type system knows the field is gone. Your error tracker finds out first.

## When to use it

When you're several versions behind and need to know the blast radius before committing to the work. When a deprecation notice or a sunset email lands and you need to find out whether it touches you. When `X-Shopify-API-Deprecated-Reason` starts showing up in your response headers. When you want to migrate legacy Admin REST calls to GraphQL and want the GID, error-model and rate-limit traps handled deliberately rather than discovered in production. Or just to answer *"which Shopify version are we even on?"* — a question with a surprisingly long answer in most repos.

"Tell me what breaks, don't change anything" is a complete, supported run: it stops at the plan, and the plan is the deliverable.

## What you get

- **A real surface inventory** — every version pin with its file and line, each SDK's *implicit* default resolved (the version that silently moves when someone bumps a dependency), and an explicit row for every surface, including the ones marked "not present" so an absent row is never confused with an overlooked one.
- **A change ledger, one row per affected call site** — what it uses, its fate in the target version, and the **source URL with a fetch date**. Deprecation reasons are quoted verbatim from the versioned docs, because that text usually names the replacement — and they are looked up deliberately, because a query can validate cleanly and still be selecting a field that's on its way out. Nothing is edited without a row.
- **A risk-tiered plan you approve before any file changes** — `BREAKING` (fails at runtime), `BEHAVIOR` (same shape, different result), `DEPRECATED` (with its removal version, so accepting it as debt is a real choice), `SCOPE`, and `OPPORTUNITY`. Opportunities stay opt-in: an upgrade PR that also refactors is a PR nobody can review.
- **Access-scope changes surfaced as their own tier** — a newly required scope means every *already-installed* merchant must re-authorise. It works perfectly in dev and fails for every existing customer, so it's reported as an operational event with a comms note, never buried in a table of file paths.
- **A specialist agent per surface, run in parallel** — Admin GraphQL, Admin REST (including REST→GraphQL when you approve it), Storefront and Customer Account, Hydrogen, Functions, App Bridge and UI extensions, Liquid themes. Each loads only its own playbook and validates its own output against the target version before reporting done.
- **Honest partial upgrades** — a surface with an unresolved breaking finding stays on its old version and says so. A partial upgrade you can see beats a complete one that fails at 2am with a clean git history.
- **Verification that outlives the diff** — the codebase is re-swept for stale version literals (the config constant is easy; the hardcoded URL is what gets missed), GraphQL and Liquid are validated at the target version, and the build runs. Whatever couldn't be verified is named as unverified rather than implied as passing.
- **Two zero-dependency scripts you can read before installing** — one finds version pins in any language, one filters the ~780-entry changelog by status, surface and date. Neither makes a network call: you fetch, they parse.

> It works alongside **Shopify's own AI Toolkit** and relies on its versioned validators — the same tools that report which access scopes each operation now requires — and it discloses that the toolkit's telemetry is on by default (it can send your most recent prompt verbatim) *before* you install it, along with the one environment variable that turns it off.

---

Built by [Mavens Tech Lab](https://mavenslab.tech/) — a software studio that builds, deploys, and maintains custom agent skills. Need this wired into your stack? info@mavenslab.tech
