← BrainerceCONTENT HISTORY

Update to Brainerce

Snapshot Oct 24, 2026 · 18:05 UTC · version 2.0.4

Collection source: downloaded plugin package. These snapshots do not have a confirmed matching collection source. Differences in file lists alone do not establish changes to the package.

WHAT CHANGED

Instructions updated for brainerce-storefront-build

Skill instructions — Now says: '1.2.0' **Connect last, not first.** Every storefront call is scoped by a connection id that looks like `vc_...`, and nothing in the code depends on which...

Observed in instructions or declared skills. Runtime behavior has not been tested.

Save Brainerce and check future changes in Following.

Up to 10 plugins free · no card required.

All fields and original values.

Skill instructions

Before

Sep 30, 2026 · 23:07 UTC

"1.0.0" **Get the connection id.** Every storefront call is scoped by one. It looks like `vc_...`. Without it there is nothing to build against, so ask for it before doing anything else rather than scaffolding against a placeholder. **Re...

After

Oct 24, 2026 · 18:05 UTC

'1.2.0' **Connect last, not first.** Every storefront call is scoped by a connection id that looks like `vc_...`, and nothing in the code depends on which store it points at: pages, routing, cart, checkout and every SDK call are identica...

Supporting files

Before

Sep 30, 2026 · 23:07 UTC

[{"relative_path":"agents/openai.yaml","size_in_bytes":753},{"relative_path":"assets/icon.png","size_in_bytes":3208},{"relative_path":"references/critical-rules.md","size_in_bytes":7087},{"relative_path":"references/i18n.md","size_in_byt...

After

Oct 24, 2026 · 18:05 UTC

[{"relative_path":"agents/openai.yaml","size_in_bytes":1157},{"relative_path":"assets/icon.png","size_in_bytes":3208},{"relative_path":"references/account-cart-and-offers.md","size_in_bytes":15412},{"relative_path":"references/connect-ex...

Compare saved observations

Download comparison JSON

SKILL.md text changes

− removed · + added

--- before
+++ after
@@ -5,7 +5,7 @@
 maintainer: Brainerce
 metadata:
   author: Brainerce
-  version: "1.0.0"
+  version: '1.2.0'
 ---
 
 Build a working Brainerce storefront: the right calls, in the right order, with the failures that bite in production already avoided.
@@ -33,20 +33,30 @@
 
 ## Before the first line of code
 
-**Get the connection id.** Every storefront call is scoped by one. It looks like `vc_...`. Without it there is nothing to build against, so ask for it before doing anything else rather than scaffolding against a placeholder.
+**Connect last, not first.** Every storefront call is scoped by a connection id that looks like `vc_...`, and nothing in the code depends on which store it points at: pages, routing, cart, checkout and every SDK call are identical either way, and only one environment variable differs. So do not open the conversation by demanding an id, and do not stop for one mid-build. Read the user's intent, settle the framework, the routing and the design, build the whole storefront reading the id from its environment variable, and get a real id at exactly one moment: when the build is done and the storefront should load real data. How you get it is decided by what you can do, not by preference:
 
-**Read the store's actual capabilities.** Payment providers, OAuth providers, whether discounts and multi-language are on, which shipping is configured: these differ per store and they decide which parts of the UI have to exist. When the Brainerce MCP server is connected (Claude Code, Cursor, or the CLI), `get-store-capabilities` and `list-store-products` return this live. In ChatGPT there is no such connection, so ask the developer what the store has rather than assuming a default.
+- **In ChatGPT with the Brainerce app installed:** call `list_sales_channels`; reuse a channel that fits, otherwise call `create_sales_channel`. That first call is what opens ChatGPT's own sign-in window, once. If the person has no Brainerce account yet, that same window creates the account and the store (they type the store name and click Allow), closes, and the tool returns the id. Nobody visits a dashboard and nobody copies anything. Then tell them which variable to put it in.
+- **With a shell:** scaffold with `--defer-connection` and finish with `npm run connect` inside the project (details under "Don't burn the run").
+- **Neither:** ask in one message, with the click-path spelled out (dashboard sidebar → **Sales Channels** → **+ Add channel** → **Create**, then copy the **Connection ID**), and wait. Ask once.
+
+Never ship a placeholder value as the id: the variable can be empty until connect time, but grep the built output for the literal `vc_YOUR_CONNECTION_ID` once before you call the build done. Never read a full `vc_` id back into the conversation unless they asked for it: it is the credential the storefront authenticates with.
+
+**Read the store's actual capabilities.** Payment providers, OAuth providers, whether discounts and multi-language are on, which shipping is configured: these differ per store and they decide which parts of the UI have to exist. When the Brainerce MCP server is connected (Claude Code, Cursor, or the CLI), `get-store-capabilities` and `list-store-products` return this live. In ChatGPT there is no such connection, but the same object is public over HTTP with an `Origin` header, so you are still not guessing. **`references/discovery.md` is the full contract** — which fields come back, what each one decides, and the distinction that matters most: a capability being switched off today is not the same as the feature being unnecessary, because mandatory surfaces auto-hide and exist so the store works the moment the owner enables them. Read it once, hold the answer for the whole run.
+
+**Read the required-features list before you write code, not after.** It is the functional coverage checklist for a complete store, and it is a build input rather than an end-of-run audit. When the Brainerce MCP server is connected, `get-required-features` returns it live for this store; otherwise read `skills/brainerce-integration-verify/references/required-features.md` in full. Most of it is marked **MANDATORY**, and a mandatory feature has to be reachable in the finished build even when the store has that capability switched off today, because it auto-hides at runtime and the owner enables it later. The rest track a store setting and can be skipped while that setting is off. Read it now: the list is what decides the scope of the build, and features it requires such as reviews, back-in-stock alerts, saved cards, loyalty and downloadable delivery appear nowhere in the eight steps below.
+
+**Decide whether this is a build or a retrofit.** Check the project for real UI that already exists on disk, that is, more than a default framework starter, with a product grid, a cart, or a checkout that already renders something, before writing anything. If it does, this is a retrofit of an existing design, most often the output of Lovable, v0, Bolt, or a hand-built prototype, and the goal changes from "build these pages" to "make this design real without changing how it looks." Read `references/connect-existing-frontend.md` first in that case: mock UI in an existing project hides broken wiring in exactly the places a fresh build would fail loudly, and the failure modes are different enough from a from-scratch build to need their own recipe.
 
 ## The build order
 
-Do these in sequence. Each step assumes the one before it.
+Do these in sequence. Each step assumes the one before it. On a retrofit, treat the same eight steps as a checklist to verify against the existing components rather than pages to create, and keep `references/connect-existing-frontend.md` open alongside whichever step you are on.
 
 1. **Client setup.** One configured client, created once, reused. See `references/setup.md`.
 2. **Catalog.** Listing, filtering, a product detail page that handles variants and modifier groups rather than assuming a flat product. See `references/products.md`.
-3. **Cart.** Persistence across reloads is not optional; a cart that empties on refresh reads as a broken shop.
+3. **Cart.** Persistence across reloads is not optional; a cart that empties on refresh reads as a broken shop. Behaviour matters as much as persistence: a cart that reads "empty" until the API answers, or that reloads the page on every menu click, loses the sale just as surely. On SDK 3.11.0 or newer, run the cart UI on the SDK's cart store (`createCartStore` from `brainerce`, or `CartProvider` and `useCart` from `brainerce/react`), which does R1 and R3 below for you; on an older SDK, use the `smart*` cart methods and follow R1 to R6 by hand. See "The header cart badge, and cart lifecycle" in `references/account-cart-and-offers.md`.
 4. **Auth.** Registration, the six-digit email verification, login, forgot and reset password, and the OAuth buttons if the store has providers configured.
 5. **Checkout.** The one sequence you must not improvise. `brainerce-checkout-flows` owns it.
-6. **Order confirmation.** The step most often left half-built, and the one the customer judges you on.
+6. **Order confirmation.** The step most often left half-built, and the one the customer judges you on. If the merchant has opted into Google Customer Reviews (Google's own verified-buyer survey, not Brainerce's product-review feature), call `getGoogleCustomerReviewsSurvey(checkoutId)` here too and render Google's opt-in module only when `enabled` is `true` — see `references/type-definitions.md`.
 7. **Discoverability.** Sitemap from the SDK helpers, robots, structured data, slug-redirect handling. See `references/seo.md`. This is a real requirement, not a nice to have: the listing API caps its page size, so a sitemap built from a plain product list silently truncates.
 8. **Localisation**, if the store runs more than one language. See `references/i18n.md`.
 
@@ -57,14 +67,158 @@
 - **Prices come back as strings.** Parse before arithmetic. String concatenation instead of addition is a real bug that ships.
 - **Never store an auth token in the browser** without a backend-for-frontend in front of it.
 - **Never hardcode currency, locale or store id.** Read them from the store.
+- **Header, footer and FAQ text is Content, not storefront copy.** Never translate it inside the storefront. If the fetched header's language differs from `store.language`, report it and have the Content changed (`references/discovery.md`); do not ask for an admin key.
 - **Do not invent SDK methods.** If it is not in the reference, it does not exist, and a plausible-looking call that 404s at runtime is worse than asking.
 - **Line items are nested in some shapes and flat in others.** Check which one you have rather than assuming.
 
+Six more come from testing a live storefront's cart on a phone. They are about how the cart and checkout BEHAVE, so a compiling build can break every one. The cart store (SDK 3.11.0 or newer) implements R1 and R3; on an older SDK you follow all six by hand with `smartGetCart`, `smartAddToCart`, `smartUpdateCartItem` and `smartRemoveFromCart`. The fix for each is in `references/critical-rules.md` and `references/account-cart-and-offers.md`.
+
+- **R1. Never render the empty-cart state before the first cart answer.** Loading is a skeleton (sized from the remembered item count, `hintCount`, with a cap), a failed load is an error with a retry button, and only an answer from the server may say "your cart is empty". A header badge that prints 0 until the request lands is the same defect.
+- **R2. Links inside the store use the framework's router link.** Next `Link`, React Router `Link`, SvelteKit or Astro client navigation. A plain `<a href="/cart">` or `window.location.href` reloads the page and throws away the cart that was already loaded. A plain anchor is for external URLs, `mailto:` and `target="_blank"`.
+- **R3. Use the cart a write returns, and never mutate then refetch.** Every cart change already answers with the whole updated cart. Render it. Optimistic quantity and removal, taps coalesced, and `await flush()` before navigating to checkout are what the cart store does; an older SDK needs the same discipline written by hand.
+- **R4. Put the Vercel function region next to the API.** If you deploy to Vercel, set the Vercel function region (not a commerce region) to `fra1` in `vercel.json`, because the default runs the proxy in the US and adds roughly 300 to 450 ms to every proxied call. Public reads may skip the BFF proxy. Details in `references/setup.md`.
+- **R5. Nothing floats over the cart's quantity controls or the checkout fields.** No chat bubble, cookie bar, WhatsApp button or storefront bot there. The primary button under the order total is Checkout, and on a phone the cart keeps a sticky checkout bar.
+- **R6. Checkout inputs carry `autocomplete` tokens**, a `name`, and `inputMode` for email and phone. The one exception is a Places typeahead on address line 1, which stays `autocomplete="off"`. See `brainerce-checkout-flows`, `references/checkout.md`.
+
+## Don't burn the run
+
+**Do not start a dev server to prove the build works.** By default, no `npm run dev` to curl
+pages, drive the cart, or open a headless browser. Correctness comes from following the
+references, and a headless run cannot complete an email verification or a real payment anyway, so
+the loop costs minutes and returns almost no signal. Do it only when the user explicitly asks you
+to verify — and then keep it to a single pass that the pages compile and render. The one thing worth that single pass is the cart behaviour check (`https://brainerce.com/verify-storefront.mjs`, run by `brainerce-integration-verify`): when the user asks you to verify and you have a shell, run it once against the running store instead of driving the cart by hand.
+
+**Build against the empty catalog, and never trade an admin key for a fuller one.** A new store has no
+products, and you cannot create any with a `vc_` id: it is read-only over the catalog. Do not treat
+that as a blocker and **do not ask for an admin key to fill it**. Render an honest empty state
+whatever else happens, because the merchant can empty the catalog again tomorrow.
+
+There is one way to put starter products in without an admin key, and it rides on the device
+approval: approving leaves a ten-minute, single-use seeding window that `POST /api/device-auth/seed`
+redeems with the same device code. **One rule: if the command performs the approval, it can seed,
+and the flag is always `--seed-products`.** The window is spent for you, every product it creates
+is also published to the new sales channel (so the storefront lists it at once, with no dashboard
+step), and neither command ever hands you the code:
+
+```bash
+# 1. Inside a project scaffolded with --defer-connection. The preferred order:
+# the storefront already exists, so the catalog can match what you built.
+npm run connect -- --seed-products \
+  '[{"name":"Ceramic Pour-Over 600ml","basePrice":149,"description":"600ml glass carafe."}]'
+
+# 2. The scaffolder's own approval, when the user wants it live immediately.
+npm create brainerce-store my-store -- --seed-products '[...]'
+```
+
+One quoted JSON argument in both cases. If your shell mangles that quoting — PowerShell does —
+put the identical JSON in `BRAINERCE_SEED_PRODUCTS` instead; both read it, and the flag wins when
+both are set. **Prefer the first**: the second wants the catalog before a single file exists,
+which is the same guess deferring the connection exists to avoid.
+
+**Read the report in three parts, not two.** Each command prints what was _seeded and published_
+by name, then any product that was _created but NOT published_ to this channel with its
+`publishError` (it exists in the store: publish it with `publish_product_to_channel` when you hold a
+Brainerce connector, otherwise from the dashboard, Products → the product → sales channels, and
+never re-add it), then what was _not created_ with the reason. Relay all
+three; a partial write said as a clean win is how a merchant finds three of five products missing
+a week later.
+
+**Decide it before you run the connect command**: the window opens at the approval and closes with
+that same command, so a second attempt costs the user a second approval. On the deferred order that
+decision sits at the _end_ of the build, which is the better moment anyway.
+
+**`npm run connect` ends with a rebuild, not a deploy.** Besides writing the channel id it fetches
+the store's real name and currency into `.env.local` (a deferred scaffold knew only the directory
+name and `USD`). Those are `NEXT_PUBLIC_*` values, inlined at build time, so run `npm run build`
+and restart any running `npm run dev` after it, before deploying — the script prints the same
+notice when it finishes. The interface language is the one thing it does not change.
+
+**No approval, no seeding.** A run given a `vc_` id by the user, or one passing `--connection-id` /
+`BRAINERCE_CONNECTION_ID` / `--no-device`, never had a device code, and `--defer-connection` moves
+the approval into `npm run connect` where the flag belongs instead. Every one of those combinations
+is refused up front, naming the command that would have worked, rather than connecting and dropping
+the catalog silently.
+
+Where no seeding happened, the catalog genuinely comes from the merchant: the dashboard, or
+**Apps → Migration Tool**. `references/seed-catalog.md` has the full route signature, the field
+list, and the rules for both seeding paths. **Never invent a catalog for a user who did not
+describe one**, and never seed a store that already has products.
+
 ## Mandatory features
 
-Some features have to be reachable in the finished build even when the store has them switched off today. They hide themselves at runtime and the owner enables them later, so a build that omits them breaks the day the owner turns the feature on. Coupon input in the cart, email verification, password reset, the OAuth button area and the reservation countdown are the ones most often missed.
+The list lives at `skills/brainerce-integration-verify/references/required-features.md`, or comes from `get-required-features` when the MCP server is connected. You should already have read it (see "Before the first line of code"); keep it open while you build. Anything marked mandatory has to be reachable in the finished build even when the store has it switched off today, because those features hide themselves at runtime and the owner enables them later, so a build that omits one breaks the day the owner turns the feature on.
+
+Five highlights, chosen because they are the ones most often missed, not because they are the list: coupon input in the cart, email verification, password reset, the OAuth button area, and the reservation countdown.
 
-`brainerce-integration-verify` carries the full checklist. Run it before you call the build done.
+The list says which features must exist. How the cart and checkout behave (R1 to R6 under "Rules that cause incidents when skipped") is a separate bar that the list does not repeat: `brainerce-integration-verify` checks both.
+
+`brainerce-integration-verify` audits a finished build against the same checklist. Run it before you call the build done, but it should be confirming coverage you already built, not the first time you see the list.
+
+## Design quality bar
+
+A store nobody wants to buy from is a failed run, whatever the SDK calls do. Read
+`references/design-quality-bar.md` before you style anything. The four that are not negotiable:
+
+- **Tokens only.** Define the semantic colour tokens first; never a literal colour in a class name.
+- **3 to 5 colours, 2 font families at most.** 1 brand colour, 2-3 neutrals, 1-2 accents.
+- **Contrast is a hard floor: WCAG 2.2 AA.** 4.5:1 body text, 3:1 large text and UI. Check the
+  actual hex pair against the ratio; a palette is not accessible because it looks fine on your
+  screen. This is the one rule that overrides explicit direction from the user.
+- **Real imagery, designed empty states.** Catalog photos do the work. No abstract filler shapes,
+  and no section left blank, which matters because a new store's catalog is empty on day one.
+
+## Hand the store over
+
+Compiling is not shipping. The moment your build is done the store still cannot take a single
+order: no payment provider is installed, there may be no shipping zone, and the catalog is empty or
+holds only the few starter products you seeded. None of that is reachable from code with a `vc_`
+id, and a headless storefront has no editor button, so unless you point the owner into the
+dashboard they have no obvious way into their own backend. End the run by saying what is left, in
+this order.
+
+**In ChatGPT with the Brainerce app installed, or on any connection that lists `get_store_setup_status`, call it before you write the handoff**, and call it again whenever the merchant asks what is left, how to start selling, or whether the store is ready. It returns the six steps (store name, sales channel, products published to a channel, shipping, payment provider, tax), each done or not, with a `nextAction`, and a payment provider in test mode counts as not done. Then do from the conversation what the connector can do instead of sending the merchant to click, **after telling the merchant what you are about to change and getting a yes**: every call in this paragraph edits their live store, and none of them runs on your own initiative. `update_store` names the store (the consent window created it with whatever they typed; it also changes currency and language, and a currency change relabels every price without converting anything, so ask before touching it on a store with prices), `create_shipping_zone` plus `create_shipping_rate` add a delivery option, `publish_product_to_channel` makes each product visible on the channel you built against, and `set_variant_stock` fixes a count. Publish a catalog: `bulk_update_platforms({ filter: { status: 'active' }, vcPublishTo: [channel] })`; `vcPublishTo` accepts the channel id, its `vc_` id or its name. `list_tax_rates` then `create_tax_rate` add the rate the merchant gives you (never one you assume; `taxEnabled` alone charges 0 tax). Going live: `set_sales_channel_live({ channelId, domain, live: true })` records the public https domain and switches the channel to LIVE; the payment provider is still connected in the dashboard. Call it only once the storefront is deployed at that domain, because it records the address and deploys nothing, and a LIVE channel whose provider is still in TEST mode declines real cards. What stays a dashboard task, and must be said as one: connecting a payment provider and switching it live. The list below is the handoff for everything the tools cannot reach.
+
+**Brainerce does not host, and there is no deploy step.** Do not promise a live URL and do not
+invent one. The developer deploys the project wherever they already chose; Brainerce is the
+backend behind it. **The dashboard is `https://brainerce.com`.** Give them that link: everything
+below is a human step there, done by the merchant.
+
+If they do host on Vercel, say one thing about speed (it is a latency setting, not a blocker): the **Vercel function region** should be `fra1`, next to the Brainerce API, set in `vercel.json` as `{ "regions": ["fra1"] }` (the scaffolded starter already ships it). Without it Vercel runs the proxy that every cart call passes through in the US, and each call pays roughly 300 to 450 ms more. This is where the server code runs. It has nothing to do with the commerce regions in item 2 below, which are a dashboard setting for prices and payment providers.
+
+Blocks an order outright, so it comes first:
+
+1. **Install a payment provider, and put it Live.** Apps → Browse → Payment Gateways → Install,
+   then connect the credentials. Installed is not enough: a provider sitting in Test mode takes no
+   real money, and switching it back to Live reopens the credentials form, which the merchant
+   cannot complete if the provider issued those keys to Brainerce directly.
+2. **Enable that provider for every region they sell to.** Settings → Regions. A provider that is
+   installed and Live but not enabled for the customer's region shows zero payment options at
+   checkout, which reads as the store being broken.
+3. **Create a shipping zone with at least one rate.** Shipping → Zones & Rates. An address no zone
+   matches is offered no delivery option, and the order stops there.
+4. **Get products in**, unless you already seeded a starter catalog through the device-auth window
+   (see `references/seed-catalog.md`), in which case name what you added — it is published to this
+   channel and already on the storefront — and say the rest is theirs. If that seed was partial,
+   name the ones that were refused too and say they still have to be added by hand; the window is
+   single use and cannot be reopened without a second approval. And if any came back
+   `published: false`, name those separately: they exist in the store and must not be re-added,
+   only published (`publish_product_to_channel` on a connector that lists it, otherwise Products →
+   the product → sales channels → toggle this channel on).
+   Otherwise they add products in the dashboard, or install **Apps → Migration Tool** for a one-time,
+   read-only import of products and orders from Shopify or WooCommerce. Never ask for a
+   `brainerce_` admin key to fill the catalog yourself.
+
+Already built and shipped, but invisible until the merchant switches it on. Name the ones you
+wired, so nobody rebuilds what is already there:
+
+- Coupons and discount rules.
+- Gift card redemption at checkout. Wire it on every store, and say plainly that it is a **payment**, not a discount: the order total and its tax do not move, the amount due to the provider does.
+- OAuth sign-in buttons: Settings → Authentication → OAuth Providers.
+- Loyalty points, referrals, badges and paid membership.
+- Checkout custom fields, and back-in-stock alerts.
+- Additional languages.
+- Header, footer, announcement bar, FAQ, static pages and blog, all of which render from merchant
+  content and stay empty until there is some.
 
 ## Response shape
 
@@ -76,15 +230,28 @@
 >
 > Checkout next? It has a fixed sequence and I want to get it right rather than fast.
 
+When the run is finished rather than mid-way, that last line is the handoff instead:
+
+> Nothing left in code. The store cannot take an order until you do four things in the dashboard at https://brainerce.com: install a payment provider and put it Live (Apps → Payment Gateways), enable it for your regions (Settings → Regions), add a shipping zone with a rate (Shipping → Zones & Rates), and add products (or Apps → Migration Tool to import them). Coupons, gift card redemption, OAuth buttons, loyalty and the content-driven header, footer and pages are already wired and appear the moment you switch them on.
+
+With the Brainerce app in ChatGPT the same handoff is shorter, because `get_store_setup_status` told you what is done and the tools closed most of the gaps:
+
+> Nothing left in code. I named the store, added a worldwide flat-rate shipping option, added the 18% VAT rate you gave me and published all twelve active products to your storefront channel. The channel is still in test mode: once the site is deployed, tell me the address and I will record it and switch the channel live. One thing only you can do before a real order goes through: connect a payment provider and put it Live, in the dashboard at https://brainerce.com under Apps → Payment Gateways.
+
 ## Reference files in this skill
 
-- `references/setup.md`: client creation and configuration.
+- `references/discovery.md`: the one call that tells you what this store can actually do, and the contract to hold for the rest of the run. Read it first on any run against a real connection.
+- `references/setup.md`: client creation and configuration, the BFF proxy that `baseUrl` points at, and where to host it (the Vercel function region).
 - `references/products.md`: catalog, variants, modifier groups, product shape.
 - `references/critical-rules.md`: the rules above, in full, with examples.
 - `references/seo.md`: sitemap helpers, robots, structured data, slug redirects.
 - `references/i18n.md`: multi-language routing and locale resolution.
+- `references/connect-existing-frontend.md`: wiring real data into a frontend that already exists, without rebuilding it.
+- `references/seed-catalog.md`: the two ways to seed a starter catalog, the no-admin-key device-auth window (reachable via `--seed-products` on `npm run connect` or on the piped bootstrap, or by calling the route yourself) and the admin-key bulk import, when each is appropriate, and why you must never ask for an admin key to do it.
+- `references/account-cart-and-offers.md`: the account address book and linked social logins, order bumps and bundles, recommendations and nudges, the cart store (SDK 3.11.0 or newer) and the cart rules R1 to R3, the header cart badge and the cart teardown hooks, pre-checkout stock validation, first-party analytics, and guest download retrieval. Read it during steps 3, 4 and 6; these are shipped features a build silently omits.
+- `references/design-quality-bar.md`: the design bar every build is held to, including the WCAG 2.2 AA contrast floor and the cart behaviour rules. Framework independent; read it before styling anything.
 
-These are snapshots taken from the Brainerce MCP server's own content. When that server is connected, prefer its live tools, which reflect the specific store. In ChatGPT it is not, and these files are the source of truth.
+The first five carry material sourced from the Brainerce MCP server's own content; when that server is connected, prefer its live tools, which reflect the specific store, and treat these as the source of truth where it is not, such as in ChatGPT. `connect-existing-frontend.md` is not MCP-sourced: it is retrofit-specific guidance authored for this skill, built on the same SDK facts the other files carry, and it applies the same way regardless of which surface is connected.
 
 ## Cross-skill connections
 
Full technical diff · 2 changed fields

changed /included_files

BEFORE
[
  {
    "relative_path": "agents/openai.yaml",
    "size_in_bytes": 753
  },
  {
    "relative_path": "assets/icon.png",
    "size_in_bytes": 3208
  },
  {
    "relative_path": "references/critical-rules.md",
    "size_in_bytes": 7087
  },
  {
    "relative_path": "references/i18n.md",
    "size_in_bytes": 8165
  },
  {
    "relative_path": "references/products.md",
    "size_in_bytes": 20206
  },
  {
    "relative_path": "references/seo.md",
    "size_in_bytes": 11973
  },
  {
    "relative_path": "references/setup.md",
    "size_in_bytes": 3885
  }
]
AFTER
[
  {
    "relative_path": "agents/openai.yaml",
    "size_in_bytes": 1157
  },
  {
    "relative_path": "assets/icon.png",
    "size_in_bytes": 3208
  },
  {
    "relative_path": "references/account-cart-and-offers.md",
    "size_in_bytes": 15412
  },
  {
    "relative_path": "references/connect-existing-frontend.md",
    "size_in_bytes": 12598
  },
  {
    "relative_path": "references/critical-rules.md",
    "size_in_bytes": 26221
  },
  {
    "relative_path": "references/design-quality-bar.md",
    "size_in_bytes": 5440
  },
  {
    "relative_path": "references/discovery.md",
    "size_in_bytes": 14512
  },
  {
    "relative_path": "references/i18n.md",
    "size_in_bytes": 9861
  },
  {
    "relative_path": "references/products.md",
    "size_in_bytes": 24099
  },
  {
    "relative_path": "references/seed-catalog.md",
    "size_in_bytes": 9971
  },
  {
    "relative_path": "references/seo.md",
    "size_in_bytes": 17511
  },
  {
    "relative_path": "references/setup.md",
    "size_in_bytes": 13800
  }
]

changed /skill_md_contents

BEFORE
"---\nname: brainerce-storefront-build\ndescription: \"Build a storefront on Brainerce, a headless commerce platform, in whatever framework the project already uses. Use when a developer says build me a store, scaffold a storefront, I have a Brainerce connection id, wire up the shop, add commerce to this site, or start a Brainerce project. Covers the ordered build path from store capabilities through catalog, cart and checkout, and the rules that cause production incidents when skipped. For developers. Brainerce is framework agnostic: Next.js, Remix, Astro, Nuxt and plain React all work. Do not choose this for merchant tasks such as adding a product or running a sale, those are brainerce-product-onboarding and brainerce-launch-a-sale. Do not choose this for one SDK method's exact signature, use brainerce-sdk. Do not choose this for the checkout sequence, use brainerce-checkout-flows. Do not choose this for content pages or blog, use brainerce-content-and-navigation. Keywords: storefront, headless commerce, scaffold, build a store, connection id, vc_, integrate.\"\ncompatibility: ChatGPT, Claude Code, Claude Desktop, Cursor\nmaintainer: Brainerce\nmetadata:\n  author: Brainerce\n  version: \"1.0.0\"\n---\n\nBuild a working Brainerce storefront: the right calls, in the right order, with the failures that bite in production already avoided.\n\n## Core principle\n\nBrainerce is headless and framework agnostic. It supplies commerce; the project supplies the framework, the routing and the design. Never rewrite someone's stack to suit an example. Customise design, copy and layout freely; do not customise SDK call sequences, business flows or auth handling, because those are where correctness lives.\n\n## When to use this skill first\n\n- \"Build a storefront\", \"scaffold a shop\", \"add commerce to this site\".\n- The developer has a `vc_` connection id and wants to start.\n- Wiring catalog, cart or product pages into an existing app.\n- \"What do I have to build for this to be a complete store\".\n\n## When NOT to use this skill first\n\n- The exact signature, arguments or return shape of one SDK method: use `brainerce-sdk`.\n- The checkout, auth, cart persistence or inventory reservation sequence: use `brainerce-checkout-flows`.\n- Auditing a build that already exists against the required checklist: use `brainerce-integration-verify`.\n- Anything a shop owner does in the dashboard rather than in code: use the merchant skills.\n- Static pages, footers, the header's navigation links, announcements and the blog: use `brainerce-content-and-navigation`, which also carries the payload shapes and the sanitisation rule.\n\n---\n\n## Before the first line of code\n\n**Get the connection id.** Every storefront call is scoped by one. It looks like `vc_...`. Without it there is nothing to build against, so ask for it before doing anything else rather than scaffolding against a placeholder.\n\n**Read the store's actual capabilities.** Payment providers, OAuth providers, whether discounts and multi-language are on, which shipping is configured: these differ per store and they decide which parts of the UI have to exist. When the Brainerce MCP server is connected (Claude Code, Cursor, or the CLI), `get-store-capabilities` and `list-store-products` return this live. In ChatGPT there is no such connection, so ask the developer what the store has rather than assuming a default.\n\n## The build order\n\nDo these in sequence. Each step assumes the one before it.\n\n1. **Client setup.** One configured client, created once, reused. See `references/setup.md`.\n2. **Catalog.** Listing, filtering, a product detail page that handles variants and modifier groups rather than assuming a flat product. See `references/products.md`.\n3. **Cart.** Persistence across reloads is not optional; a cart that empties on refresh reads as a broken shop.\n4. **Auth.** Registration, the six-digit email verification, login, forgot and reset password, and the OAuth buttons if the store has providers configured.\n5. **Checkout.** The one sequence you must not improvise. `brainerce-checkout-flows` owns it.\n6. **Order confirmation.** The step most often left half-built, and the one the customer judges you on.\n7. **Discoverability.** Sitemap from the SDK helpers, robots, structured data, slug-redirect handling. See `references/seo.md`. This is a real requirement, not a nice to have: the listing API caps its page size, so a sitemap built from a plain product list silently truncates.\n8. **Localisation**, if the store runs more than one language. See `references/i18n.md`.\n\n## Rules that cause incidents when skipped\n\nRead `references/critical-rules.md` in full before writing SDK code. The ones that catch people most often:\n\n- **Prices come back as strings.** Parse before arithmetic. String concatenation instead of addition is a real bug that ships.\n- **Never store an auth token in the browser** without a backend-for-frontend in front of it.\n- **Never hardcode currency, locale or store id.** Read them from the store.\n- **Do not invent SDK methods.** If it is not in the reference, it does not exist, and a plausible-looking call that 404s at runtime is worse than asking.\n- **Line items are nested in some shapes and flat in others.** Check which one you have rather than assuming.\n\n## Mandatory features\n\nSome features have to be reachable in the finished build even when the store has them switched off today. They hide themselves at runtime and the owner enables them later, so a build that omits them breaks the day the owner turns the feature on. Coupon input in the cart, email verification, password reset, the OAuth button area and the reservation countdown are the ones most often missed.\n\n`brainerce-integration-verify` carries the full checklist. Run it before you call the build done.\n\n## Response shape\n\n> ✓ Catalog and product pages are wired to your Brainerce store.\n>\n> Built: product listing with category filter, product detail with variant selection and modifier groups, cart with persistence across reloads.\n>\n> Not built yet, and all three are on the mandatory list: checkout, auth with email verification, order confirmation.\n>\n> Checkout next? It has a fixed sequence and I want to get it right rather than fast.\n\n## Reference files in this skill\n\n- `references/setup.md`: client creation and configuration.\n- `references/products.md`: catalog, variants, modifier groups, product shape.\n- `references/critical-rules.md`: the rules above, in full, with examples.\n- `references/seo.md`: sitemap helpers, robots, structured data, slug redirects.\n- `references/i18n.md`: multi-language routing and locale resolution.\n\nThese are snapshots taken from the Brainerce MCP server's own content. When that server is connected, prefer its live tools, which reflect the specific store. In ChatGPT it is not, and these files are the source of truth.\n\n## Cross-skill connections\n\n- One method's exact shape: `brainerce-sdk`.\n- Checkout, auth, cart and reservation sequences: `brainerce-checkout-flows`.\n- Auditing what you built: `brainerce-integration-verify`.\n- Content entries, navigation and blog, including the fact that page and rich-text HTML arrives unsanitized: `brainerce-content-and-navigation`.\n- Rendering custom fields and building a filter UI from the filterable ones: `brainerce-custom-fields`.\n\nRoute once, and do not bounce back and forth.\n"
AFTER
"---\nname: brainerce-storefront-build\ndescription: \"Build a storefront on Brainerce, a headless commerce platform, in whatever framework the project already uses. Use when a developer says build me a store, scaffold a storefront, I have a Brainerce connection id, wire up the shop, add commerce to this site, or start a Brainerce project. Covers the ordered build path from store capabilities through catalog, cart and checkout, and the rules that cause production incidents when skipped. For developers. Brainerce is framework agnostic: Next.js, Remix, Astro, Nuxt and plain React all work. Do not choose this for merchant tasks such as adding a product or running a sale, those are brainerce-product-onboarding and brainerce-launch-a-sale. Do not choose this for one SDK method's exact signature, use brainerce-sdk. Do not choose this for the checkout sequence, use brainerce-checkout-flows. Do not choose this for content pages or blog, use brainerce-content-and-navigation. Keywords: storefront, headless commerce, scaffold, build a store, connection id, vc_, integrate.\"\ncompatibility: ChatGPT, Claude Code, Claude Desktop, Cursor\nmaintainer: Brainerce\nmetadata:\n  author: Brainerce\n  version: '1.2.0'\n---\n\nBuild a working Brainerce storefront: the right calls, in the right order, with the failures that bite in production already avoided.\n\n## Core principle\n\nBrainerce is headless and framework agnostic. It supplies commerce; the project supplies the framework, the routing and the design. Never rewrite someone's stack to suit an example. Customise design, copy and layout freely; do not customise SDK call sequences, business flows or auth handling, because those are where correctness lives.\n\n## When to use this skill first\n\n- \"Build a storefront\", \"scaffold a shop\", \"add commerce to this site\".\n- The developer has a `vc_` connection id and wants to start.\n- Wiring catalog, cart or product pages into an existing app.\n- \"What do I have to build for this to be a complete store\".\n\n## When NOT to use this skill first\n\n- The exact signature, arguments or return shape of one SDK method: use `brainerce-sdk`.\n- The checkout, auth, cart persistence or inventory reservation sequence: use `brainerce-checkout-flows`.\n- Auditing a build that already exists against the required checklist: use `brainerce-integration-verify`.\n- Anything a shop owner does in the dashboard rather than in code: use the merchant skills.\n- Static pages, footers, the header's navigation links, announcements and the blog: use `brainerce-content-and-navigation`, which also carries the payload shapes and the sanitisation rule.\n\n---\n\n## Before the first line of code\n\n**Connect last, not first.** Every storefront call is scoped by a connection id that looks like `vc_...`, and nothing in the code depends on which store it points at: pages, routing, cart, checkout and every SDK call are identical either way, and only one environment variable differs. So do not open the conversation by demanding an id, and do not stop for one mid-build. Read the user's intent, settle the framework, the routing and the design, build the whole storefront reading the id from its environment variable, and get a real id at exactly one moment: when the build is done and the storefront should load real data. How you get it is decided by what you can do, not by preference:\n\n- **In ChatGPT with the Brainerce app installed:** call `list_sales_channels`; reuse a channel that fits, otherwise call `create_sales_channel`. That first call is what opens ChatGPT's own sign-in window, once. If the person has no Brainerce account yet, that same window creates the account and the store (they type the store name and click Allow), closes, and the tool returns the id. Nobody visits a dashboard and nobody copies anything. Then tell them which variable to put it in.\n- **With a shell:** scaffold with `--defer-connection` and finish with `npm run connect` inside the project (details under \"Don't burn the run\").\n- **Neither:** ask in one message, with the click-path spelled out (dashboard sidebar → **Sales Channels** → **+ Add channel** → **Create**, then copy the **Connection ID**), and wait. Ask once.\n\nNever ship a placeholder value as the id: the variable can be empty until connect time, but grep the built output for the literal `vc_YOUR_CONNECTION_ID` once before you call the build done. Never read a full `vc_` id back into the conversation unless they asked for it: it is the credential the storefront authenticates with.\n\n**Read the store's actual capabilities.** Payment providers, OAuth providers, whether discounts and multi-language are on, which shipping is configured: these differ per store and they decide which parts of the UI have to exist. When the Brainerce MCP server is connected (Claude Code, Cursor, or the CLI), `get-store-capabilities` and `list-store-products` return this live. In ChatGPT there is no such connection, but the same object is public over HTTP with an `Origin` header, so you are still not guessing. **`references/discovery.md` is the full contract** — which fields come back, what each one decides, and the distinction that matters most: a capability being switched off today is not the same as the feature being unnecessary, because mandatory surfaces auto-hide and exist so the store works the moment the owner enables them. Read it once, hold the answer for the whole run.\n\n**Read the required-features list before you write code, not after.** It is the functional coverage checklist for a complete store, and it is a build input rather than an end-of-run audit. When the Brainerce MCP server is connected, `get-required-features` returns it live for this store; otherwise read `skills/brainerce-integration-verify/references/required-features.md` in full. Most of it is marked **MANDATORY**, and a mandatory feature has to be reachable in the finished build even when the store has that capability switched off today, because it auto-hides at runtime and the owner enables it later. The rest track a store setting and can be skipped while that setting is off. Read it now: the list is what decides the scope of the build, and features it requires such as reviews, back-in-stock alerts, saved cards, loyalty and downloadable delivery appear nowhere in the eight steps below.\n\n**Decide whether this is a build or a retrofit.** Check the project for real UI that already exists on disk, that is, more than a default framework starter, with a product grid, a cart, or a checkout that already renders something, before writing anything. If it does, this is a retrofit of an existing design, most often the output of Lovable, v0, Bolt, or a hand-built prototype, and the goal changes from \"build these pages\" to \"make this design real without changing how it looks.\" Read `references/connect-existing-frontend.md` first in that case: mock UI in an existing project hides broken wiring in exactly the places a fresh build would fail loudly, and the failure modes are different enough from a from-scratch build to need their own recipe.\n\n## The build order\n\nDo these in sequence. Each step assumes the one before it. On a retrofit, treat the same eight steps as a checklist to verify against the existing components rather than pages to create, and keep `references/connect-existing-frontend.md` open alongside whichever step you are on.\n\n1. **Client setup.** One configured client, created once, reused. See `references/setup.md`.\n2. **Catalog.** Listing, filtering, a product detail page that handles variants and modifier groups rather than assuming a flat product. See `references/products.md`.\n3. **Cart.** Persistence across reloads is not optional; a cart that empties on refresh reads as a broken shop. Behaviour matters as much as persistence: a cart that reads \"empty\" until the API answers, or that reloads the page on every menu click, loses the sale just as surely. On SDK 3.11.0 or newer, run the cart UI on the SDK's cart store (`createCartStore` from `brainerce`, or `CartProvider` and `useCart` from `brainerce/react`), which does R1 and R3 below for you; on an older SDK, use the `smart*` cart methods and follow R1 to R6 by hand. See \"The header cart badge, and cart lifecycle\" in `references/account-cart-and-offers.md`.\n4. **Auth.** Registration, the six-digit email verification, login, forgot and reset password, and the OAuth buttons if the store has providers configured.\n5. **Checkout.** The one sequence you must not improvise. `brainerce-checkout-flows` owns it.\n6. **Order confirmation.** The step most often left half-built, and the one the customer judges you on. If the merchant has opted into Google Customer Reviews (Google's own verified-buyer survey, not Brainerce's product-review feature), call `getGoogleCustomerReviewsSurvey(checkoutId)` here too and render Google's opt-in module only when `enabled` is `true` — see `references/type-definitions.md`.\n7. **Discoverability.** Sitemap from the SDK helpers, robots, structured data, slug-redirect handling. See `references/seo.md`. This is a real requirement, not a nice to have: the listing API caps its page size, so a sitemap built from a plain product list silently truncates.\n8. **Localisation**, if the store runs more than one language. See `references/i18n.md`.\n\n## Rules that cause incidents when skipped\n\nRead `references/critical-rules.md` in full before writing SDK code. The ones that catch people most often:\n\n- **Prices come back as strings.** Parse before arithmetic. String concatenation instead of addition is a real bug that ships.\n- **Never store an auth token in the browser** without a backend-for-frontend in front of it.\n- **Never hardcode currency, locale or store id.** Read them from the store.\n- **Header, footer and FAQ text is Content, not storefront copy.** Never translate it inside the storefront. If the fetched header's language differs from `store.language`, report it and have the Content changed (`references/discovery.md`); do not ask for an admin key.\n- **Do not invent SDK methods.** If it is not in the reference, it does not exist, and a plausible-looking call that 404s at runtime is worse than asking.\n- **Line items are nested in some shapes and flat in others.** Check which one you have rather than assuming.\n\nSix more come from testing a live storefront's cart on a phone. They are about how the cart and checkout BEHAVE, so a compiling build can break every one. The cart store (SDK 3.11.0 or newer) implements R1 and R3; on an older SDK you follow all six by hand with `smartGetCart`, `smartAddToCart`, `smartUpdateCartItem` and `smartRemoveFromCart`. The fix for each is in `references/critical-rules.md` and `references/account-cart-and-offers.md`.\n\n- **R1. Never render the empty-cart state before the first cart answer.** Loading is a skeleton (sized from the remembered item count, `hintCount`, with a cap), a failed load is an error with a retry button, and only an answer from the server may say \"your cart is empty\". A header badge that prints 0 until the request lands is the same defect.\n- **R2. Links inside the store use the framework's router link.** Next `Link`, React Router `Link`, SvelteKit or Astro client navigation. A plain `<a href=\"/cart\">` or `window.location.href` reloads the page and throws away the cart that was already loaded. A plain anchor is for external URLs, `mailto:` and `target=\"_blank\"`.\n- **R3. Use the cart a write returns, and never mutate then refetch.** Every cart change already answers with the whole updated cart. Render it. Optimistic quantity and removal, taps coalesced, and `await flush()` before navigating to checkout are what the cart store does; an older SDK needs the same discipline written by hand.\n- **R4. Put the Vercel function region next to the API.** If you deploy to Vercel, set the Vercel function region (not a commerce region) to `fra1` in `vercel.json`, because the default runs the proxy in the US and adds roughly 300 to 450 ms to every proxied call. Public reads may skip the BFF proxy. Details in `references/setup.md`.\n- **R5. Nothing floats over the cart's quantity controls or the checkout fields.** No chat bubble, cookie bar, WhatsApp button or storefront bot there. The primary button under the order total is Checkout, and on a phone the cart keeps a sticky checkout bar.\n- **R6. Checkout inputs carry `autocomplete` tokens**, a `name`, and `inputMode` for email and phone. The one exception is a Places typeahead on address line 1, which stays `autocomplete=\"off\"`. See `brainerce-checkout-flows`, `references/checkout.md`.\n\n## Don't burn the run\n\n**Do not start a dev server to prove the build works.** By default, no `npm run dev` to curl\npages, drive the cart, or open a headless browser. Correctness comes from following the\nreferences, and a headless run cannot complete an email verification or a real payment anyway, so\nthe loop costs minutes and returns almost no signal. Do it only when the user explicitly asks you\nto verify — and then keep it to a single pass that the pages compile and render. The one thing worth that single pass is the cart behaviour check (`https://brainerce.com/verify-storefront.mjs`, run by `brainerce-integration-verify`): when the user asks you to verify and you have a shell, run it once against the running store instead of driving the cart by hand.\n\n**Build against the empty catalog, and never trade an admin key for a fuller one.** A new store has no\nproducts, and you cannot create any with a `vc_` id: it is read-only over the catalog. Do not treat\nthat as a blocker and **do not ask for an admin key to fill it**. Render an honest empty state\nwhatever else happens, because the merchant can empty the catalog again tomorrow.\n\nThere is one way to put starter products in without an admin key, and it rides on the device\napproval: approving leaves a ten-minute, single-use seeding window that `POST /api/device-auth/seed`\nredeems with the same device code. **One rule: if the command performs the approval, it can seed,\nand the flag is always `--seed-products`.** The window is spent for you, every product it creates\nis also published to the new sales channel (so the storefront lists it at once, with no dashboard\nstep), and neither command ever hands you the code:\n\n```bash\n# 1. Inside a project scaffolded with --defer-connection. The preferred order:\n# the storefront already exists, so the catalog can match what you built.\nnpm run connect -- --seed-products \\\n  '[{\"name\":\"Ceramic Pour-Over 600ml\",\"basePrice\":149,\"description\":\"600ml glass carafe.\"}]'\n\n# 2. The scaffolder's own approval, when the user wants it live immediately.\nnpm create brainerce-store my-store -- --seed-products '[...]'\n```\n\nOne quoted JSON argument in both cases. If your shell mangles that quoting — PowerShell does —\nput the identical JSON in `BRAINERCE_SEED_PRODUCTS` instead; both read it, and the flag wins when\nboth are set. **Prefer the first**: the second wants the catalog before a single file exists,\nwhich is the same guess deferring the connection exists to avoid.\n\n**Read the report in three parts, not two.** Each command prints what was _seeded and published_\nby name, then any product that was _created but NOT published_ to this channel with its\n`publishError` (it exists in the store: publish it with `publish_product_to_channel` when you hold a\nBrainerce connector, otherwise from the dashboard, Products → the product → sales channels, and\nnever re-add it), then what was _not created_ with the reason. Relay all\nthree; a partial write said as a clean win is how a merchant finds three of five products missing\na week later.\n\n**Decide it before you run the connect command**: the window opens at the approval and closes with\nthat same command, so a second attempt costs the user a second approval. On the deferred order that\ndecision sits at the _end_ of the build, which is the better moment anyway.\n\n**`npm run connect` ends with a rebuild, not a deploy.** Besides writing the channel id it fetches\nthe store's real name and currency into `.env.local` (a deferred scaffold knew only the directory\nname and `USD`). Those are `NEXT_PUBLIC_*` values, inlined at build time, so run `npm run build`\nand restart any running `npm run dev` after it, before deploying — the script prints the same\nnotice when it finishes. The interface language is the one thing it does not change.\n\n**No approval, no seeding.** A run given a `vc_` id by the user, or one passing `--connection-id` /\n`BRAINERCE_CONNECTION_ID` / `--no-device`, never had a device code, and `--defer-connection` moves\nthe approval into `npm run connect` where the flag belongs instead. Every one of those combinations\nis refused up front, naming the command that would have worked, rather than connecting and dropping\nthe catalog silently.\n\nWhere no seeding happened, the catalog genuinely comes from the merchant: the dashboard, or\n**Apps → Migration Tool**. `references/seed-catalog.md` has the full route signature, the field\nlist, and the rules for both seeding paths. **Never invent a catalog for a user who did not\ndescribe one**, and never seed a store that already has products.\n\n## Mandatory features\n\nThe list lives at `skills/brainerce-integration-verify/references/required-features.md`, or comes from `get-required-features` when the MCP server is connected. You should already have read it (see \"Before the first line of code\"); keep it open while you build. Anything marked mandatory has to be reachable in the finished build even when the store has it switched off today, because those features hide themselves at runtime and the owner enables them later, so a build that omits one breaks the day the owner turns the feature on.\n\nFive highlights, chosen because they are the ones most often missed, not because they are the list: coupon input in the cart, email verification, password reset, the OAuth button area, and the reservation countdown.\n\nThe list says which features must exist. How the cart and checkout behave (R1 to R6 under \"Rules that cause incidents when skipped\") is a separate bar that the list does not repeat: `brainerce-integration-verify` checks both.\n\n`brainerce-integration-verify` audits a finished build against the same checklist. Run it before you call the build done, but it should be confirming coverage you already built, not the first time you see the list.\n\n## Design quality bar\n\nA store nobody wants to buy from is a failed run, whatever the SDK calls do. Read\n`references/design-quality-bar.md` before you style anything. The four that are not negotiable:\n\n- **Tokens only.** Define the semantic colour tokens first; never a literal colour in a class name.\n- **3 to 5 colours, 2 font families at most.** 1 brand colour, 2-3 neutrals, 1-2 accents.\n- **Contrast is a hard floor: WCAG 2.2 AA.** 4.5:1 body text, 3:1 large text and UI. Check the\n  actual hex pair against the ratio; a palette is not accessible because it looks fine on your\n  screen. This is the one rule that overrides explicit direction from the user.\n- **Real imagery, designed empty states.** Catalog photos do the work. No abstract filler shapes,\n  and no section left blank, which matters because a new store's catalog is empty on day one.\n\n## Hand the store over\n\nCompiling is not shipping. The moment your build is done the store still cannot take a single\norder: no payment provider is installed, there may be no shipping zone, and the catalog is empty or\nholds only the few starter products you seeded. None of that is reachable from code with a `vc_`\nid, and a headless storefront has no editor button, so unless you point the owner into the\ndashboard they have no obvious way into their own backend. End the run by saying what is left, in\nthis order.\n\n**In ChatGPT with the Brainerce app installed, or on any connection that lists `get_store_setup_status`, call it before you write the handoff**, and call it again whenever the merchant asks what is left, how to start selling, or whether the store is ready. It returns the six steps (store name, sales channel, products published to a channel, shipping, payment provider, tax), each done or not, with a `nextAction`, and a payment provider in test mode counts as not done. Then do from the conversation what the connector can do instead of sending the merchant to click, **after telling the merchant what you are about to change and getting a yes**: every call in this paragraph edits their live store, and none of them runs on your own initiative. `update_store` names the store (the consent window created it with whatever they typed; it also changes currency and language, and a currency change relabels every price without converting anything, so ask before touching it on a store with prices), `create_shipping_zone` plus `create_shipping_rate` add a delivery option, `publish_product_to_channel` makes each product visible on the channel you built against, and `set_variant_stock` fixes a count. Publish a catalog: `bulk_update_platforms({ filter: { status: 'active' }, vcPublishTo: [channel] })`; `vcPublishTo` accepts the channel id, its `vc_` id or its name. `list_tax_rates` then `create_tax_rate` add the rate the merchant gives you (never one you assume; `taxEnabled` alone charges 0 tax). Going live: `set_sales_channel_live({ channelId, domain, live: true })` records the public https domain and switches the channel to LIVE; the payment provider is still connected in the dashboard. Call it only once the storefront is deployed at that domain, because it records the address and deploys nothing, and a LIVE channel whose provider is still in TEST mode declines real cards. What stays a dashboard task, and must be said as one: connecting a payment provider and switching it live. The list below is the handoff for everything the tools cannot reach.\n\n**Brainerce does not host, and there is no deploy step.** Do not promise a live URL and do not\ninvent one. The developer deploys the project wherever they already chose; Brainerce is the\nbackend behind it. **The dashboard is `https://brainerce.com`.** Give them that link: everything\nbelow is a human step there, done by the merchant.\n\nIf they do host on Vercel, say one thing about speed (it is a latency setting, not a blocker): the **Vercel function region** should be `fra1`, next to the Brainerce API, set in `vercel.json` as `{ \"regions\": [\"fra1\"] }` (the scaffolded starter already ships it). Without it Vercel runs the proxy that every cart call passes through in the US, and each call pays roughly 300 to 450 ms more. This is where the server code runs. It has nothing to do with the commerce regions in item 2 below, which are a dashboard setting for prices and payment providers.\n\nBlocks an order outright, so it comes first:\n\n1. **Install a payment provider, and put it Live.** Apps → Browse → Payment Gateways → Install,\n   then connect the credentials. Installed is not enough: a provider sitting in Test mode takes no\n   real money, and switching it back to Live reopens the credentials form, which the merchant\n   cannot complete if the provider issued those keys to Brainerce directly.\n2. **Enable that provider for every region they sell to.** Settings → Regions. A provider that is\n   installed and Live but not enabled for the customer's region shows zero payment options at\n   checkout, which reads as the store being broken.\n3. **Create a shipping zone with at least one rate.** Shipping → Zones & Rates. An address no zone\n   matches is offered no delivery option, and the order stops there.\n4. **Get products in**, unless you already seeded a starter catalog through the device-auth window\n   (see `references/seed-catalog.md`), in which case name what you added — it is published to this\n   channel and already on the storefront — and say the rest is theirs. If that seed was partial,\n   name the ones that were refused too and say they still have to be added by hand; the window is\n   single use and cannot be reopened without a second approval. And if any came back\n   `published: false`, name those separately: they exist in the store and must not be re-added,\n   only published (`publish_product_to_channel` on a connector that lists it, otherwise Products →\n   the product → sales channels → toggle this channel on).\n   Otherwise they add products in the dashboard, or install **Apps → Migration Tool** for a one-time,\n   read-only import of products and orders from Shopify or WooCommerce. Never ask for a\n   `brainerce_` admin key to fill the catalog yourself.\n\nAlready built and shipped, but invisible until the merchant switches it on. Name the ones you\nwired, so nobody rebuilds what is already there:\n\n- Coupons and discount rules.\n- Gift card redemption at checkout. Wire it on every store, and say plainly that it is a **payment**, not a discount: the order total and its tax do not move, the amount due to the provider does.\n- OAuth sign-in buttons: Settings → Authentication → OAuth Providers.\n- Loyalty points, referrals, badges and paid membership.\n- Checkout custom fields, and back-in-stock alerts.\n- Additional languages.\n- Header, footer, announcement bar, FAQ, static pages and blog, all of which render from merchant\n  content and stay empty until there is some.\n\n## Response shape\n\n> ✓ Catalog and product pages are wired to your Brainerce store.\n>\n> Built: product listing with category filter, product detail with variant selection and modifier groups, cart with persistence across reloads.\n>\n> Not built yet, and all three are on the mandatory list: checkout, auth with email verification, order confirmation.\n>\n> Checkout next? It has a fixed sequence and I want to get it right rather than fast.\n\nWhen the run is finished rather than mid-way, that last line is the handoff instead:\n\n> Nothing left in code. The store cannot take an order until you do four things in the dashboard at https://brainerce.com: install a payment provider and put it Live (Apps → Payment Gateways), enable it for your regions (Settings → Regions), add a shipping zone with a rate (Shipping → Zones & Rates), and add products (or Apps → Migration Tool to import them). Coupons, gift card redemption, OAuth buttons, loyalty and the content-driven header, footer and pages are already wired and appear the moment you switch them on.\n\nWith the Brainerce app in ChatGPT the same handoff is shorter, because `get_store_setup_status` told you what is done and the tools closed most of the gaps:\n\n> Nothing left in code. I named the store, added a worldwide flat-rate shipping option, added the 18% VAT rate you gave me and published all twelve active products to your storefront channel. The channel is still in test mode: once the site is deployed, tell me the address and I will record it and switch the channel live. One thing only you can do before a real order goes through: connect a payment provider and put it Live, in the dashboard at https://brainerce.com under Apps → Payment Gateways.\n\n## Reference files in this skill\n\n- `references/discovery.md`: the one call that tells you what this store can actually do, and the contract to hold for the rest of the run. Read it first on any run against a real connection.\n- `references/setup.md`: client creation and configuration, the BFF proxy that `baseUrl` points at, and where to host it (the Vercel function region).\n- `references/products.md`: catalog, variants, modifier groups, product shape.\n- `references/critical-rules.md`: the rules above, in full, with examples.\n- `references/seo.md`: sitemap helpers, robots, structured data, slug redirects.\n- `references/i18n.md`: multi-language routing and locale resolution.\n- `references/connect-existing-frontend.md`: wiring real data into a frontend that already exists, without rebuilding it.\n- `references/seed-catalog.md`: the two ways to seed a starter catalog, the no-admin-key device-auth window (reachable via `--seed-products` on `npm run connect` or on the piped bootstrap, or by calling the route yourself) and the admin-key bulk import, when each is appropriate, and why you must never ask for an admin key to do it.\n- `references/account-cart-and-offers.md`: the account address book and linked social logins, order bumps and bundles, recommendations and nudges, the cart store (SDK 3.11.0 or newer) and the cart rules R1 to R3, the header cart badge and the cart teardown hooks, pre-checkout stock validation, first-party analytics, and guest download retrieval. Read it during steps 3, 4 and 6; these are shipped features a build silently omits.\n- `references/design-quality-bar.md`: the design bar every build is held to, including the WCAG 2.2 AA contrast floor and the cart behaviour rules. Framework independent; read it before styling anything.\n\nThe first five carry material sourced from the Brainerce MCP server's own content; when that server is connected, prefer its live tools, which reflect the specific store, and treat these as the source of truth where it is not, such as in ChatGPT. `connect-existing-frontend.md` is not MCP-sourced: it is retrofit-specific guidance authored for this skill, built on the same SDK facts the other files carry, and it applies the same way regardless of which surface is connected.\n\n## Cross-skill connections\n\n- One method's exact shape: `brainerce-sdk`.\n- Checkout, auth, cart and reservation sequences: `brainerce-checkout-flows`.\n- Auditing what you built: `brainerce-integration-verify`.\n- Content entries, navigation and blog, including the fact that page and rich-text HTML arrives unsanitized: `brainerce-content-and-navigation`.\n- Rendering custom fields and building a filter UI from the filterable ones: `brainerce-custom-fields`.\n\nRoute once, and do not bounce back and forth.\n"
Full snapshot data
{
  "description": "Build a storefront on Brainerce, a headless commerce platform, in whatever framework the project already uses. Use when a developer says build me a store, scaffold a storefront, I have a Brainerce connection id, wire up the shop, add commerce to this site, or start a Brainerce project. Covers the ordered build path from store capabilities through catalog, cart and checkout, and the rules that cause production incidents when skipped. For developers. Brainerce is framework agnostic: Next.js, Remix, Astro, Nuxt and plain React all work. Do not choose this for merchant tasks such as adding a product or running a sale, those are brainerce-product-onboarding and brainerce-launch-a-sale. Do not choose this for one SDK method's exact signature, use brainerce-sdk. Do not choose this for the checkout sequence, use brainerce-checkout-flows. Do not choose this for content pages or blog, use brainerce-content-and-navigation. Keywords: storefront, headless commerce, scaffold, build a store, connection id, vc_, integrate.",
  "included_files": [
    {
      "relative_path": "agents/openai.yaml",
      "size_in_bytes": 1157
    },
    {
      "relative_path": "assets/icon.png",
      "size_in_bytes": 3208
    },
    {
      "relative_path": "references/account-cart-and-offers.md",
      "size_in_bytes": 15412
    },
    {
      "relative_path": "references/connect-existing-frontend.md",
      "size_in_bytes": 12598
    },
    {
      "relative_path": "references/critical-rules.md",
      "size_in_bytes": 26221
    },
    {
      "relative_path": "references/design-quality-bar.md",
      "size_in_bytes": 5440
    },
    {
      "relative_path": "references/discovery.md",
      "size_in_bytes": 14512
    },
    {
      "relative_path": "references/i18n.md",
      "size_in_bytes": 9861
    },
    {
      "relative_path": "references/products.md",
      "size_in_bytes": 24099
    },
    {
      "relative_path": "references/seed-catalog.md",
      "size_in_bytes": 9971
    },
    {
      "relative_path": "references/seo.md",
      "size_in_bytes": 17511
    },
    {
      "relative_path": "references/setup.md",
      "size_in_bytes": 13800
    }
  ],
  "name": "brainerce-storefront-build",
  "skill_md_contents": "---\nname: brainerce-storefront-build\ndescription: \"Build a storefront on Brainerce, a headless commerce platform, in whatever framework the project already uses. Use when a developer says build me a store, scaffold a storefront, I have a Brainerce connection id, wire up the shop, add commerce to this site, or start a Brainerce project. Covers the ordered build path from store capabilities through catalog, cart and checkout, and the rules that cause production incidents when skipped. For developers. Brainerce is framework agnostic: Next.js, Remix, Astro, Nuxt and plain React all work. Do not choose this for merchant tasks such as adding a product or running a sale, those are brainerce-product-onboarding and brainerce-launch-a-sale. Do not choose this for one SDK method's exact signature, use brainerce-sdk. Do not choose this for the checkout sequence, use brainerce-checkout-flows. Do not choose this for content pages or blog, use brainerce-content-and-navigation. Keywords: storefront, headless commerce, scaffold, build a store, connection id, vc_, integrate.\"\ncompatibility: ChatGPT, Claude Code, Claude Desktop, Cursor\nmaintainer: Brainerce\nmetadata:\n  author: Brainerce\n  version: '1.2.0'\n---\n\nBuild a working Brainerce storefront: the right calls, in the right order, with the failures that bite in production already avoided.\n\n## Core principle\n\nBrainerce is headless and framework agnostic. It supplies commerce; the project supplies the framework, the routing and the design. Never rewrite someone's stack to suit an example. Customise design, copy and layout freely; do not customise SDK call sequences, business flows or auth handling, because those are where correctness lives.\n\n## When to use this skill first\n\n- \"Build a storefront\", \"scaffold a shop\", \"add commerce to this site\".\n- The developer has a `vc_` connection id and wants to start.\n- Wiring catalog, cart or product pages into an existing app.\n- \"What do I have to build for this to be a complete store\".\n\n## When NOT to use this skill first\n\n- The exact signature, arguments or return shape of one SDK method: use `brainerce-sdk`.\n- The checkout, auth, cart persistence or inventory reservation sequence: use `brainerce-checkout-flows`.\n- Auditing a build that already exists against the required checklist: use `brainerce-integration-verify`.\n- Anything a shop owner does in the dashboard rather than in code: use the merchant skills.\n- Static pages, footers, the header's navigation links, announcements and the blog: use `brainerce-content-and-navigation`, which also carries the payload shapes and the sanitisation rule.\n\n---\n\n## Before the first line of code\n\n**Connect last, not first.** Every storefront call is scoped by a connection id that looks like `vc_...`, and nothing in the code depends on which store it points at: pages, routing, cart, checkout and every SDK call are identical either way, and only one environment variable differs. So do not open the conversation by demanding an id, and do not stop for one mid-build. Read the user's intent, settle the framework, the routing and the design, build the whole storefront reading the id from its environment variable, and get a real id at exactly one moment: when the build is done and the storefront should load real data. How you get it is decided by what you can do, not by preference:\n\n- **In ChatGPT with the Brainerce app installed:** call `list_sales_channels`; reuse a channel that fits, otherwise call `create_sales_channel`. That first call is what opens ChatGPT's own sign-in window, once. If the person has no Brainerce account yet, that same window creates the account and the store (they type the store name and click Allow), closes, and the tool returns the id. Nobody visits a dashboard and nobody copies anything. Then tell them which variable to put it in.\n- **With a shell:** scaffold with `--defer-connection` and finish with `npm run connect` inside the project (details under \"Don't burn the run\").\n- **Neither:** ask in one message, with the click-path spelled out (dashboard sidebar → **Sales Channels** → **+ Add channel** → **Create**, then copy the **Connection ID**), and wait. Ask once.\n\nNever ship a placeholder value as the id: the variable can be empty until connect time, but grep the built output for the literal `vc_YOUR_CONNECTION_ID` once before you call the build done. Never read a full `vc_` id back into the conversation unless they asked for it: it is the credential the storefront authenticates with.\n\n**Read the store's actual capabilities.** Payment providers, OAuth providers, whether discounts and multi-language are on, which shipping is configured: these differ per store and they decide which parts of the UI have to exist. When the Brainerce MCP server is connected (Claude Code, Cursor, or the CLI), `get-store-capabilities` and `list-store-products` return this live. In ChatGPT there is no such connection, but the same object is public over HTTP with an `Origin` header, so you are still not guessing. **`references/discovery.md` is the full contract** — which fields come back, what each one decides, and the distinction that matters most: a capability being switched off today is not the same as the feature being unnecessary, because mandatory surfaces auto-hide and exist so the store works the moment the owner enables them. Read it once, hold the answer for the whole run.\n\n**Read the required-features list before you write code, not after.** It is the functional coverage checklist for a complete store, and it is a build input rather than an end-of-run audit. When the Brainerce MCP server is connected, `get-required-features` returns it live for this store; otherwise read `skills/brainerce-integration-verify/references/required-features.md` in full. Most of it is marked **MANDATORY**, and a mandatory feature has to be reachable in the finished build even when the store has that capability switched off today, because it auto-hides at runtime and the owner enables it later. The rest track a store setting and can be skipped while that setting is off. Read it now: the list is what decides the scope of the build, and features it requires such as reviews, back-in-stock alerts, saved cards, loyalty and downloadable delivery appear nowhere in the eight steps below.\n\n**Decide whether this is a build or a retrofit.** Check the project for real UI that already exists on disk, that is, more than a default framework starter, with a product grid, a cart, or a checkout that already renders something, before writing anything. If it does, this is a retrofit of an existing design, most often the output of Lovable, v0, Bolt, or a hand-built prototype, and the goal changes from \"build these pages\" to \"make this design real without changing how it looks.\" Read `references/connect-existing-frontend.md` first in that case: mock UI in an existing project hides broken wiring in exactly the places a fresh build would fail loudly, and the failure modes are different enough from a from-scratch build to need their own recipe.\n\n## The build order\n\nDo these in sequence. Each step assumes the one before it. On a retrofit, treat the same eight steps as a checklist to verify against the existing components rather than pages to create, and keep `references/connect-existing-frontend.md` open alongside whichever step you are on.\n\n1. **Client setup.** One configured client, created once, reused. See `references/setup.md`.\n2. **Catalog.** Listing, filtering, a product detail page that handles variants and modifier groups rather than assuming a flat product. See `references/products.md`.\n3. **Cart.** Persistence across reloads is not optional; a cart that empties on refresh reads as a broken shop. Behaviour matters as much as persistence: a cart that reads \"empty\" until the API answers, or that reloads the page on every menu click, loses the sale just as surely. On SDK 3.11.0 or newer, run the cart UI on the SDK's cart store (`createCartStore` from `brainerce`, or `CartProvider` and `useCart` from `brainerce/react`), which does R1 and R3 below for you; on an older SDK, use the `smart*` cart methods and follow R1 to R6 by hand. See \"The header cart badge, and cart lifecycle\" in `references/account-cart-and-offers.md`.\n4. **Auth.** Registration, the six-digit email verification, login, forgot and reset password, and the OAuth buttons if the store has providers configured.\n5. **Checkout.** The one sequence you must not improvise. `brainerce-checkout-flows` owns it.\n6. **Order confirmation.** The step most often left half-built, and the one the customer judges you on. If the merchant has opted into Google Customer Reviews (Google's own verified-buyer survey, not Brainerce's product-review feature), call `getGoogleCustomerReviewsSurvey(checkoutId)` here too and render Google's opt-in module only when `enabled` is `true` — see `references/type-definitions.md`.\n7. **Discoverability.** Sitemap from the SDK helpers, robots, structured data, slug-redirect handling. See `references/seo.md`. This is a real requirement, not a nice to have: the listing API caps its page size, so a sitemap built from a plain product list silently truncates.\n8. **Localisation**, if the store runs more than one language. See `references/i18n.md`.\n\n## Rules that cause incidents when skipped\n\nRead `references/critical-rules.md` in full before writing SDK code. The ones that catch people most often:\n\n- **Prices come back as strings.** Parse before arithmetic. String concatenation instead of addition is a real bug that ships.\n- **Never store an auth token in the browser** without a backend-for-frontend in front of it.\n- **Never hardcode currency, locale or store id.** Read them from the store.\n- **Header, footer and FAQ text is Content, not storefront copy.** Never translate it inside the storefront. If the fetched header's language differs from `store.language`, report it and have the Content changed (`references/discovery.md`); do not ask for an admin key.\n- **Do not invent SDK methods.** If it is not in the reference, it does not exist, and a plausible-looking call that 404s at runtime is worse than asking.\n- **Line items are nested in some shapes and flat in others.** Check which one you have rather than assuming.\n\nSix more come from testing a live storefront's cart on a phone. They are about how the cart and checkout BEHAVE, so a compiling build can break every one. The cart store (SDK 3.11.0 or newer) implements R1 and R3; on an older SDK you follow all six by hand with `smartGetCart`, `smartAddToCart`, `smartUpdateCartItem` and `smartRemoveFromCart`. The fix for each is in `references/critical-rules.md` and `references/account-cart-and-offers.md`.\n\n- **R1. Never render the empty-cart state before the first cart answer.** Loading is a skeleton (sized from the remembered item count, `hintCount`, with a cap), a failed load is an error with a retry button, and only an answer from the server may say \"your cart is empty\". A header badge that prints 0 until the request lands is the same defect.\n- **R2. Links inside the store use the framework's router link.** Next `Link`, React Router `Link`, SvelteKit or Astro client navigation. A plain `<a href=\"/cart\">` or `window.location.href` reloads the page and throws away the cart that was already loaded. A plain anchor is for external URLs, `mailto:` and `target=\"_blank\"`.\n- **R3. Use the cart a write returns, and never mutate then refetch.** Every cart change already answers with the whole updated cart. Render it. Optimistic quantity and removal, taps coalesced, and `await flush()` before navigating to checkout are what the cart store does; an older SDK needs the same discipline written by hand.\n- **R4. Put the Vercel function region next to the API.** If you deploy to Vercel, set the Vercel function region (not a commerce region) to `fra1` in `vercel.json`, because the default runs the proxy in the US and adds roughly 300 to 450 ms to every proxied call. Public reads may skip the BFF proxy. Details in `references/setup.md`.\n- **R5. Nothing floats over the cart's quantity controls or the checkout fields.** No chat bubble, cookie bar, WhatsApp button or storefront bot there. The primary button under the order total is Checkout, and on a phone the cart keeps a sticky checkout bar.\n- **R6. Checkout inputs carry `autocomplete` tokens**, a `name`, and `inputMode` for email and phone. The one exception is a Places typeahead on address line 1, which stays `autocomplete=\"off\"`. See `brainerce-checkout-flows`, `references/checkout.md`.\n\n## Don't burn the run\n\n**Do not start a dev server to prove the build works.** By default, no `npm run dev` to curl\npages, drive the cart, or open a headless browser. Correctness comes from following the\nreferences, and a headless run cannot complete an email verification or a real payment anyway, so\nthe loop costs minutes and returns almost no signal. Do it only when the user explicitly asks you\nto verify — and then keep it to a single pass that the pages compile and render. The one thing worth that single pass is the cart behaviour check (`https://brainerce.com/verify-storefront.mjs`, run by `brainerce-integration-verify`): when the user asks you to verify and you have a shell, run it once against the running store instead of driving the cart by hand.\n\n**Build against the empty catalog, and never trade an admin key for a fuller one.** A new store has no\nproducts, and you cannot create any with a `vc_` id: it is read-only over the catalog. Do not treat\nthat as a blocker and **do not ask for an admin key to fill it**. Render an honest empty state\nwhatever else happens, because the merchant can empty the catalog again tomorrow.\n\nThere is one way to put starter products in without an admin key, and it rides on the device\napproval: approving leaves a ten-minute, single-use seeding window that `POST /api/device-auth/seed`\nredeems with the same device code. **One rule: if the command performs the approval, it can seed,\nand the flag is always `--seed-products`.** The window is spent for you, every product it creates\nis also published to the new sales channel (so the storefront lists it at once, with no dashboard\nstep), and neither command ever hands you the code:\n\n```bash\n# 1. Inside a project scaffolded with --defer-connection. The preferred order:\n# the storefront already exists, so the catalog can match what you built.\nnpm run connect -- --seed-products \\\n  '[{\"name\":\"Ceramic Pour-Over 600ml\",\"basePrice\":149,\"description\":\"600ml glass carafe.\"}]'\n\n# 2. The scaffolder's own approval, when the user wants it live immediately.\nnpm create brainerce-store my-store -- --seed-products '[...]'\n```\n\nOne quoted JSON argument in both cases. If your shell mangles that quoting — PowerShell does —\nput the identical JSON in `BRAINERCE_SEED_PRODUCTS` instead; both read it, and the flag wins when\nboth are set. **Prefer the first**: the second wants the catalog before a single file exists,\nwhich is the same guess deferring the connection exists to avoid.\n\n**Read the report in three parts, not two.** Each command prints what was _seeded and published_\nby name, then any product that was _created but NOT published_ to this channel with its\n`publishError` (it exists in the store: publish it with `publish_product_to_channel` when you hold a\nBrainerce connector, otherwise from the dashboard, Products → the product → sales channels, and\nnever re-add it), then what was _not created_ with the reason. Relay all\nthree; a partial write said as a clean win is how a merchant finds three of five products missing\na week later.\n\n**Decide it before you run the connect command**: the window opens at the approval and closes with\nthat same command, so a second attempt costs the user a second approval. On the deferred order that\ndecision sits at the _end_ of the build, which is the better moment anyway.\n\n**`npm run connect` ends with a rebuild, not a deploy.** Besides writing the channel id it fetches\nthe store's real name and currency into `.env.local` (a deferred scaffold knew only the directory\nname and `USD`). Those are `NEXT_PUBLIC_*` values, inlined at build time, so run `npm run build`\nand restart any running `npm run dev` after it, before deploying — the script prints the same\nnotice when it finishes. The interface language is the one thing it does not change.\n\n**No approval, no seeding.** A run given a `vc_` id by the user, or one passing `--connection-id` /\n`BRAINERCE_CONNECTION_ID` / `--no-device`, never had a device code, and `--defer-connection` moves\nthe approval into `npm run connect` where the flag belongs instead. Every one of those combinations\nis refused up front, naming the command that would have worked, rather than connecting and dropping\nthe catalog silently.\n\nWhere no seeding happened, the catalog genuinely comes from the merchant: the dashboard, or\n**Apps → Migration Tool**. `references/seed-catalog.md` has the full route signature, the field\nlist, and the rules for both seeding paths. **Never invent a catalog for a user who did not\ndescribe one**, and never seed a store that already has products.\n\n## Mandatory features\n\nThe list lives at `skills/brainerce-integration-verify/references/required-features.md`, or comes from `get-required-features` when the MCP server is connected. You should already have read it (see \"Before the first line of code\"); keep it open while you build. Anything marked mandatory has to be reachable in the finished build even when the store has it switched off today, because those features hide themselves at runtime and the owner enables them later, so a build that omits one breaks the day the owner turns the feature on.\n\nFive highlights, chosen because they are the ones most often missed, not because they are the list: coupon input in the cart, email verification, password reset, the OAuth button area, and the reservation countdown.\n\nThe list says which features must exist. How the cart and checkout behave (R1 to R6 under \"Rules that cause incidents when skipped\") is a separate bar that the list does not repeat: `brainerce-integration-verify` checks both.\n\n`brainerce-integration-verify` audits a finished build against the same checklist. Run it before you call the build done, but it should be confirming coverage you already built, not the first time you see the list.\n\n## Design quality bar\n\nA store nobody wants to buy from is a failed run, whatever the SDK calls do. Read\n`references/design-quality-bar.md` before you style anything. The four that are not negotiable:\n\n- **Tokens only.** Define the semantic colour tokens first; never a literal colour in a class name.\n- **3 to 5 colours, 2 font families at most.** 1 brand colour, 2-3 neutrals, 1-2 accents.\n- **Contrast is a hard floor: WCAG 2.2 AA.** 4.5:1 body text, 3:1 large text and UI. Check the\n  actual hex pair against the ratio; a palette is not accessible because it looks fine on your\n  screen. This is the one rule that overrides explicit direction from the user.\n- **Real imagery, designed empty states.** Catalog photos do the work. No abstract filler shapes,\n  and no section left blank, which matters because a new store's catalog is empty on day one.\n\n## Hand the store over\n\nCompiling is not shipping. The moment your build is done the store still cannot take a single\norder: no payment provider is installed, there may be no shipping zone, and the catalog is empty or\nholds only the few starter products you seeded. None of that is reachable from code with a `vc_`\nid, and a headless storefront has no editor button, so unless you point the owner into the\ndashboard they have no obvious way into their own backend. End the run by saying what is left, in\nthis order.\n\n**In ChatGPT with the Brainerce app installed, or on any connection that lists `get_store_setup_status`, call it before you write the handoff**, and call it again whenever the merchant asks what is left, how to start selling, or whether the store is ready. It returns the six steps (store name, sales channel, products published to a channel, shipping, payment provider, tax), each done or not, with a `nextAction`, and a payment provider in test mode counts as not done. Then do from the conversation what the connector can do instead of sending the merchant to click, **after telling the merchant what you are about to change and getting a yes**: every call in this paragraph edits their live store, and none of them runs on your own initiative. `update_store` names the store (the consent window created it with whatever they typed; it also changes currency and language, and a currency change relabels every price without converting anything, so ask before touching it on a store with prices), `create_shipping_zone` plus `create_shipping_rate` add a delivery option, `publish_product_to_channel` makes each product visible on the channel you built against, and `set_variant_stock` fixes a count. Publish a catalog: `bulk_update_platforms({ filter: { status: 'active' }, vcPublishTo: [channel] })`; `vcPublishTo` accepts the channel id, its `vc_` id or its name. `list_tax_rates` then `create_tax_rate` add the rate the merchant gives you (never one you assume; `taxEnabled` alone charges 0 tax). Going live: `set_sales_channel_live({ channelId, domain, live: true })` records the public https domain and switches the channel to LIVE; the payment provider is still connected in the dashboard. Call it only once the storefront is deployed at that domain, because it records the address and deploys nothing, and a LIVE channel whose provider is still in TEST mode declines real cards. What stays a dashboard task, and must be said as one: connecting a payment provider and switching it live. The list below is the handoff for everything the tools cannot reach.\n\n**Brainerce does not host, and there is no deploy step.** Do not promise a live URL and do not\ninvent one. The developer deploys the project wherever they already chose; Brainerce is the\nbackend behind it. **The dashboard is `https://brainerce.com`.** Give them that link: everything\nbelow is a human step there, done by the merchant.\n\nIf they do host on Vercel, say one thing about speed (it is a latency setting, not a blocker): the **Vercel function region** should be `fra1`, next to the Brainerce API, set in `vercel.json` as `{ \"regions\": [\"fra1\"] }` (the scaffolded starter already ships it). Without it Vercel runs the proxy that every cart call passes through in the US, and each call pays roughly 300 to 450 ms more. This is where the server code runs. It has nothing to do with the commerce regions in item 2 below, which are a dashboard setting for prices and payment providers.\n\nBlocks an order outright, so it comes first:\n\n1. **Install a payment provider, and put it Live.** Apps → Browse → Payment Gateways → Install,\n   then connect the credentials. Installed is not enough: a provider sitting in Test mode takes no\n   real money, and switching it back to Live reopens the credentials form, which the merchant\n   cannot complete if the provider issued those keys to Brainerce directly.\n2. **Enable that provider for every region they sell to.** Settings → Regions. A provider that is\n   installed and Live but not enabled for the customer's region shows zero payment options at\n   checkout, which reads as the store being broken.\n3. **Create a shipping zone with at least one rate.** Shipping → Zones & Rates. An address no zone\n   matches is offered no delivery option, and the order stops there.\n4. **Get products in**, unless you already seeded a starter catalog through the device-auth window\n   (see `references/seed-catalog.md`), in which case name what you added — it is published to this\n   channel and already on the storefront — and say the rest is theirs. If that seed was partial,\n   name the ones that were refused too and say they still have to be added by hand; the window is\n   single use and cannot be reopened without a second approval. And if any came back\n   `published: false`, name those separately: they exist in the store and must not be re-added,\n   only published (`publish_product_to_channel` on a connector that lists it, otherwise Products →\n   the product → sales channels → toggle this channel on).\n   Otherwise they add products in the dashboard, or install **Apps → Migration Tool** for a one-time,\n   read-only import of products and orders from Shopify or WooCommerce. Never ask for a\n   `brainerce_` admin key to fill the catalog yourself.\n\nAlready built and shipped, but invisible until the merchant switches it on. Name the ones you\nwired, so nobody rebuilds what is already there:\n\n- Coupons and discount rules.\n- Gift card redemption at checkout. Wire it on every store, and say plainly that it is a **payment**, not a discount: the order total and its tax do not move, the amount due to the provider does.\n- OAuth sign-in buttons: Settings → Authentication → OAuth Providers.\n- Loyalty points, referrals, badges and paid membership.\n- Checkout custom fields, and back-in-stock alerts.\n- Additional languages.\n- Header, footer, announcement bar, FAQ, static pages and blog, all of which render from merchant\n  content and stay empty until there is some.\n\n## Response shape\n\n> ✓ Catalog and product pages are wired to your Brainerce store.\n>\n> Built: product listing with category filter, product detail with variant selection and modifier groups, cart with persistence across reloads.\n>\n> Not built yet, and all three are on the mandatory list: checkout, auth with email verification, order confirmation.\n>\n> Checkout next? It has a fixed sequence and I want to get it right rather than fast.\n\nWhen the run is finished rather than mid-way, that last line is the handoff instead:\n\n> Nothing left in code. The store cannot take an order until you do four things in the dashboard at https://brainerce.com: install a payment provider and put it Live (Apps → Payment Gateways), enable it for your regions (Settings → Regions), add a shipping zone with a rate (Shipping → Zones & Rates), and add products (or Apps → Migration Tool to import them). Coupons, gift card redemption, OAuth buttons, loyalty and the content-driven header, footer and pages are already wired and appear the moment you switch them on.\n\nWith the Brainerce app in ChatGPT the same handoff is shorter, because `get_store_setup_status` told you what is done and the tools closed most of the gaps:\n\n> Nothing left in code. I named the store, added a worldwide flat-rate shipping option, added the 18% VAT rate you gave me and published all twelve active products to your storefront channel. The channel is still in test mode: once the site is deployed, tell me the address and I will record it and switch the channel live. One thing only you can do before a real order goes through: connect a payment provider and put it Live, in the dashboard at https://brainerce.com under Apps → Payment Gateways.\n\n## Reference files in this skill\n\n- `references/discovery.md`: the one call that tells you what this store can actually do, and the contract to hold for the rest of the run. Read it first on any run against a real connection.\n- `references/setup.md`: client creation and configuration, the BFF proxy that `baseUrl` points at, and where to host it (the Vercel function region).\n- `references/products.md`: catalog, variants, modifier groups, product shape.\n- `references/critical-rules.md`: the rules above, in full, with examples.\n- `references/seo.md`: sitemap helpers, robots, structured data, slug redirects.\n- `references/i18n.md`: multi-language routing and locale resolution.\n- `references/connect-existing-frontend.md`: wiring real data into a frontend that already exists, without rebuilding it.\n- `references/seed-catalog.md`: the two ways to seed a starter catalog, the no-admin-key device-auth window (reachable via `--seed-products` on `npm run connect` or on the piped bootstrap, or by calling the route yourself) and the admin-key bulk import, when each is appropriate, and why you must never ask for an admin key to do it.\n- `references/account-cart-and-offers.md`: the account address book and linked social logins, order bumps and bundles, recommendations and nudges, the cart store (SDK 3.11.0 or newer) and the cart rules R1 to R3, the header cart badge and the cart teardown hooks, pre-checkout stock validation, first-party analytics, and guest download retrieval. Read it during steps 3, 4 and 6; these are shipped features a build silently omits.\n- `references/design-quality-bar.md`: the design bar every build is held to, including the WCAG 2.2 AA contrast floor and the cart behaviour rules. Framework independent; read it before styling anything.\n\nThe first five carry material sourced from the Brainerce MCP server's own content; when that server is connected, prefer its live tools, which reflect the specific store, and treat these as the source of truth where it is not, such as in ChatGPT. `connect-existing-frontend.md` is not MCP-sourced: it is retrofit-specific guidance authored for this skill, built on the same SDK facts the other files carry, and it applies the same way regardless of which surface is connected.\n\n## Cross-skill connections\n\n- One method's exact shape: `brainerce-sdk`.\n- Checkout, auth, cart and reservation sequences: `brainerce-checkout-flows`.\n- Auditing what you built: `brainerce-integration-verify`.\n- Content entries, navigation and blog, including the fact that page and rich-text HTML arrives unsanitized: `brainerce-content-and-navigation`.\n- Rendering custom fields and building a filter UI from the filterable ones: `brainerce-custom-fields`.\n\nRoute once, and do not bounce back and forth.\n"
}

SHA-256 of public snapshot: 0660c3c8c7dc06d90be0c2bb9619446cac84b75369756e079991b05afc1050e2