create-brainerce-store 1.72.0 → 1.74.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/dist/index.js +37 -4
  2. package/messages/en.json +30 -1
  3. package/messages/he.json +30 -1
  4. package/package.json +1 -1
  5. package/templates/nextjs/base/AGENTS.md.ejs +63 -16
  6. package/templates/nextjs/base/AI-GUIDE.md +17 -4
  7. package/templates/nextjs/base/CLAUDE.md.ejs +67 -20
  8. package/templates/nextjs/base/TRANSLATIONS.md +207 -207
  9. package/templates/nextjs/base/src/app/account/page.tsx +168 -122
  10. package/templates/nextjs/base/src/app/category/[slug]/page.tsx +10 -1
  11. package/templates/nextjs/base/src/app/checkout/page.tsx +1179 -1074
  12. package/templates/nextjs/base/src/app/layout.tsx.ejs +48 -4
  13. package/templates/nextjs/base/src/app/order-confirmation/page.tsx +98 -3
  14. package/templates/nextjs/base/src/app/products/[slug]/page.tsx +14 -2
  15. package/templates/nextjs/base/src/components/account/loyalty-panel.tsx +226 -0
  16. package/templates/nextjs/base/src/components/account/order-history.tsx +422 -371
  17. package/templates/nextjs/base/src/components/account/order-status-timeline.tsx +85 -85
  18. package/templates/nextjs/base/src/components/account/saved-payment-methods.tsx +104 -0
  19. package/templates/nextjs/base/src/components/checkout/checkout-form.tsx +618 -612
  20. package/templates/nextjs/base/src/components/checkout/custom-fields-step.tsx +354 -306
  21. package/templates/nextjs/base/src/components/checkout/tax-display.tsx +141 -74
  22. package/templates/nextjs/base/src/core/hooks/use-cart-page.ts +218 -127
  23. package/templates/nextjs/base/src/core/hooks/use-home-data.ts +63 -51
  24. package/templates/nextjs/base/src/core/hooks/use-product-listing.ts +379 -295
  25. package/templates/nextjs/base/src/core/hooks/use-product-page.ts +33 -1
  26. package/templates/nextjs/base/src/core/lib/capabilities.ts +65 -0
  27. package/templates/nextjs/base/src/core/lib/display-price.ts +139 -0
  28. package/templates/nextjs/base/src/core/lib/region.server.ts +112 -0
  29. package/templates/nextjs/base/src/core/lib/region.ts +112 -0
  30. package/templates/nextjs/base/src/core/lib/store-info.ts +19 -0
  31. package/templates/nextjs/base/src/core/providers/store-provider.tsx.ejs +423 -243
  32. package/templates/nextjs/base/src/ui/cart/cart-item.tsx +174 -164
  33. package/templates/nextjs/base/src/ui/cart/cart-summary.tsx +109 -110
  34. package/templates/nextjs/base/src/ui/cart/cart-view.tsx +219 -176
  35. package/templates/nextjs/base/src/ui/cart/gift-card-input.tsx +191 -0
  36. package/templates/nextjs/base/src/ui/cart/reservation-countdown.tsx +137 -137
  37. package/templates/nextjs/base/src/ui/cart/tax-estimate-line.tsx +108 -0
  38. package/templates/nextjs/base/src/ui/home/home-client.tsx +27 -29
  39. package/templates/nextjs/base/src/ui/layout/header-search.tsx +249 -0
  40. package/templates/nextjs/base/src/ui/layout/region-switcher.tsx +59 -0
  41. package/templates/nextjs/base/src/ui/layout/site-header.tsx.ejs +171 -152
  42. package/templates/nextjs/base/src/ui/product/frequently-bought-together.tsx +197 -191
  43. package/templates/nextjs/base/src/ui/product/product-card.tsx +25 -52
  44. package/templates/nextjs/base/src/ui/product/product-client-section.tsx +12 -3
  45. package/templates/nextjs/base/src/ui/product/product-listing.tsx +460 -446
  46. package/templates/nextjs/base/src/ui/product/recommendation-section.tsx +108 -102
  47. package/templates/nextjs/base/src/ui/product/review-form.tsx +33 -11
  48. package/templates/nextjs/base/src/ui/product/stock-badge.tsx +15 -3
  49. package/templates/nextjs/designs/atelier/app-overlay/layout.tsx.ejs +48 -4
  50. package/templates/nextjs/designs/atelier/messages-patch/en.json +21 -25
  51. package/templates/nextjs/designs/atelier/messages-patch/he.json +21 -25
  52. package/templates/nextjs/designs/atelier/ui/cart/cart-drawer.tsx +177 -181
  53. package/templates/nextjs/designs/atelier/ui/cart/cart-item.tsx +168 -158
  54. package/templates/nextjs/designs/atelier/ui/cart/cart-summary.tsx +106 -107
  55. package/templates/nextjs/designs/atelier/ui/cart/cart-view.tsx +229 -184
  56. package/templates/nextjs/designs/atelier/ui/cart/reservation-countdown.tsx +131 -131
  57. package/templates/nextjs/designs/atelier/ui/cart/tax-estimate-line.tsx +108 -0
  58. package/templates/nextjs/designs/atelier/ui/home/benefits-band.tsx +10 -1
  59. package/templates/nextjs/designs/atelier/ui/home/hero-section.tsx +178 -174
  60. package/templates/nextjs/designs/atelier/ui/home/home-client.tsx +4 -6
  61. package/templates/nextjs/designs/atelier/ui/home/newsletter-section.tsx +150 -78
  62. package/templates/nextjs/designs/atelier/ui/home/testimonials-band.tsx +79 -46
  63. package/templates/nextjs/designs/atelier/ui/layout/header-search.tsx +264 -0
  64. package/templates/nextjs/designs/atelier/ui/layout/region-switcher.tsx +44 -0
  65. package/templates/nextjs/designs/atelier/ui/layout/site-header.tsx.ejs +5 -0
  66. package/templates/nextjs/designs/atelier/ui/product/frequently-bought-together.tsx +202 -196
  67. package/templates/nextjs/designs/atelier/ui/product/product-card.tsx +27 -52
  68. package/templates/nextjs/designs/atelier/ui/product/product-client-section.tsx +12 -3
  69. package/templates/nextjs/designs/atelier/ui/product/product-listing.tsx +332 -260
  70. package/templates/nextjs/designs/atelier/ui/product/recommendation-section.tsx +101 -95
  71. package/templates/nextjs/designs/atelier/ui/product/review-form.tsx +30 -10
  72. package/templates/nextjs/designs/atelier/ui/product/stock-badge.tsx +17 -2
  73. package/templates/nextjs/designs/atelier/ui/shared/icons.tsx +9 -0
  74. package/templates/nextjs/ui-canvas/cart/cart-item.tsx +137 -137
  75. package/templates/nextjs/ui-canvas/cart/cart-summary.tsx +98 -99
  76. package/templates/nextjs/ui-canvas/cart/cart-view.tsx +140 -140
  77. package/templates/nextjs/ui-canvas/cart/gift-card-input.tsx +142 -0
  78. package/templates/nextjs/ui-canvas/cart/reservation-countdown.tsx +124 -124
  79. package/templates/nextjs/ui-canvas/cart/tax-estimate-line.tsx +104 -0
  80. package/templates/nextjs/ui-canvas/home/home-client.tsx +24 -26
  81. package/templates/nextjs/ui-canvas/layout/region-switcher.tsx +51 -0
  82. package/templates/nextjs/ui-canvas/layout/site-header.tsx.ejs +3 -0
  83. package/templates/nextjs/ui-canvas/product/frequently-bought-together.tsx +174 -168
  84. package/templates/nextjs/ui-canvas/product/product-card.tsx +9 -51
  85. package/templates/nextjs/ui-canvas/product/product-client-section.tsx +5 -3
  86. package/templates/nextjs/ui-canvas/product/recommendation-section.tsx +105 -99
  87. package/templates/nextjs/ui-canvas/product/review-form.tsx +9 -1
  88. package/templates/nextjs/ui-canvas/product/stock-badge.tsx +17 -2
package/dist/index.js CHANGED
@@ -31,7 +31,7 @@ var require_package = __commonJS({
31
31
  "package.json"(exports2, module2) {
32
32
  module2.exports = {
33
33
  name: "create-brainerce-store",
34
- version: "1.72.0",
34
+ version: "1.74.0",
35
35
  description: "Scaffold a production-ready e-commerce storefront connected to Brainerce",
36
36
  bin: {
37
37
  "create-brainerce-store": "dist/index.js"
@@ -235,7 +235,40 @@ var BRAINERCE_RUNTIME_DEPS = Object.freeze({
235
235
  // missing keys. 2.0 also stops forgotPassword sending `resetUrl`, which the
236
236
  // API rejects with 400 under forbidNonWhitelisted, so a scaffold on 1.x has
237
237
  // a broken password reset in the browser.
238
- brainerce: "^2.0.0",
238
+ // 2.0.1 exports the three review-photo types (`ReviewPhotoUpload`,
239
+ // `ProductReviewImage`, `ProductReviewImageAdmin`). They were declared but
240
+ // never exported from 1.63.0 onwards, and the scaffolded review form imports
241
+ // `ReviewPhotoUpload` by name, so on any earlier 2.x every scaffolded store
242
+ // failed `tsc` outright. This is why the pin is ^2.0.1 and not ^2.0.0.
243
+ //
244
+ // RELEASE ORDER: npm must already carry a version satisfying this range
245
+ // before the CLI is published, or every scaffold dies at install on an
246
+ // unsatisfiable range. Publish the SDK first, then the CLI. That is what
247
+ // happened for 1.73.0 (brainerce 2.0.2 at 06:42:53Z, the CLI 26 seconds
248
+ // later), so this is a standing rule, not an open problem.
249
+ //
250
+ // Note that brainerce 2.0.1 was never published: the SDK went 2.0.0 ->
251
+ // 2.0.2. Do not "fix" any range here to an exact 2.0.1, which would resolve
252
+ // to nothing at all.
253
+ // 2.1.0 adds the gift-card redemption seam the scaffolded checkout now
254
+ // depends on: `applyGiftCard()` and `removeGiftCard()` on the client, and
255
+ // `tenders` + `providerAmountDue` on `Checkout`. The checkout page renders
256
+ // the applied cards and pays out `providerAmountDue` beside the total, and
257
+ // `gift-card-input.tsx` types its prop as `NonNullable<Checkout['tenders']>`,
258
+ // so on 2.0.2 every scaffolded store fails `tsc` on a missing method AND a
259
+ // missing property. That is why the floor moved off ^2.0.1.
260
+ //
261
+ // (The prop deliberately derives from `Checkout` rather than importing the
262
+ // exported `CheckoutTender`: that type is the APPLY response and carries a
263
+ // third field, `providerAmountDue`, which a checkout read reports once at the
264
+ // top level instead of per card. Typing the prop as `CheckoutTender[]` does
265
+ // not compile against `checkout.tenders`.)
266
+ //
267
+ // ⛔ 2.1.0 IS NOT PUBLISHED YET (npm latest is 2.0.2). Per the RELEASE ORDER
268
+ // rule above, publishing this CLI before the SDK makes the range
269
+ // unsatisfiable and kills every scaffold at install. Publish brainerce
270
+ // 2.1.0 first, confirm it on the registry, then publish the CLI.
271
+ brainerce: "^2.1.0",
239
272
  "isomorphic-dompurify": "^3.8.0"
240
273
  });
241
274
 
@@ -976,13 +1009,13 @@ program.name("create-brainerce-store").description("Scaffold a production-ready
976
1009
  const channelSlug = storeInfo ? slugify(storeInfo.name) : "";
977
1010
  const storeSlug = storeInfo ? slugify(storeInfo.storeName) : "";
978
1011
  const projectNameSuggestion = channelSlug || storeSlug || void 0;
979
- const languageDefault = language || storeInfo?.language;
1012
+ language = language || storeInfo?.language;
980
1013
  if (!projectName || !connectionId || !language) {
981
1014
  const answers = await runInteractive({
982
1015
  projectName,
983
1016
  projectNameSuggestion,
984
1017
  connectionId,
985
- language: languageDefault,
1018
+ language,
986
1019
  framework,
987
1020
  design,
988
1021
  pkgManager,
package/messages/en.json CHANGED
@@ -19,6 +19,7 @@
19
19
  "pickup": "Pickup",
20
20
  "tax": "Tax",
21
21
  "taxIncl": "Tax (incl.)",
22
+ "inclSuffix": "incl.",
22
23
  "sale": "Sale",
23
24
  "remove": "Remove",
24
25
  "removing": "Removing...",
@@ -59,7 +60,9 @@
59
60
  "monthSeptember": "September",
60
61
  "monthOctober": "October",
61
62
  "monthNovember": "November",
62
- "monthDecember": "December"
63
+ "monthDecember": "December",
64
+ "giftCard": "Gift card",
65
+ "amountDue": "Amount due"
63
66
  },
64
67
  "nav": {
65
68
  "products": "Products",
@@ -154,6 +157,9 @@
154
157
  "submitReview": "Submit review",
155
158
  "addPhotos": "Add photos",
156
159
  "removePhoto": "Remove photo",
160
+ "choosePhotos": "Choose photos",
161
+ "photoFormats": "JPG, PNG, WebP or GIF, up to {mb}MB each.",
162
+ "photoLimitReached": "That is all {max} photos. Remove one to add another.",
157
163
  "photoUploading": "Uploading…",
158
164
  "photoTooLarge": "That photo is too large. Please pick a smaller one.",
159
165
  "photoUploadFailed": "Could not upload that photo. Please try another.",
@@ -556,10 +562,33 @@
556
562
  "discountCode": "Your code: {code}",
557
563
  "genericError": "Something went wrong. Please try again."
558
564
  },
565
+ "loyalty": {
566
+ "title": "Rewards",
567
+ "pointsFallback": "points",
568
+ "readyToSpend": "Ready to spend. Points from a recent order become available after they clear.",
569
+ "earningPaused": "The rewards programme is paused, so orders are not earning right now. Points you already have can still be spent.",
570
+ "toNextTierPoints": "{amount} {pointsName} to {tier}",
571
+ "toNextTierSpend": "{amount} more spent to reach {tier}",
572
+ "rewardsTitle": "Redeem your points",
573
+ "pointsCost": "{points} {pointsName}",
574
+ "tierLocked": "Unlocks at a higher tier",
575
+ "redeem": "Redeem",
576
+ "redeeming": "Redeeming...",
577
+ "notEnoughPoints": "Not enough points",
578
+ "yourCode": "Your code",
579
+ "applyAtCheckout": "Enter it at checkout to get the discount.",
580
+ "redeemError": "We could not redeem that. Please try again."
581
+ },
559
582
  "content": {
560
583
  "faqTitle": "Frequently Asked Questions",
561
584
  "faqEmptyTitle": "FAQ coming soon",
562
585
  "faqEmptyBody": "We're still putting together answers to common questions. In the meantime, feel free to reach out.",
563
586
  "faqContactCta": "Contact us"
587
+ },
588
+ "giftCard": {
589
+ "placeholder": "Gift card code",
590
+ "invalidCode": "That gift card code cannot be used on this order.",
591
+ "removeFailed": "We could not remove that gift card.",
592
+ "applied": "Gift card applied — {amount}"
564
593
  }
565
594
  }
package/messages/he.json CHANGED
@@ -19,6 +19,7 @@
19
19
  "pickup": "איסוף",
20
20
  "tax": "מע\"מ",
21
21
  "taxIncl": "כולל מע\"מ",
22
+ "inclSuffix": "כלול",
22
23
  "sale": "מבצע",
23
24
  "remove": "הסרה",
24
25
  "removing": "מסיר...",
@@ -59,7 +60,9 @@
59
60
  "monthSeptember": "ספטמבר",
60
61
  "monthOctober": "אוקטובר",
61
62
  "monthNovember": "נובמבר",
62
- "monthDecember": "דצמבר"
63
+ "monthDecember": "דצמבר",
64
+ "giftCard": "כרטיס מתנה",
65
+ "amountDue": "לתשלום"
63
66
  },
64
67
  "nav": {
65
68
  "products": "מוצרים",
@@ -154,6 +157,9 @@
154
157
  "submitReview": "שליחת ביקורת",
155
158
  "addPhotos": "הוספת תמונות",
156
159
  "removePhoto": "הסרת תמונה",
160
+ "choosePhotos": "בחירת תמונות",
161
+ "photoFormats": "JPG, PNG, WebP או GIF, עד {mb}MB לכל תמונה.",
162
+ "photoLimitReached": "אלה כל {max} התמונות. הסר אחת כדי להוסיף אחרת.",
157
163
  "photoUploading": "מעלה...",
158
164
  "photoTooLarge": "התמונה הזו גדולה מדי. בחרו תמונה קטנה יותר.",
159
165
  "photoUploadFailed": "לא הצלחנו להעלות את התמונה. נסו תמונה אחרת.",
@@ -556,10 +562,33 @@
556
562
  "discountCode": "הקוד שלכם: {code}",
557
563
  "genericError": "משהו השתבש. נסו שוב."
558
564
  },
565
+ "loyalty": {
566
+ "title": "מועדון הטבות",
567
+ "pointsFallback": "נקודות",
568
+ "readyToSpend": "זמינות למימוש. נקודות מהזמנה אחרונה יהפכו לזמינות לאחר תקופת המתנה.",
569
+ "earningPaused": "תוכנית ההטבות מושהית, ולכן הזמנות לא צוברות נקודות כרגע. את הנקודות שכבר צברת ניתן לממש.",
570
+ "toNextTierPoints": "{amount} {pointsName} עד {tier}",
571
+ "toNextTierSpend": "עוד {amount} בקניות כדי להגיע ל-{tier}",
572
+ "rewardsTitle": "מימוש נקודות",
573
+ "pointsCost": "{points} {pointsName}",
574
+ "tierLocked": "נפתח בדרגה גבוהה יותר",
575
+ "redeem": "מימוש",
576
+ "redeeming": "מממש...",
577
+ "notEnoughPoints": "אין מספיק נקודות",
578
+ "yourCode": "הקוד שלך",
579
+ "applyAtCheckout": "הזינו אותו בצ׳קאאוט כדי לקבל את ההנחה.",
580
+ "redeemError": "לא הצלחנו לממש. נסו שוב."
581
+ },
559
582
  "content": {
560
583
  "faqTitle": "שאלות נפוצות",
561
584
  "faqEmptyTitle": "השאלות הנפוצות בדרך",
562
585
  "faqEmptyBody": "אנחנו עוד אוספים את התשובות לשאלות הנפוצות. בינתיים, אתם מוזמנים לפנות אלינו.",
563
586
  "faqContactCta": "צרו קשר"
587
+ },
588
+ "giftCard": {
589
+ "placeholder": "קוד כרטיס מתנה",
590
+ "invalidCode": "לא ניתן להשתמש בקוד הזה בהזמנה הזאת.",
591
+ "removeFailed": "לא הצלחנו להסיר את כרטיס המתנה.",
592
+ "applied": "כרטיס מתנה — {amount}"
564
593
  }
565
594
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-brainerce-store",
3
- "version": "1.72.0",
3
+ "version": "1.74.0",
4
4
  "description": "Scaffold a production-ready e-commerce storefront connected to Brainerce",
5
5
  "bin": {
6
6
  "create-brainerce-store": "dist/index.js"
@@ -20,11 +20,16 @@ Platform docs (endpoints, SDK, integration recipes): https://brainerce.com/docs
20
20
 
21
21
  ## MCP servers
22
22
 
23
- - **`brainerce-docs`** already connected via `.mcp.json`, no auth needed.
24
- A live SDK/docs oracle: current SDK method shapes, type definitions, code
25
- examples, and this store's actual capabilities/config. Prefer it over
26
- guessing or relying on training data it reflects what's actually toggled
27
- on for `<%- connectionId %>` right now.
23
+ - **`brainerce-docs`** (already connected via `.mcp.json`, no auth needed).
24
+ Treat it as the build spec, not a lookup desk. `get-required-features` is
25
+ the functional checklist this store is measured against, and it is longer
26
+ than what any art-direction brief would make you think to build.
27
+ `get-critical-rules` and `get-business-flows` carry the sequences that cause
28
+ incidents when reordered. `get-sdk-docs`, `get-type-definitions` and
29
+ `get-code-example` give current method shapes instead of training-data
30
+ guesses, and `get-store-capabilities` reports what is actually toggled on
31
+ for `<%- connectionId %>` right now. Read the checklist before you start,
32
+ and again before you call the work done.
28
33
  - **Brainerce Admin MCP** — opt-in, not wired up by default. Lets an agent
29
34
  directly manage this store's *live* data (products, orders, discounts,
30
35
  shipping, …) instead of just reading docs. Only add it if the merchant
@@ -35,25 +40,59 @@ Platform docs (endpoints, SDK, integration recipes): https://brainerce.com/docs
35
40
  Treat it like handing the agent write access to production commerce data.
36
41
 
37
42
  **Before building any feature the merchant asks for** (loyalty points,
38
- shipping zones, subscriptions, gift cards, multi-currency, reviews,
43
+ shipping zones, subscriptions, gift cards, donations, multi-currency, reviews,
39
44
  abandoned-cart recovery, etc.) — check the docs first. Brainerce likely
40
45
  already has it as a platform capability (dashboard toggle + hook/SDK
41
46
  method) that only needs a UI in `src/ui/`, not a feature built from scratch.
42
47
 
43
- Your job here is almost always **design**.
48
+ Your job here is almost always **design**. It is never *only* design: the
49
+ coverage checklist in `get-required-features` applies to a redesign exactly as
50
+ it applies to a build from scratch.
44
51
 
45
52
  ## The one rule
46
53
 
47
54
  **`src/core/` is the platform's. `src/ui/` is yours.**
48
55
 
49
- The shipped `src/ui/` is a working reference, not a design to preserve
50
- full delete-and-rebuild of ui files is encouraged and expected.
51
- Rewrite anything under `src/ui/` and `src/app/globals.css` as boldly as you
52
- like the store keeps working. Never modify `src/core/`, `src/app/api/`, or
56
+ The shipped `src/ui/` is a working reference, not a design to preserve: a full
57
+ delete-and-rebuild of the *look* is encouraged and expected, and you can
58
+ rewrite anything under `src/ui/` and `src/app/globals.css` as boldly as you
59
+ like. The store keeps working. Never modify `src/core/`, `src/app/api/`, or
53
60
  the checkout/auth/account components. Data and behavior come exclusively from
54
- `@/core/hooks/*` and `@/core/providers/store-provider` hooks return state
61
+ `@/core/hooks/*` and `@/core/providers/store-provider`: hooks return state
55
62
  and handlers, never JSX. Never hardcode catalog content.
56
63
 
64
+ ### Rebuilding the look is free. Dropping a feature is not.
65
+
66
+ Some files under `src/ui/` are the ONLY place a mandatory checklist entry
67
+ exists in this project. Delete one and the capability leaves the store with
68
+ nothing to notice it by: no type error, no console warning, and no visual hole
69
+ either, because these components auto-hide while the merchant has the feature
70
+ switched off, so a deleted one and an idle one look identical on the page.
71
+ These are the usual casualties of a redesign, because no art-direction brief
72
+ asks for them by name:
73
+
74
+ ```
75
+ product/ back-in-stock-form · customization-fields · modifier-group-selector
76
+ review-form · reviews-section · frequently-bought-together
77
+ discount-badge · stock-badge
78
+ cart/ reservation-countdown · coupon-input · cart-upgrade-banner
79
+ cart-bundle-offer · tax-estimate-line
80
+ home/ discount-banner-strip
81
+ layout/ newsletter-signup · announcement-bar · region-switcher<% if (i18nEnabled) { %>
82
+ language-switcher<% } %> · faq-section · rich-text-block
83
+ ```
84
+
85
+ Restyle them, re-lay them out, rename them, fold them into other components,
86
+ split them in half: all fine. What has to survive a rebuild is the SDK call
87
+ each one makes and the states it handles (loading, empty, failed, and the
88
+ merchant-has-it-off state that renders nothing).
89
+
90
+ The list is short on purpose and it is NOT the specification. It names the
91
+ files people lose, not every mandatory entry. `get-required-features` is the
92
+ specification, and step 1 of "Verify before declaring done" is what actually
93
+ catches a loss. `git show HEAD:src/ui/<path>` brings back anything you already
94
+ deleted: the scaffolder committed the tree before you touched it.
95
+
57
96
  **Read `AI-GUIDE.md` before any redesign** — it has the full file map, hook
58
97
  contracts, motion language, and hard-won RTL/i18n gotchas that will save you
59
98
  real debugging time.
@@ -99,11 +138,19 @@ development and on any host with nothing configured.
99
138
 
100
139
  ## Verify before declaring done
101
140
 
102
- 1. `pnpm exec tsc --noEmit` 0 errors
103
- 2. `pnpm dev` drive the changed flow in a real browser (home → product →
141
+ 1. **Feature coverage, first and always.** Call `get-required-features` on the
142
+ `brainerce-docs` MCP server (already wired, nothing to set up) and confirm
143
+ every mandatory entry is still reachable in the running store. Do this
144
+ before the steps below, because if you rebuilt `src/ui/` a feature that
145
+ lived only in the shipped reference is now gone, and no other check can see
146
+ it: `tsc` cannot see a missing feature, and the component that used to
147
+ carry it auto-hid when the merchant had not switched it on, so the page
148
+ looks right either way.
149
+ 2. `pnpm exec tsc --noEmit` → 0 errors
150
+ 3. `pnpm dev` → drive the changed flow in a real browser (home → product →
104
151
  add to cart → cart)
105
- 3. Screenshot desktop (1440px) and mobile (390px)
106
- 4. RTL stores: check anchoring and arrow directions
152
+ 4. Screenshot desktop (1440px) and mobile (390px)
153
+ 5. RTL stores: check anchoring and arrow directions
107
154
 
108
155
  ## i18n
109
156
 
@@ -68,11 +68,20 @@ images, stock) comes from them — **never hardcode products**.
68
68
 
69
69
  ## Verification loop (before you declare anything done)
70
70
 
71
- 1. `pnpm exec tsc --noEmit` must be 0.
72
- 2. `pnpm dev` drive the real flow you changed: home listing → product →
71
+ 1. **Feature coverage.** Call `get-required-features` on the `brainerce-docs`
72
+ MCP server (wired by the scaffolder in `.mcp.json`, no setup) and confirm
73
+ every mandatory entry is still reachable. First step, not last: you were
74
+ invited to rewrite `src/ui/` from scratch, and a feature that lived only in
75
+ the shipped reference is gone now with nothing to notice it by. `tsc`
76
+ cannot see a missing feature, and these components render nothing while the
77
+ merchant has the feature off, so a deleted one and an idle one look the
78
+ same. `CLAUDE.md` lists the files people usually lose; the MCP tool is the
79
+ actual specification.
80
+ 2. `pnpm exec tsc --noEmit` → must be 0.
81
+ 3. `pnpm dev` → drive the real flow you changed: home → listing → product →
73
82
  add to cart → cart → checkout page renders.
74
- 3. Screenshot desktop (1440) AND mobile (390), in the store's language.
75
- 4. If the store is RTL: check nothing is left-anchored that should be
83
+ 4. Screenshot desktop (1440) AND mobile (390), in the store's language.
84
+ 5. If the store is RTL: check nothing is left-anchored that should be
76
85
  right-anchored, and directional arrows point with the reading direction.
77
86
 
78
87
  ## The quality bar (distilled from Lovable / v0 / Bolt system prompts)
@@ -163,6 +172,10 @@ attention, confirms an action, or rewards exploration. Rules:
163
172
  - Remove accessibility attributes (`aria-*`, `role`, `alt`, focus styles).
164
173
  - Hardcode catalog content, prices, or currency symbols.
165
174
  - Swallow the add-to-cart / checkout error states — restyle them, keep them.
175
+ - Drop a `src/ui/` component that is the only place a mandatory feature
176
+ exists. Rebuilding the look is free; losing the SDK call inside it is not,
177
+ and it is silent. See "Rebuilding the look is free" in `CLAUDE.md` for the
178
+ files people usually lose, and `get-required-features` for the real list.
166
179
  - Introduce new runtime dependencies without flagging it.
167
180
 
168
181
  ## Adding things
@@ -20,11 +20,16 @@ Platform docs (endpoints, SDK, integration recipes): https://brainerce.com/docs
20
20
 
21
21
  ## MCP servers
22
22
 
23
- - **`brainerce-docs`** already connected via `.mcp.json`, no auth needed.
24
- A live SDK/docs oracle: current SDK method shapes, type definitions, code
25
- examples, and this store's actual capabilities/config. Prefer it over
26
- guessing or relying on training data it reflects what's actually toggled
27
- on for `<%- connectionId %>` right now.
23
+ - **`brainerce-docs`** (already connected via `.mcp.json`, no auth needed).
24
+ Treat it as the build spec, not a lookup desk. `get-required-features` is
25
+ the functional checklist this store is measured against, and it is longer
26
+ than what any art-direction brief would make you think to build.
27
+ `get-critical-rules` and `get-business-flows` carry the sequences that cause
28
+ incidents when reordered. `get-sdk-docs`, `get-type-definitions` and
29
+ `get-code-example` give current method shapes instead of training-data
30
+ guesses, and `get-store-capabilities` reports what is actually toggled on
31
+ for `<%- connectionId %>` right now. Read the checklist before you start,
32
+ and again before you call the work done.
28
33
  - **Brainerce Admin MCP** — opt-in, not wired up by default. Lets an agent
29
34
  directly manage this store's *live* data (products, orders, discounts,
30
35
  shipping, …) instead of just reading docs. Only add it if the merchant
@@ -35,26 +40,60 @@ Platform docs (endpoints, SDK, integration recipes): https://brainerce.com/docs
35
40
  Treat it like handing the agent write access to production commerce data.
36
41
 
37
42
  **Before building any feature the merchant asks for** (loyalty points,
38
- shipping zones, subscriptions, gift cards, multi-currency, reviews,
43
+ shipping zones, subscriptions, gift cards, donations, multi-currency, reviews,
39
44
  abandoned-cart recovery, etc.) — check the docs first. Brainerce likely
40
45
  already has it as a platform capability (dashboard toggle + hook/SDK
41
46
  method) that only needs a UI in `src/ui/`, not a feature built from scratch.
42
47
 
43
- Your job here is almost always **design**.
48
+ Your job here is almost always **design**. It is never *only* design: the
49
+ coverage checklist in `get-required-features` applies to a redesign exactly as
50
+ it applies to a build from scratch.
44
51
 
45
52
  ## The one rule
46
53
 
47
54
  **`src/core/` is the platform's. `src/ui/` is yours.**
48
55
 
49
- The shipped `src/ui/` is a working reference, not a design to preserve
50
- full delete-and-rebuild of ui files is encouraged and expected. (Stores
51
- scaffolded with `--canvas` ship `src/ui/` as bare unstyled skeletons —
52
- there is no reference look at all; the design is entirely yours to create.)
53
- Rewrite anything under `src/ui/` and `src/app/globals.css` as boldly as you
54
- like the store keeps working. Never modify `src/core/`, `src/app/api/`, or
55
- the checkout/auth/account components. Data and behavior come exclusively from
56
- `@/core/hooks/*` and `@/core/providers/store-provider` hooks return state
57
- and handlers, never JSX. Never hardcode catalog content.
56
+ The shipped `src/ui/` is a working reference, not a design to preserve: a full
57
+ delete-and-rebuild of the *look* is encouraged and expected, and you can
58
+ rewrite anything under `src/ui/` and `src/app/globals.css` as boldly as you
59
+ like. The store keeps working. (Stores scaffolded with `--canvas` ship
60
+ `src/ui/` as bare unstyled skeletons, so there is no reference look at all and
61
+ the design is entirely yours to create.) Never modify `src/core/`,
62
+ `src/app/api/`, or the checkout/auth/account components. Data and behavior come
63
+ exclusively from `@/core/hooks/*` and `@/core/providers/store-provider`: hooks
64
+ return state and handlers, never JSX. Never hardcode catalog content.
65
+
66
+ ### Rebuilding the look is free. Dropping a feature is not.
67
+
68
+ Some files under `src/ui/` are the ONLY place a mandatory checklist entry
69
+ exists in this project. Delete one and the capability leaves the store with
70
+ nothing to notice it by: no type error, no console warning, and no visual hole
71
+ either, because these components auto-hide while the merchant has the feature
72
+ switched off, so a deleted one and an idle one look identical on the page.
73
+ These are the usual casualties of a redesign, because no art-direction brief
74
+ asks for them by name:
75
+
76
+ ```
77
+ product/ back-in-stock-form · customization-fields · modifier-group-selector
78
+ review-form · reviews-section · frequently-bought-together
79
+ discount-badge · stock-badge
80
+ cart/ reservation-countdown · coupon-input · cart-upgrade-banner
81
+ cart-bundle-offer · tax-estimate-line
82
+ home/ discount-banner-strip
83
+ layout/ newsletter-signup · announcement-bar · region-switcher<% if (i18nEnabled) { %>
84
+ language-switcher<% } %> · faq-section · rich-text-block
85
+ ```
86
+
87
+ Restyle them, re-lay them out, rename them, fold them into other components,
88
+ split them in half: all fine. What has to survive a rebuild is the SDK call
89
+ each one makes and the states it handles (loading, empty, failed, and the
90
+ merchant-has-it-off state that renders nothing).
91
+
92
+ The list is short on purpose and it is NOT the specification. It names the
93
+ files people lose, not every mandatory entry. `get-required-features` is the
94
+ specification, and step 1 of "Verify before declaring done" is what actually
95
+ catches a loss. `git show HEAD:src/ui/<path>` brings back anything you already
96
+ deleted: the scaffolder committed the tree before you touched it.
58
97
 
59
98
  **Read `AI-GUIDE.md` before any redesign** — it has the full file map, hook
60
99
  contracts, motion language, and hard-won RTL/i18n gotchas that will save you
@@ -110,11 +149,19 @@ development and on any host with nothing configured.
110
149
 
111
150
  ## Verify before declaring done
112
151
 
113
- 1. `pnpm exec tsc --noEmit` 0 errors
114
- 2. `pnpm dev` drive the changed flow in a real browser (home → product →
152
+ 1. **Feature coverage, first and always.** Call `get-required-features` on the
153
+ `brainerce-docs` MCP server (already wired, nothing to set up) and confirm
154
+ every mandatory entry is still reachable in the running store. Do this
155
+ before the steps below, because if you rebuilt `src/ui/` a feature that
156
+ lived only in the shipped reference is now gone, and no other check can see
157
+ it: `tsc` cannot see a missing feature, and the component that used to
158
+ carry it auto-hid when the merchant had not switched it on, so the page
159
+ looks right either way.
160
+ 2. `pnpm exec tsc --noEmit` → 0 errors
161
+ 3. `pnpm dev` → drive the changed flow in a real browser (home → product →
115
162
  add to cart → cart)
116
- 3. Screenshot desktop (1440px) and mobile (390px)
117
- 4. RTL stores: check anchoring and arrow directions
163
+ 4. Screenshot desktop (1440px) and mobile (390px)
164
+ 5. RTL stores: check anchoring and arrow directions
118
165
 
119
166
  ## i18n
120
167