@wix/agent-skills 1.0.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 (220) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +111 -0
  3. package/package.json +29 -0
  4. package/skills/wix-app/SKILL.md +344 -0
  5. package/skills/wix-app/references/APP_IDENTIFIERS.md +35 -0
  6. package/skills/wix-app/references/APP_MARKET_REVIEW.md +311 -0
  7. package/skills/wix-app/references/APP_VALIDATION.md +171 -0
  8. package/skills/wix-app/references/BACKEND_API.md +233 -0
  9. package/skills/wix-app/references/BACKEND_EVENT.md +116 -0
  10. package/skills/wix-app/references/CODE_QUALITY.md +33 -0
  11. package/skills/wix-app/references/CUSTOM_ELEMENT_WIDGET.md +587 -0
  12. package/skills/wix-app/references/DASHBOARD_MENU_PLUGIN.md +157 -0
  13. package/skills/wix-app/references/DASHBOARD_MODAL.md +283 -0
  14. package/skills/wix-app/references/DASHBOARD_PAGE.md +403 -0
  15. package/skills/wix-app/references/DASHBOARD_PLUGIN.md +205 -0
  16. package/skills/wix-app/references/DATA_COLLECTION.md +451 -0
  17. package/skills/wix-app/references/DOCUMENTATION.md +42 -0
  18. package/skills/wix-app/references/EDITOR_REACT_COMPONENT.md +65 -0
  19. package/skills/wix-app/references/EMBEDDED_SCRIPT.md +468 -0
  20. package/skills/wix-app/references/EXTENSION_REGISTRATION.md +96 -0
  21. package/skills/wix-app/references/SERVICE_PLUGIN.md +235 -0
  22. package/skills/wix-app/references/SITE_PLUGIN.md +436 -0
  23. package/skills/wix-app/references/STORES_VERSIONING.md +334 -0
  24. package/skills/wix-app/references/backend-event/COMMON-EVENTS.md +84 -0
  25. package/skills/wix-app/references/custom-element-widget/SETTINGS_PANEL.md +345 -0
  26. package/skills/wix-app/references/dashboard-menu-plugin/blog-slots.md +71 -0
  27. package/skills/wix-app/references/dashboard-menu-plugin/bookings-slots.md +58 -0
  28. package/skills/wix-app/references/dashboard-menu-plugin/crm-slots.md +8 -0
  29. package/skills/wix-app/references/dashboard-menu-plugin/ecommerce-slots.md +17 -0
  30. package/skills/wix-app/references/dashboard-menu-plugin/events-slots.md +29 -0
  31. package/skills/wix-app/references/dashboard-menu-plugin/restaurants-slots.md +27 -0
  32. package/skills/wix-app/references/dashboard-menu-plugin/stores-slots.md +35 -0
  33. package/skills/wix-app/references/dashboard-page/API_SPEC.md +138 -0
  34. package/skills/wix-app/references/dashboard-page/DASHBOARD_API.md +573 -0
  35. package/skills/wix-app/references/dashboard-page/DYNAMIC_PARAMETERS.md +269 -0
  36. package/skills/wix-app/references/dashboard-page/ECOM_NAVIGATION.md +164 -0
  37. package/skills/wix-app/references/dashboard-plugin/SLOTS.md +294 -0
  38. package/skills/wix-app/references/data-collection/WIX_DATA.md +270 -0
  39. package/skills/wix-app/references/data-collection/extension-template.ts +107 -0
  40. package/skills/wix-app/references/editor-react-component/ACCESSIBILITY.md +138 -0
  41. package/skills/wix-app/references/editor-react-component/COMPONENT-API.md +454 -0
  42. package/skills/wix-app/references/editor-react-component/COMPONENT-CONFIGURATION.md +165 -0
  43. package/skills/wix-app/references/editor-react-component/CSS-GUIDELINES.md +576 -0
  44. package/skills/wix-app/references/editor-react-component/DIRECTIONALITY.md +170 -0
  45. package/skills/wix-app/references/editor-react-component/EDIT-FLOW.md +6 -0
  46. package/skills/wix-app/references/editor-react-component/PARTS.md +25 -0
  47. package/skills/wix-app/references/editor-react-component/PROPS-VS-CSS.md +203 -0
  48. package/skills/wix-app/references/editor-react-component/REACT-GUIDELINES.md +167 -0
  49. package/skills/wix-app/references/editor-react-component/REACT-PATTERNS.md +137 -0
  50. package/skills/wix-app/references/service-plugin/ADDITIONAL-FEES.md +112 -0
  51. package/skills/wix-app/references/service-plugin/BOOKINGS-STAFF-SORTING.md +118 -0
  52. package/skills/wix-app/references/service-plugin/DISCOUNT-TRIGGERS.md +87 -0
  53. package/skills/wix-app/references/service-plugin/GIFT-CARDS.md +86 -0
  54. package/skills/wix-app/references/service-plugin/PAYMENT-SETTINGS.md +135 -0
  55. package/skills/wix-app/references/service-plugin/SHIPPING-RATES.md +79 -0
  56. package/skills/wix-app/references/service-plugin/VALIDATIONS.md +68 -0
  57. package/skills/wix-app/references/site-plugin/EXAMPLES.md +311 -0
  58. package/skills/wix-app/references/site-plugin/SLOTS.md +263 -0
  59. package/skills/wix-design-system/SKILL.md +129 -0
  60. package/skills/wix-design-system/references/file-structure.md +56 -0
  61. package/skills/wix-design-system/scripts/wds.cjs +531 -0
  62. package/skills/wix-headless/SKILL.md +418 -0
  63. package/skills/wix-headless/references/DISCOVERY.md +332 -0
  64. package/skills/wix-headless/references/ORCHESTRATION.md +269 -0
  65. package/skills/wix-headless/references/SETUP.md +154 -0
  66. package/skills/wix-headless/references/blog/BLOG_CONTENT.md +152 -0
  67. package/skills/wix-headless/references/blog/BLOG_PAGES.md +299 -0
  68. package/skills/wix-headless/references/blog/BLOG_SETUP.md +218 -0
  69. package/skills/wix-headless/references/blog/INSTRUCTIONS.md +32 -0
  70. package/skills/wix-headless/references/cms/CMS_FOUNDATIONS.md +373 -0
  71. package/skills/wix-headless/references/cms/FAQ_KNOWLEDGE_BASE.md +229 -0
  72. package/skills/wix-headless/references/cms/INSTRUCTIONS.md +40 -0
  73. package/skills/wix-headless/references/cms/PORTFOLIO.md +454 -0
  74. package/skills/wix-headless/references/cms/RESOURCE_LIBRARY.md +356 -0
  75. package/skills/wix-headless/references/cms/TEAM_DIRECTORY.md +299 -0
  76. package/skills/wix-headless/references/commands/install-app.md +42 -0
  77. package/skills/wix-headless/references/commands/known-apps.json +5 -0
  78. package/skills/wix-headless/references/commands/mcp-bootstrap.md +28 -0
  79. package/skills/wix-headless/references/designer/INSTRUCTIONS.md +828 -0
  80. package/skills/wix-headless/references/ecom/CART_PAGES.md +120 -0
  81. package/skills/wix-headless/references/ecom/CART_WIRING.md +103 -0
  82. package/skills/wix-headless/references/ecom/COMPONENTS_CSS.md +132 -0
  83. package/skills/wix-headless/references/ecom/INSTRUCTIONS.md +59 -0
  84. package/skills/wix-headless/references/forms/CONTACT_FORM.md +477 -0
  85. package/skills/wix-headless/references/forms/INSTRUCTIONS.md +43 -0
  86. package/skills/wix-headless/references/gift-cards/COMPONENTS.md +119 -0
  87. package/skills/wix-headless/references/gift-cards/INSTRUCTIONS.md +51 -0
  88. package/skills/wix-headless/references/gift-cards/PAGES.md +129 -0
  89. package/skills/wix-headless/references/images/INSTRUCTIONS.md +359 -0
  90. package/skills/wix-headless/references/shared/BUILD_NOISE.md +8 -0
  91. package/skills/wix-headless/references/shared/IMAGE_GENERATION.md +185 -0
  92. package/skills/wix-headless/references/shared/IMPLEMENTER.md +155 -0
  93. package/skills/wix-headless/references/shared/MCP_PREFIX.md +105 -0
  94. package/skills/wix-headless/references/shared/PRODUCTION_SHARP_EDGES.md +97 -0
  95. package/skills/wix-headless/references/shared/RETURN_CONTRACT.md +423 -0
  96. package/skills/wix-headless/references/shared/STYLING.md +117 -0
  97. package/skills/wix-headless/references/stores/BACK_IN_STOCK.md +178 -0
  98. package/skills/wix-headless/references/stores/CATEGORY_PAGES.md +86 -0
  99. package/skills/wix-headless/references/stores/COMPONENTS_CSS.md +129 -0
  100. package/skills/wix-headless/references/stores/HOME_AND_NAV.md +227 -0
  101. package/skills/wix-headless/references/stores/INSTRUCTIONS.md +96 -0
  102. package/skills/wix-headless/references/stores/PRODUCT_CATALOG_DATA.md +249 -0
  103. package/skills/wix-headless/references/stores/PRODUCT_PAGES.md +213 -0
  104. package/skills/wix-headless/references/stores/SHARED_WIRING.md +164 -0
  105. package/skills/wix-headless/references/verticals/_schema.json +160 -0
  106. package/skills/wix-headless/references/verticals/_schema.md +185 -0
  107. package/skills/wix-headless/references/verticals/blog.md +125 -0
  108. package/skills/wix-headless/references/verticals/cms.md +121 -0
  109. package/skills/wix-headless/references/verticals/ecom.md +96 -0
  110. package/skills/wix-headless/references/verticals/forms.md +106 -0
  111. package/skills/wix-headless/references/verticals/gift-cards.md +121 -0
  112. package/skills/wix-headless/references/verticals/stores.md +167 -0
  113. package/skills/wix-headless/scripts/check-manifest.mjs +198 -0
  114. package/skills/wix-headless/scripts/copy-utility-templates.mjs +153 -0
  115. package/skills/wix-headless/scripts/emit-design-tokens.mjs +77 -0
  116. package/skills/wix-headless/scripts/finalize-run-json.mjs +141 -0
  117. package/skills/wix-headless/scripts/init-site-json.mjs +63 -0
  118. package/skills/wix-headless/scripts/patch-decorative-slots.mjs +124 -0
  119. package/skills/wix-headless/scripts/plan-entity-image-waves.mjs +190 -0
  120. package/skills/wix-headless/scripts/preview.sh +45 -0
  121. package/skills/wix-headless/scripts/release.sh +73 -0
  122. package/skills/wix-headless/scripts/scaffold.sh +53 -0
  123. package/skills/wix-headless/scripts/seed-utilities.sh +55 -0
  124. package/skills/wix-headless/shared-utilities/analytics.ts +40 -0
  125. package/skills/wix-headless/shared-utilities/ricos.ts +179 -0
  126. package/skills/wix-headless/shared-utilities/wix-image.ts +72 -0
  127. package/skills/wix-headless/templates/ecom/CartBadge.tsx +84 -0
  128. package/skills/wix-headless/templates/ecom/CartView.tsx +543 -0
  129. package/skills/wix-headless/templates/ecom/cart.astro +13 -0
  130. package/skills/wix-headless/templates/ecom/components-ecom.css +215 -0
  131. package/skills/wix-headless/templates/ecom/discounts.ts +71 -0
  132. package/skills/wix-headless/templates/ecom/thank-you.astro +24 -0
  133. package/skills/wix-headless/templates/gift-cards/GiftCardPurchase.tsx +172 -0
  134. package/skills/wix-headless/templates/gift-cards/_home-teaser-snippet.astro +42 -0
  135. package/skills/wix-headless/templates/gift-cards/_nav-snippet.astro +11 -0
  136. package/skills/wix-headless/templates/gift-cards/components-gift-cards.css +219 -0
  137. package/skills/wix-headless/templates/gift-cards/gift-cards.astro +51 -0
  138. package/skills/wix-headless/templates/gift-cards/gift-cards.ts +75 -0
  139. package/skills/wix-headless/templates/stores/AddToCartButton.tsx +77 -0
  140. package/skills/wix-headless/templates/stores/BackInStockForm.tsx +176 -0
  141. package/skills/wix-headless/templates/stores/CategoryRail.astro +69 -0
  142. package/skills/wix-headless/templates/stores/ProductCard.astro +79 -0
  143. package/skills/wix-headless/templates/stores/ProductPurchase.tsx +397 -0
  144. package/skills/wix-headless/templates/stores/SeoTags.astro +21 -0
  145. package/skills/wix-headless/templates/stores/back-in-stock.ts +67 -0
  146. package/skills/wix-headless/templates/stores/categories.ts +155 -0
  147. package/skills/wix-headless/templates/stores/category/[slug].astro +130 -0
  148. package/skills/wix-headless/templates/stores/components-stores.css +295 -0
  149. package/skills/wix-headless/templates/stores/products/[slug].astro +128 -0
  150. package/skills/wix-headless/templates/stores/products/index.astro +101 -0
  151. package/skills/wix-manage/SKILL.md +280 -0
  152. package/skills/wix-manage/references/app-installation/install-wix-apps.md +155 -0
  153. package/skills/wix-manage/references/app-installation/list-installed-apps.md +124 -0
  154. package/skills/wix-manage/references/blog/how-to-create-blog-posts.md +226 -0
  155. package/skills/wix-manage/references/bookings/booking-service-policy-setup.md +95 -0
  156. package/skills/wix-manage/references/bookings/booking-system-integration-gaps.md +416 -0
  157. package/skills/wix-manage/references/bookings/bookings-staff-setup.md +255 -0
  158. package/skills/wix-manage/references/bookings/create-and-update-booking-services.md +462 -0
  159. package/skills/wix-manage/references/bookings/end-to-end-booking-flow.md +278 -0
  160. package/skills/wix-manage/references/bookings/external-calendar-integration.md +258 -0
  161. package/skills/wix-manage/references/bookings/multi-resource-service-creation.md +231 -0
  162. package/skills/wix-manage/references/calendar/configure-default-business-hours.md +226 -0
  163. package/skills/wix-manage/references/cms/cms-data-items-crud.md +422 -0
  164. package/skills/wix-manage/references/cms/cms-data-operations-extended.md +263 -0
  165. package/skills/wix-manage/references/cms/cms-ecommerce-catalog-integration.md +136 -0
  166. package/skills/wix-manage/references/cms/cms-references-and-relationships.md +160 -0
  167. package/skills/wix-manage/references/cms/cms-schema-management.md +143 -0
  168. package/skills/wix-manage/references/contacts/bulk-delete-contacts.md +73 -0
  169. package/skills/wix-manage/references/contacts/bulk-label-and-unlabel-contacts.md +67 -0
  170. package/skills/wix-manage/references/domains/domain-search-and-purchase.md +434 -0
  171. package/skills/wix-manage/references/ecommerce/api-recommendation-tracking.md +420 -0
  172. package/skills/wix-manage/references/ecommerce/flow-add-free-shipping.md +267 -0
  173. package/skills/wix-manage/references/ecommerce/flow-bundle-and-save.md +290 -0
  174. package/skills/wix-manage/references/ecommerce/flow-fix-coverage-gaps.md +300 -0
  175. package/skills/wix-manage/references/ecommerce/flow-optimize-shipping-rates.md +364 -0
  176. package/skills/wix-manage/references/ecommerce/flow-seasonal-promotion.md +315 -0
  177. package/skills/wix-manage/references/ecommerce/flow-stock-mover.md +308 -0
  178. package/skills/wix-manage/references/ecommerce/flow-upsell-boost.md +271 -0
  179. package/skills/wix-manage/references/ecommerce/goal-clear-inventory.md +118 -0
  180. package/skills/wix-manage/references/ecommerce/goal-drive-cross-sells.md +122 -0
  181. package/skills/wix-manage/references/ecommerce/goal-increase-aov.md +132 -0
  182. package/skills/wix-manage/references/ecommerce/goal-reduce-cart-abandonment.md +148 -0
  183. package/skills/wix-manage/references/ecommerce/goal-seasonal-revenue.md +146 -0
  184. package/skills/wix-manage/references/ecommerce/guardrail-discount-conflicts.md +118 -0
  185. package/skills/wix-manage/references/ecommerce/guardrail-margin-protection.md +88 -0
  186. package/skills/wix-manage/references/ecommerce/guardrail-rate-pricing-sanity.md +108 -0
  187. package/skills/wix-manage/references/ecommerce/guardrail-shipping-health.md +124 -0
  188. package/skills/wix-manage/references/ecommerce/recipe-apply-shipping-recommendations.md +299 -0
  189. package/skills/wix-manage/references/ecommerce/recommend-ecommerce-strategy.md +582 -0
  190. package/skills/wix-manage/references/ecommerce/setup-coupons.md +338 -0
  191. package/skills/wix-manage/references/ecommerce/setup-discount-rules.md +444 -0
  192. package/skills/wix-manage/references/ecommerce/setup-shipping-rates.md +86 -0
  193. package/skills/wix-manage/references/ecommerce/setup-shipping-regions.md +56 -0
  194. package/skills/wix-manage/references/ecommerce/setup-store-pickup-location.md +209 -0
  195. package/skills/wix-manage/references/ecommerce/skill-graph.md +139 -0
  196. package/skills/wix-manage/references/ecommerce/troubleshoot-checkout-delivery-dropoff.md +124 -0
  197. package/skills/wix-manage/references/ecommerce/troubleshoot-discount-not-applying.md +95 -0
  198. package/skills/wix-manage/references/events/list-events.md +203 -0
  199. package/skills/wix-manage/references/forms/create-form.md +260 -0
  200. package/skills/wix-manage/references/get-paid/create-payment-links.md +212 -0
  201. package/skills/wix-manage/references/get-paid/how-to-setup-wix-payments.md +57 -0
  202. package/skills/wix-manage/references/get-paid/payment-links-for-bookings.md +101 -0
  203. package/skills/wix-manage/references/media/upload-media-to-wix.md +216 -0
  204. package/skills/wix-manage/references/pricing-plans/create-and-update-pricing-plans.md +77 -0
  205. package/skills/wix-manage/references/pricing-plans/pricing-plans-bookings-integration.md +166 -0
  206. package/skills/wix-manage/references/restaurants/wix-restaurants-setup.md +336 -0
  207. package/skills/wix-manage/references/rich-content/ricos-converter-service.md +295 -0
  208. package/skills/wix-manage/references/site-properties/change-payment-currency-site-properties.md +59 -0
  209. package/skills/wix-manage/references/sites/create-site-from-template.md +183 -0
  210. package/skills/wix-manage/references/sites/query-sites.md +125 -0
  211. package/skills/wix-manage/references/stores/add-store-pages-to-site.md +57 -0
  212. package/skills/wix-manage/references/stores/bulk-create-products-with-options.md +1041 -0
  213. package/skills/wix-manage/references/stores/create-product-catalog-v1.md +125 -0
  214. package/skills/wix-manage/references/stores/create-product-from-image.md +824 -0
  215. package/skills/wix-manage/references/stores/create-product-with-options-catalog-v3.md +566 -0
  216. package/skills/wix-manage/references/stores/find-products-query-and-search-catalog-v3.md +194 -0
  217. package/skills/wix-manage/references/stores/query-products-catalog-v1.md +80 -0
  218. package/skills/wix-manage/references/stores/setup-online-store-catalog-v3.md +99 -0
  219. package/skills/wix-manage/references/stores/update-product-pre-order.md +213 -0
  220. package/skills/wix-manage/references/stores/update-product-with-options.md +318 -0
@@ -0,0 +1,178 @@
1
+ # Phase 3 Components — Back in Stock (Stores)
2
+
3
+ Split across the stores `components` scope (TSX/util files) and the `components-css` sibling (CSS rules). The matching Phase 4 wiring lives in `PRODUCT_PAGES.md` (SSR probe import + new props on `<ProductPurchase>`).
4
+
5
+ ## Scope
6
+
7
+ Files written for back-in-stock, by scope:
8
+
9
+ **`components` scope** (see `./SHARED_WIRING.md`):
10
+ - `src/utils/back-in-stock.ts` — SSR-elevated probe of the Wix back-in-stock service, plus the canonical Stores app id constant
11
+ - `src/components/BackInStockForm.tsx` — React island that posts via `@wix/ecom`'s `backInStockNotifications.createBackInStockNotificationRequest`
12
+
13
+ **`components-css` scope** (see `./COMPONENTS_CSS.md`):
14
+ - `src/styles/components-stores.css` — appends the back-in-stock form CSS rules at the end of the file (see § 3 below)
15
+
16
+ This file is read by both scopes. Sections covering the SDK / probe / form island are for the `components` scope; § 3 (CSS append) is for the `components-css` scope.
17
+
18
+ ## Critical rules
19
+
20
+ These come from live trials on Catalog-V3 sites. Encode them verbatim — none of them are in the public docs.
21
+
22
+ 1. **Two app ids — pick the right one.**
23
+ - The Wix Stores **install** app id is `215238eb-22a5-4c36-9e7b-e7c08025e04e` (used in `catalogReference.appId` for cart adds, app install, `Phase 1`).
24
+ - The Wix Stores **back-in-stock** app id is `1380b703-ce81-ff05-f115-39571d94dfcd` (the Stores sub-page registration id).
25
+ - The back-in-stock service rejects `215238eb-…` (`428 NOT_SUPPORTED_APP_DEF_ID` on `start-collecting`, `428 REQUEST_COLLECTION_DISABLED` on the create endpoint) and accepts `1380b703-…`. Both are correct in their own contexts; do not unify them.
26
+
27
+ 2. **Bare-fields rule for the SDK subscribe call.** `backInStockNotifications.createBackInStockNotificationRequest(request, itemDetails)` throws an opaque `TypeError: Failed to construct 'URL': Invalid URL` when the optional `request.itemUrl` or `itemDetails.image` fields are present, even with browser-valid URLs. Send only the four required fields: `catalogReference`, `email`, `name`, `price`. The notification email and the dashboard view both work without them.
28
+
29
+ 3. **Numeric price only.** `itemDetails.price` must be a numeric string (e.g. `"385"`). Currency-formatted strings (`"$385"`) fail with `400 DECIMAL_GTE`. The `normalizePrice` helper in the form template strips `$`/`,` and falls back to `"0"`.
30
+
31
+ 4. **Visitor scope from the client; SSR-only elevation for the probe.**
32
+ - The form's subscribe call uses `@wix/ecom` straight from the React island — no `auth.elevate`, no Astro API route. The visitor token is enough.
33
+ - The settings probe uses `auth.elevate(httpClient.fetchWithAuth)` because `getSettings` requires Manage Stores. Run it in `[slug].astro` frontmatter, **never from the client**.
34
+ - Do NOT invent an Astro `src/pages/api/...` POST route. The `@wix/cloud-provider-fetch-adapter` that ships with the scaffold returned 403 to the browser on app-defined POST routes during the trial. Stay on the SDK.
35
+
36
+ 5. **Module-memoize the probe.** `getBackInStockEnabled()` holds one in-flight `Promise<boolean>` at module scope so multiple SSR awaits in the same request coalesce. Same pattern as `gift-cards.ts`'s `getGiftCardProduct()`.
37
+
38
+ ## Template files
39
+
40
+ This scope uses **template files** instead of inline code. For each file below:
41
+
42
+ 1. Read the template from `<Agent location>/templates/<path>`
43
+ 2. Write it to the project at the target path
44
+ 3. Adapt CSS class names if the design tokens map them differently
45
+
46
+ Do NOT modify logic, imports, the bare-fields request shape, or the app-id constants.
47
+
48
+ ### 1. `src/utils/back-in-stock.ts`
49
+
50
+ Use template `templates/back-in-stock.ts`.
51
+
52
+ Exports:
53
+ - `WIX_STORES_BACK_IN_STOCK_APP_ID` — string constant. Use this for the `catalogReference.appId` in the form.
54
+ - `WIX_STORES_INSTALL_APP_ID` — string constant. Exported for completeness; unused by this file.
55
+ - `getBackInStockEnabled(): Promise<boolean>` — memoized SSR probe.
56
+ - `SETTINGS_URL` — the `getSettings` REST URL, exported in case future scopes need it.
57
+
58
+ The probe header comment block documents the app-id discrepancy in detail. Keep that block intact when copying — it's the only place the next maintainer will see the rationale.
59
+
60
+ ### 2. `src/components/BackInStockForm.tsx`
61
+
62
+ Use template `templates/BackInStockForm.tsx`.
63
+
64
+ Props: `{ productId, variantId?, productName, productPrice: number | string, variantLabel? }`. The form accepts price as either a number or a numeric string and normalizes internally.
65
+
66
+ State machine: `idle → submitting → (success | error)` with `success` carrying an optional `alreadySubscribed` flag for the duplicate-detection branch (`BACK_IN_STOCK_NOTIFICATION_REQUEST_ALREADY_EXISTS` → "You're already on the list").
67
+
68
+ Class names:
69
+ - `.back-in-stock-form`, `.back-in-stock-headline`, `.back-in-stock-eyebrow`, `.back-in-stock-lede`, `.back-in-stock-label`, `.back-in-stock-row`, `.back-in-stock-input`, `.back-in-stock-submit`, `.back-in-stock-error`, `.back-in-stock-success`, `.back-in-stock-success-headline`, `.back-in-stock-success-detail` — defined in the CSS append below.
70
+
71
+ ### 3. `src/styles/components-stores.css` — append
72
+
73
+ The `components-stores.css` template already covers options/quantity/modifiers/stock-status. Append the back-in-stock rules at the end. Use the existing pack token vocabulary (`bark`, `cream`, `parchment`, `ink`, `rule`) so the styling lands on every brand without per-site rewrites.
74
+
75
+ ```css
76
+ /* --- Back-in-stock subscribe form (BackInStockForm.tsx) --- */
77
+ .back-in-stock-form {
78
+ @apply flex flex-col gap-md mt-md p-lg border border-rule rounded;
79
+ background-color: var(--color-cream);
80
+ }
81
+ .back-in-stock-headline {
82
+ @apply flex flex-col gap-sm;
83
+ }
84
+ .back-in-stock-eyebrow {
85
+ @apply font-heading text-xs uppercase tracking-wider text-bark/70;
86
+ }
87
+ .back-in-stock-lede {
88
+ @apply font-body text-sm text-ink;
89
+ line-height: 1.5;
90
+ }
91
+ .back-in-stock-label {
92
+ @apply font-heading text-xs uppercase tracking-wider text-bark/70;
93
+ }
94
+ .back-in-stock-row {
95
+ @apply flex flex-row flex-wrap gap-sm;
96
+ }
97
+ .back-in-stock-input {
98
+ @apply flex-1 px-md py-sm font-body text-sm border border-rule rounded bg-parchment text-ink;
99
+ min-width: 0;
100
+ transition: border-color 0.15s ease;
101
+ }
102
+ .back-in-stock-input:focus {
103
+ @apply outline-none border-ink;
104
+ }
105
+ .back-in-stock-input[aria-invalid="true"] {
106
+ @apply border-rust;
107
+ }
108
+ .back-in-stock-submit {
109
+ @apply px-lg py-sm font-heading text-xs uppercase tracking-wider bg-bark text-cream rounded cursor-pointer transition-colors;
110
+ border: 1px solid var(--color-bark);
111
+ }
112
+ .back-in-stock-submit:hover:not(:disabled) {
113
+ @apply bg-ink;
114
+ }
115
+ .back-in-stock-submit:disabled {
116
+ @apply opacity-50 cursor-not-allowed;
117
+ }
118
+ .back-in-stock-error {
119
+ @apply font-body text-sm text-rust;
120
+ }
121
+ .back-in-stock-success {
122
+ @apply mt-md p-lg border border-rule rounded;
123
+ background-color: var(--color-cream);
124
+ }
125
+ .back-in-stock-success-headline {
126
+ @apply font-heading text-base text-ink;
127
+ margin: 0 0 0.5rem 0;
128
+ }
129
+ .back-in-stock-success-detail {
130
+ @apply font-body text-sm text-ink;
131
+ line-height: 1.55;
132
+ margin: 0;
133
+ }
134
+ .stock-status.back-in-stock-alt {
135
+ @apply mt-sm font-body text-sm italic text-bark/70;
136
+ }
137
+ ```
138
+
139
+ If the brand's design tokens don't include a `rust` (error) color, fall back to a neutral `text-ink` on the error state — the `aria-invalid` border still flags it visually.
140
+
141
+ ## Return format
142
+
143
+ The full components scope return must mention back-in-stock:
144
+
145
+ ```json
146
+ {
147
+ "status": "complete",
148
+ "phase": "stores-components",
149
+ "scope": "components",
150
+ "summary": "Wrote stores islands, scoped CSS, back-in-stock probe + form",
151
+ "data": {
152
+ "islands": ["ProductPurchase.tsx", "AddToCartButton.tsx", "BackInStockForm.tsx"],
153
+ "utils": ["back-in-stock.ts"],
154
+ "scopedCssFile": "src/styles/components-stores.css",
155
+ "backInStockWired": true
156
+ },
157
+ "files": [
158
+ "src/components/SeoTags.astro",
159
+ "src/components/AddToCartButton.tsx",
160
+ "src/components/ProductPurchase.tsx",
161
+ "src/components/BackInStockForm.tsx",
162
+ "src/utils/back-in-stock.ts",
163
+ "src/styles/components-stores.css"
164
+ ],
165
+ "errors": []
166
+ }
167
+ ```
168
+
169
+ ## Anti-patterns
170
+
171
+ | WRONG | CORRECT |
172
+ |---|---|
173
+ | Use `215238eb-…` (Stores install id) as `catalogReference.appId` for back-in-stock | Use `WIX_STORES_BACK_IN_STOCK_APP_ID` (`1380b703-…`); the install id is rejected on V3 |
174
+ | Pass `itemUrl` or `image` to `createBackInStockNotificationRequest` | Send only `catalogReference`, `email`, `name`, numeric `price` — the SDK throws `Failed to construct 'URL': Invalid URL` on either optional field |
175
+ | Send `"$385"` as `price` | Numeric string `"385"` only; the API rejects formatted prices with `400 DECIMAL_GTE` |
176
+ | Wrap the subscribe call in `auth.elevate(...)` from the React island | Visitor scope is enough; elevation belongs only to the SSR probe |
177
+ | Add a custom `src/pages/api/back-in-stock-subscribe.ts` route | Not needed — SDK from the island works. The Wix cloud adapter returned 403 on app-defined POST routes during the trial. |
178
+ | Drop the module-memoization in `back-in-stock.ts` | Keep it; multiple SSR awaits in the same request coalesce into one `getSettings` call |
@@ -0,0 +1,86 @@
1
+ # Phase 4 Category Pages — Stores
2
+
3
+ Scope: `pages-categories`. Launched in **Step 7** alongside `pages-products` and `pages-home-and-nav`. This scope writes the dedicated category landing route and the shared `<CategoryRail/>` + `categories.ts` helper that `pages-products` and `pages-home-and-nav` also import.
4
+
5
+ **Dispatch:** all three stores Phase-4 scopes are dispatched in parallel — Astro resolves the cross-file imports at build time (Step 8). The orchestrator does not need to serialize. Each scope only needs its own declared files to exist by the time `astro build` runs.
6
+
7
+ ## Scope
8
+
9
+ Files this agent OWNS (writes):
10
+
11
+ - `src/pages/category/[slug].astro` — category landing (server-side filtered, cursor-paginated)
12
+ - `src/components/CategoryRail.astro` — shared rail + Prev/Next pagination, persisted across `<ClientRouter />` swaps
13
+ - `src/utils/categories.ts` — TTL-cached helpers: `listStoreCategories`, `getCategoryBySlug`, `listProductsInCategory`
14
+
15
+ Files this agent MUST NOT touch:
16
+ - `src/pages/products/index.astro`, `[slug].astro`, `src/components/ProductCard.astro` — owned by `pages-products`
17
+ - `src/pages/index.astro`, `src/components/Navigation.astro` — owned by `pages-home-and-nav`
18
+ - `src/layouts/Layout.astro`, `global.css` — owned by designer (View Transitions + loading bar live there)
19
+ - `src/components/ProductPurchase.tsx`, `AddToCartButton.tsx`, `BackInStockForm.tsx` — owned by `components`
20
+
21
+ ## Inputs (from parent prompt)
22
+
23
+ - **Phase 1 return data** — `categories: []`. Phase 1 does not seed categories (they're merchant-driven). This scope still writes the helper + rail + route — they're harmless when no categories exist, and they light up automatically once the merchant creates visible categories with items in the dashboard. `listStoreCategories()` queries the API live at SSR time (5-min TTL cache), so no redeploy is needed when categories are added later.
24
+ - **Design tokens** — `.wix/site.json.designTokens` for the published vocabulary. Page header / breadcrumbs / pill / pagination styling should follow `references/shared/STYLING.md` (utilities derived from tokens, semantic classes only for primitives).
25
+ - **Designer output summary** — confirm `Layout.astro` already includes `<ClientRouter />`, `transition:persist` markers on nav/footer, and the `[data-nav-progress]` element + after-swap hook. If any of those is missing, return `status: "partial"` with `errors: [{ code: "DESIGNER_LAYOUT_MISSING_TRANSITIONS", path: "src/layouts/Layout.astro" }]`.
26
+
27
+ ## Critical rules (all must be honored)
28
+
29
+ 1. **Server-side filter only.** Do NOT ship a client-side filter that hides cards via `card.hidden = true` or `data-category-ids`. That pattern doesn't scale past a few hundred products and breaks SEO. Filtering is by URL: `/category/<slug>` is the canonical filter, server-renders only matching products. The rail click is a real navigation that `<ClientRouter />` swaps in place.
30
+ 2. **Use `@wix/auto_sdk_categories_categories`**, not `@wix/categories` (the published name) — the auto_sdk package is already on disk via every other `@wix/*` package's transitive deps. Importing `@wix/categories` triggers a fresh `npm install`. The provided template uses `import * as categories from "@wix/auto_sdk_categories_categories"` already; do not rewrite.
31
+ 3. **`queryCategories(...)` rejects empty filters.** The SDK builder's `.find()` validates that at least one predicate has been chained. Always include `.eq("visible", true)` (the constraint we want anyway). Provided template already does this.
32
+ 4. **Filter out the auto-managed "All Products" category** by `handle === "online_stores_all_products"`. It's installed by Wix Stores automatically and contains every product; surfacing it in the rail makes the All pill duplicate.
33
+ 5. **Filter out empty categories** by `itemCounter === 0` so the rail doesn't show buckets that 404 in practice (the route still works, but the pill leads to "Nothing in <name> just now").
34
+ 6. **Use the Stores app id `215238eb-22a5-4c36-9e7b-e7c08025e04e`** as `STORES_APP_ID` in `categories.ts`. Same id used for cart ops and Phase 1 product seed. NOT the back-in-stock id `1380b703-…`.
35
+ 7. **Cursor pagination** uses `productsV3.queryProducts().limit(24).skipTo(cursor)`. Cursor lives in `?cursor=…` on the URL, surfaced from `result.cursors.next` / `result.cursors.prev`. Prev/Next links use `data-astro-prefetch="hover"` so hovering them warms the cache.
36
+ 8. **Module-level TTL cache (5 min)** in `categories.ts` is opportunistic; safe under the Cloudflare-style fetch adapter (each worker isolate is single-tenant). Errors don't poison the cache.
37
+ 9. **Two-call pipeline** in `listProductsInCategory`: first `listItemsInCategory(categoryId, { appNamespace: "@wix/stores" })` for IDs, then `productsV3.queryProducts().in("_id", ids).limit(24).skipTo(cursor).find()`. There is no Wix endpoint that does category filter + cursor paging in one shot — don't attempt `listCategoriesForItems` from the SDK; it ships items via GET querystring and breaks on arrays. If you need product → categories mapping (e.g. for breadcrumbs on product detail), call the REST POST endpoint directly: `POST /categories/v1/categories/list-categories-for-items`.
38
+
39
+ ## Writing the templates
40
+
41
+ Read each template at `templates/stores/` and write it verbatim to the corresponding `src/` path, with three small adjustments:
42
+
43
+ | Template path | Site path |
44
+ |---|---|
45
+ | `templates/categories.ts` | `src/utils/categories.ts` |
46
+ | `templates/CategoryRail.astro` | `src/components/CategoryRail.astro` |
47
+ | `templates/category/[slug].astro` | `src/pages/category/[slug].astro` |
48
+
49
+ Adjustments at the call site:
50
+
51
+ 1. The category page header copy ("Shop", breadcrumbs, lede) should adapt to brand tone. The template ships generic ("Browse our X collection"); rewrite the breadcrumb middle anchor and the empty-state line to match the rest of the site's voice. Keep semantics — same elements, same classes, same `data-*` markers.
52
+ 2. If the brand uses an editorial eyebrow pattern on `/products` (e.g. "Issue No. 01 · The Collection"), mirror it on `/category/[slug]` (e.g. "Category · Lounge Chairs"). Otherwise omit.
53
+ 3. Page-header CSS class names (`page-header`, `page-header-title`, `page-header-lede`, `breadcrumbs`, `page-header-image`) must match what the designer published. If the designer used different names, rename inside the template — do NOT introduce new ones.
54
+
55
+ ## Pre-return file-existence assertion
56
+
57
+ Before returning `status: "complete"`, verify all three files exist:
58
+
59
+ - `src/utils/categories.ts`
60
+ - `src/components/CategoryRail.astro`
61
+ - `src/pages/category/[slug].astro`
62
+
63
+ If any is missing, return `status: "partial"` with `errors: [{ code: "PHASE4_FILE_MISSING", path: "<expected path>" }]`. The orchestrator's manifest check will also catch this, but an agent-side assertion gives a faster and more precise failure.
64
+
65
+ ## Return contract
66
+
67
+ ```json
68
+ {
69
+ "status": "complete",
70
+ "phase": "stores-pages",
71
+ "scope": "pages-categories",
72
+ "summary": "Wrote shared CategoryRail + categories helper; /category/[slug] route renders M categories.",
73
+ "data": {
74
+ "categoriesRendered": 0,
75
+ "filesWritten": [
76
+ "src/utils/categories.ts",
77
+ "src/components/CategoryRail.astro",
78
+ "src/pages/category/[slug].astro"
79
+ ]
80
+ },
81
+ "files": [],
82
+ "errors": []
83
+ }
84
+ ```
85
+
86
+ Phase 1 always reports zero categories (it does not seed them). Set `categoriesRendered: 0` and return `status: "complete"` — the helper, rail, and route are still written so the storefront lights up automatically the first time the merchant creates a visible category with items in the dashboard, with no code change needed.
@@ -0,0 +1,129 @@
1
+ # Phase 3 Components-CSS — Stores
2
+
3
+ Sibling of the `components` scope. Launched in **Step 4.5** in the same concurrent batch — runs in parallel with the TSX/Astro work, ecom and gift-cards components, and Image Phase 2.
4
+
5
+ ## What this scope owns
6
+
7
+ Exactly one file:
8
+
9
+ - `src/styles/components-stores.css` — scoped CSS for stores-specific contract keys (option pills, quantity stepper, stock status, modifier free-text input, product card, product grid, offer callout panel). Imported by `Layout.astro` (the designer foundation sets up the import).
10
+
11
+ ## What this scope does NOT own
12
+
13
+ - Any `.tsx` or `.astro` file. Those are the `components` sibling scope (`./SHARED_WIRING.md`).
14
+ - `src/styles/global.css` — owned by the designer foundation. **You read it (to audit for stores-class leaks) but never write it.**
15
+ - `src/styles/components-ecom.css`, `src/styles/components-gift-cards.css` — owned by other packs' `components` (or `components-css`) scopes.
16
+ - `src/utils/back-in-stock.ts` — pre-copied by the orchestrator before this dispatch; not your concern.
17
+
18
+ ## Reading set
19
+
20
+ You only need:
21
+
22
+ 1. **`<SKILL_ROOT>/templates/stores/components-stores.css`** — the canonical template. Read it once.
23
+ 2. **`<SKILL_ROOT>/references/shared/STYLING.md`** — the styling-contract conventions (how to use `@apply`, the `@theme` token utilities, the no-default-Tailwind-colors rule, and the global-vs-scoped CSS ownership boundary).
24
+ 3. **`<SKILL_ROOT>/references/shared/RETURN_CONTRACT.md`** — the return JSON shape.
25
+ 4. **`src/styles/global.css`** in the project — read to audit for stores-class leaks (see § "Global-CSS leak audit" below).
26
+ 5. **Design tokens (inline in your prompt)** — the parent skill pastes the full `designTokens` JSON into your dispatch prompt. Use it directly; do NOT read `.wix/design-tokens.css` or `.wix/site.d.ts` from disk.
27
+
28
+ You do NOT need to read `INSTRUCTIONS.md`, `SHARED_WIRING.md`, `BACK_IN_STOCK.md`, the TSX templates, the back-in-stock util, or any other reference. Skipping those reads is the point of the split — they would consume tokens for context this scope doesn't use.
29
+
30
+ ## Implementation
31
+
32
+ ### 1. Read the template
33
+
34
+ ```
35
+ <SKILL_ROOT>/templates/stores/components-stores.css
36
+ ```
37
+
38
+ This is the canonical scoped CSS for the stores pack. Adapt sizing/spacing to the brand's aesthetic — use the design tokens from your prompt (`--color-bark`, `--color-cream`, `--spacing-md`, `--font-display`, etc.). **Do not rename the class names or state modifiers** — they must match the contract keys the TSX components reference.
39
+
40
+ ### 2. Use `@apply` with brand `@theme` utilities
41
+
42
+ The `@theme` block in `global.css` (written by the designer foundation) exposes the brand tokens as Tailwind utilities (e.g., `bg-bark`, `text-cream`, `font-body`). They are globally available because `global.css` is imported first in `Layout.astro`.
43
+
44
+ Use `@apply` for color, font, and spacing properties. Drop to `var(--color-bark)` directly when `@apply` doesn't cover a property (e.g., border-color via custom property).
45
+
46
+ Do **NOT** use default Tailwind colors (`bg-green-50`, `text-red-600`). The brand palette is the only allowed source.
47
+
48
+ ### 3. Class ownership
49
+
50
+ Classes you own (define rules in `components-stores.css`):
51
+
52
+ - **`.product-card`, `.product-card-media`, `.product-card-ribbon`, `.product-card-index`** — the product card itself, including the `overflow: hidden` + `border-radius` clipping context. Whoever writes the `border-radius` here also writes any inner padding required to keep child content inside the rounded edges. Without inner padding, a price `<p>` sits flush against the rounded bottom corner and descenders get clipped. Add `padding-bottom: var(--spacing-md)` on the card plus horizontal padding on each text block when you set the radius.
53
+ - **`.product-grid`** — the layout that lists product cards. Both `/products` (pages-products scope) and `/category/[slug]` (pages-categories scope) consume it from one place. Include `display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: var(--spacing-xl);` plus the View-Transitions opacity fade for in-flight navigations.
54
+ - **`.offer-callout` family (`.offer-callout`, `-item`, `-badge`, `-name`, `-detail`, `-foot`)** — discount panel rendered above `<ProductPurchase>` on `/products/[slug]`.
55
+ - **Option-selector contract classes** — `option-group`, `option-label`, `option-choices`, `option-pill` (with `.selected` state modifier).
56
+ - **Quantity-stepper contract classes** — `quantity-selector`, `quantity-btn`, `quantity-value`.
57
+ - **Stock status** — `stock-status`.
58
+ - **Back-in-stock form** (`.back-in-stock-form` and child classes) — append the rules from `./BACK_IN_STOCK.md` § 3 to the end of `components-stores.css`. The TSX form island is written by the `components` sibling; this file owns its styling.
59
+
60
+ Classes you do NOT own:
61
+
62
+ - `.btn`, `.btn-primary`, `.btn-secondary` — designer's `global.css`.
63
+ - `addToCartButton` → `.add-to-cart-btn` — designer's `global.css` (it's a global contract key).
64
+ - `productPurchase` → `.product-purchase` outer wrapper — designer's `global.css`.
65
+ - Anything in `components-ecom.css` (CartBadge, CartView, CartLine) — owned by ecom pack.
66
+
67
+ The boundary: **rules referenced by exactly one pack's TSX live in that pack's scoped CSS; rules referenced by every page (buttons, links, type) live in the designer's `global.css`.**
68
+
69
+ ### 4. Global-CSS leak audit
70
+
71
+ Before writing your file, **read `src/styles/global.css`** and grep for any class your scope owns. Stores-specific rules sometimes leak into the designer's foundation (observed across runs):
72
+
73
+ - `.product-grid` and `body[data-navigating="true"] .product-grid` — designer drift; should be in `components-stores.css`, not `global.css`.
74
+ - Any `.product-card-*` rule.
75
+ - Any `.offer-callout-*` rule.
76
+ - Any contract class that maps to a key in `contractKeys.scoped.stores`.
77
+
78
+ If you find a leak, do NOT edit `global.css` (the designer owns it). Instead:
79
+
80
+ 1. Override the rule with the complete declaration in `components-stores.css` (later imports win in CSS cascade because Layout.astro imports `components-stores.css` AFTER `global.css`).
81
+ 2. Add `{code: "GLOBAL_CSS_LEAK", class: "<name>", file: "src/styles/global.css"}` to your return JSON's `errors` array — non-fatal but tracked.
82
+
83
+ ### 5. Write the file
84
+
85
+ Write the adapted CSS to `src/styles/components-stores.css`. The first line must be `@reference "./global.css";` so Tailwind's `@apply` resolves the `@theme` utilities. The orchestrator's post-Phase-3 manifest check verifies the file exists; it does not verify the `@reference` line.
86
+
87
+ ## Coordination: design tokens
88
+
89
+ Your parent prompt includes the design tokens JSON inline. Use it directly — do **not** read `.wix/design-tokens.css` or `.wix/site.d.ts` from disk and do not poll for them.
90
+
91
+ ## Return format
92
+
93
+ ```json
94
+ {
95
+ "status": "complete",
96
+ "phase": "stores-components-css",
97
+ "scope": "components-css",
98
+ "summary": "Wrote components-stores.css from template, adapted to brand tokens",
99
+ "data": {
100
+ "scopedCssFile": "src/styles/components-stores.css",
101
+ "scopedCssRules": 18,
102
+ "scopedContractClassesDefined": [
103
+ "option-group", "option-label", "option-choices", "option-pill",
104
+ "quantity-selector", "quantity-btn", "quantity-value",
105
+ "stock-status",
106
+ "product-card", "product-card-media", "product-card-ribbon", "product-card-index",
107
+ "product-grid",
108
+ "offer-callout", "offer-callout-item", "offer-callout-badge", "offer-callout-name", "offer-callout-detail", "offer-callout-foot"
109
+ ]
110
+ },
111
+ "files": [
112
+ "src/styles/components-stores.css"
113
+ ],
114
+ "errors": []
115
+ }
116
+ ```
117
+
118
+ If a leak was found and overridden, include `errors: [{code: "GLOBAL_CSS_LEAK", class: "<name>", file: "src/styles/global.css"}]`.
119
+
120
+ ## Anti-patterns
121
+
122
+ | WRONG | CORRECT |
123
+ |-------|---------|
124
+ | Read `INSTRUCTIONS.md`, `SHARED_WIRING.md`, or any `.tsx` template | Not needed — this scope only writes CSS |
125
+ | Edit `src/styles/global.css` to fix a leak | Override in `components-stores.css`; report the leak in `errors` |
126
+ | Use default Tailwind colors (`bg-green-50`, `text-red-600`) | Brand `@theme` utilities (`bg-bark`, `text-cream`) or `var(--color-...)` |
127
+ | Write rules for `.add-to-cart-btn` here | That's a global contract class — owned by the designer's `global.css` |
128
+ | Rename a class because the brand is "more elegant" with kebab-cased variants | Class names are contract keys; renaming breaks every TSX import that references them |
129
+ | Skip the leak audit | Skipping ships double-defined rules; the audit is < 5 s and prevents downstream visual regressions |
@@ -0,0 +1,227 @@
1
+ # Phase 4 Home Page + Nav — Stores
2
+
3
+ Scope: `pages-home-and-nav`. Launched in **Step 7** after `pages-categories` has written the shared rail and `categories.ts` helper. Patches the home page's stores-related placeholder data with live `productsV3` queries AND inserts the Shop submenu (categories list) into the persisted Navigation.
4
+
5
+ ## Scope
6
+
7
+ Files this agent PATCHES (does NOT rewrite):
8
+
9
+ - `src/pages/index.astro` — only the stores-related sections (featured products grid, category cards)
10
+ - `src/components/Navigation.astro` — only at the `<!-- nav:links -->` marker; insert the Shop link + categories submenu
11
+
12
+ Files this agent MUST NOT touch:
13
+ - Any other part of `index.astro` — hero, copy, newsletter, decorative ornaments are designer-owned
14
+ - Any part of `Navigation.astro` outside the `<!-- nav:links -->` marker — designer/ecom-owned (the marker model lets multiple verticals contribute siblings without conflict)
15
+ - `src/utils/categories.ts`, `src/components/CategoryRail.astro`, `src/pages/category/[slug].astro` — owned by `pages-categories`; this scope only **imports** `listStoreCategories` from `categories.ts`
16
+ - Any other component, page, or CSS
17
+ - `global.css`
18
+
19
+ ## Inputs (from parent prompt)
20
+
21
+ - **Phase 1 stores return** — `products: [{id, name, slug, ...}]`. Needed for live query on home page; also useful for deciding how many to feature.
22
+ - **Design tokens** — read `.wix/site.json.designTokens` for the published color/spacing/typography vocabulary; compose Tailwind utilities derived from those tokens at the call site rather than inventing semantic classes. See `references/shared/STYLING.md` for the three styling categories.
23
+ - **Designer output summary** — path of `src/pages/index.astro` and `src/components/Navigation.astro`, with notes on what placeholder data exists.
24
+ - **Categories (lookup)** — if the designer used category links with hardcoded slugs, call `categoriesV3` SDK to discover real category slugs and rewrite `href`s.
25
+
26
+ ## Critical rules
27
+
28
+ 1. **Surgical edits only.** Use `Edit` tool, not `Write`. Preserve everything the designer wrote — hero, copy, decorative elements, section structure, class names.
29
+ 2. **Do NOT restructure layout.** If the designer didn't include featured products, don't add it.
30
+ 3. **Do NOT mutate categories in the catalog.** Read-only. Match designer's category slugs against real ones; rewrite `href` if matched; fall back to `/products` if not.
31
+ 4. **Never improvise category endpoint URLs.** Use `categoriesV3` SDK. If the SDK isn't available, fall back to `<prefix>CallWixSiteAPI` with `POST /categories/v1/categories/query` body `{"query":{}}`. Improvised `/stores/v3/categories/...` URLs caused a multi-minute stall historically.
32
+ 5. **If another agent already wired the home page** (e.g., a previous run), leave it alone and note this in the return.
33
+ 6. **ProductCard is a template** — always accepts `{ product }`. Pass raw SDK product objects, never flat-map. See § 1a.
34
+
35
+ ## When to run the home-page patch
36
+
37
+ Skip the home-page patch entirely if the home page has NO stores-consuming components:
38
+
39
+ - No `ProductGrid` / `ProductCard` with placeholder products array
40
+ - No category cards with hardcoded category slugs (e.g., `/products?category=...`)
41
+
42
+ If the home page is purely editorial (hero + copy + newsletter), return with `featuredProductsWired: false` — there's nothing to patch.
43
+
44
+ ## Implementation
45
+
46
+ ### 1. Home page: featured products
47
+
48
+ Find the placeholder products array in `src/pages/index.astro`. Replace with a server-side `productsV3` query; pass the raw product objects to `ProductCard`.
49
+
50
+ > **WRONG:** `featured = products.map(p => ({name: p.name, price: ...}))` then `<ProductCard name={p.name} .../>`
51
+ > **RIGHT:** `featured = featuredProducts ?? []` as `any[]`, then `<ProductCard product={p} />`
52
+ >
53
+ > Flat-mapping strips fields that ProductCard needs (`media`, `actualPriceRange`, etc.) and crashes the home page (`product` is `undefined`).
54
+
55
+ ```astro
56
+ ---
57
+ // src/pages/index.astro (frontmatter additions only — keep existing imports)
58
+ import { productsV3 } from "@wix/stores";
59
+
60
+ // Wrap every SSR await in try/catch — see references/shared/IMPLEMENTER.md
61
+ // § "SSR error guards" for the full rule.
62
+ let featured: any[] = [];
63
+ try {
64
+ const { items: featuredProducts } = await productsV3
65
+ .queryProducts({ fields: ["CURRENCY"] })
66
+ .limit(4)
67
+ .find();
68
+ featured = featuredProducts ?? [];
69
+ } catch (err) {
70
+ console.error("[home] featured products query failed:", err);
71
+ }
72
+ ---
73
+ ```
74
+
75
+ Then pass each raw product to `ProductCard`. The ribbon is fetched inside ProductCard itself — pages no longer wire offers:
76
+ ```astro
77
+ {featured.map((p) => <ProductCard product={p} />)}
78
+ ```
79
+
80
+ > **Gift-card mirror filter.** After `featured = featuredProducts ?? []`, apply the same filter the listing template uses:
81
+ > ```ts
82
+ > featured = featured.filter((p) => p.ribbon?.name !== "Gift Card");
83
+ > ```
84
+ > The Wix Gift Card app, when enabled in the dashboard, auto-creates 5 DIGITAL Stores products tagged with the "Gift Card" ribbon. They must not appear in the home featured grid for the same reason they're filtered from `/products`: buying a mirror produces a dud line item that doesn't trigger gift-card issuance, and the home teaser block (gift-cards pack) is the right surface for gift cards on the home page.
85
+
86
+ Do **NOT** flat-map products into `{name, price, slug, image}` — pass the raw SDK objects. ProductCard handles its own field extraction, image resolution, and ribbon (offer) rendering internally.
87
+
88
+ Preserve every other prop the designer set on the grid. If `featured` is empty (query failed, or stock cleared), the grid renders with zero cards — the rest of the page stays up.
89
+
90
+ ### 1a. ProductCard interface (template — deterministic)
91
+
92
+ ProductCard is a **template file** (`templates/ProductCard.astro`). The `product-pages` scope copies it deterministically. The interface is:
93
+
94
+ ```astro
95
+ interface Props {
96
+ product: { _id?: string; name?: string; slug?: string; media?: ...; actualPriceRange?: ... };
97
+ index?: number;
98
+ }
99
+ const { product, index } = Astro.props;
100
+ ```
101
+
102
+ The card fetches its own discount-rule offers internally via `fetchLiveOffers()` (memoized per-request), so pages don't pass an `offers` prop. Just `<ProductCard product={p} />`.
103
+
104
+ **Do NOT flat-map.** ProductCard handles image resolution, price formatting, and ribbon rendering internally.
105
+
106
+ **Verification:** After writing your Edit, grep `ProductCard.astro` for `Astro.props` and confirm the prop name in your `<ProductCard .../>` JSX matches `product`.
107
+
108
+ ### 2. Home page: category cards (slug matching)
109
+
110
+ The designer may hardcode category links like `href="/products?category=rubber"`. These rely on Stores-app categories matching those slugs. Phase 1 does NOT create categories — they're merchant-driven, so on a fresh build the only category in the catalog is the auto-managed "All Products" (which the helper filters out). Expect zero real categories on first load; the matching logic below should degrade gracefully to `/products` and re-evaluate on each request as the merchant adds categories in the dashboard.
111
+
112
+ Handle this:
113
+
114
+ 1. **Query real categories** via `@wix/stores` `categoriesV3`:
115
+ ```typescript
116
+ import { categoriesV3 } from "@wix/stores";
117
+ const { items: categories } = await categoriesV3.queryCategories().find();
118
+ ```
119
+ Fall back to `CallWixSiteAPI` with `POST /categories/v1/categories/query` body `{"query":{}}` if the SDK module is unavailable.
120
+ 2. **Match by name or slug** — case-insensitive substring match is fine (e.g., designer's "rubber" card matches a real category "Rubber Ducks").
121
+ 3. **If a match exists** → rewrite the `href` to use the real category slug (and optionally real category name).
122
+ 4. **If no match exists** → render the card with `/products` (no filter) rather than a dead filter URL. Keep the visual card intact.
123
+ 5. **If fewer real categories exist than cards the designer rendered** → render only matching cards. Do NOT invent categories.
124
+
125
+ > Never call `/stores/v3/categories/*` — category endpoints live under `/categories/v1/`. Improvising URLs caused a documented multi-minute stall in past runs.
126
+
127
+ ### 3. Navigation: Shop submenu
128
+
129
+ The designer scaffolds `Navigation.astro` with a `<!-- nav:links -->` marker that vertical packs replace with their primary nav contributions. Stores contributes the Shop link (always) and a hover/focus submenu listing the merchant's visible categories (when any exist — empty by default, since Phase 1 does not seed them).
130
+
131
+ Read `src/utils/categories.ts` (already on disk — written by `pages-categories`) and import `listStoreCategories`. At the marker, insert:
132
+
133
+ ```astro
134
+ ---
135
+ // (frontmatter additions to Navigation.astro — keep existing imports)
136
+ import { listStoreCategories } from "../utils/categories";
137
+
138
+ const navCategories = await listStoreCategories();
139
+ ---
140
+ ```
141
+
142
+ Then replace the `<!-- nav:links -->` marker with:
143
+
144
+ ```astro
145
+ <li class={`site-nav-item${navCategories.length > 0 ? ' has-submenu' : ''}`}>
146
+ <a
147
+ href="/products"
148
+ class="site-nav-link"
149
+ data-astro-prefetch="hover"
150
+ aria-current={isActive('/products') || isActive('/category') ? 'page' : undefined}
151
+ aria-haspopup={navCategories.length > 0 ? 'true' : undefined}
152
+ >Shop</a>
153
+ {navCategories.length > 0 && (
154
+ <ul class="site-nav-submenu" aria-label="Shop categories">
155
+ <li>
156
+ <a href="/products" class="site-nav-sublink" data-astro-prefetch="hover">All</a>
157
+ </li>
158
+ {navCategories.map((cat) => (
159
+ <li>
160
+ <a
161
+ href={`/category/${cat.slug}`}
162
+ class="site-nav-sublink"
163
+ data-astro-prefetch="hover"
164
+ aria-current={Astro.url.pathname === `/category/${cat.slug}` ? 'page' : undefined}
165
+ >{cat.name}</a>
166
+ </li>
167
+ ))}
168
+ </ul>
169
+ )}
170
+ </li>
171
+ <!-- nav:links -->
172
+ ```
173
+
174
+ Keep the marker comment immediately after the inserted `<li>` so other vertical packs (gift-cards, etc.) can still contribute siblings.
175
+
176
+ > **Empty-categories fallback.** `navCategories` is `[]` by default — Phase 1 does not seed categories, and `listStoreCategories()` only returns visible, non-empty, merchant-created categories. When empty, the submenu renders nothing and the link is just `Shop` with no dropdown. The aria-haspopup attribute is conditionally added so screen readers don't promise a menu that isn't there. As soon as the merchant creates a visible category with items in the dashboard, the submenu lights up automatically (≤ 5 min, the helper's TTL).
177
+
178
+ > **`isActive` is already defined** in the designer-scaffolded Navigation.astro frontmatter (it returns whether a path matches the current URL). Reuse it; do not redefine.
179
+
180
+ > **`data-astro-prefetch="hover"` is required** on every category link so hovering warms the prefetch cache before the click. Designer's Layout includes `<ClientRouter />` — without prefetch, each click waits a full network round-trip.
181
+
182
+ > **CSS for submenu** comes from designer's `global.css` (`.site-nav-item`, `.site-nav-submenu`, `.site-nav-sublink`, hover/focus reveals). If those classes don't exist, return `status: "partial"` with `errors: [{ code: "DESIGNER_MISSING_NAV_SUBMENU_CSS", path: "src/styles/global.css" }]`.
183
+
184
+ ## Return format
185
+
186
+ ```json
187
+ {
188
+ "status": "complete",
189
+ "phase": "stores-pages-home-and-nav",
190
+ "scope": "pages-home-and-nav",
191
+ "summary": "Wired home page featured products; inserted Shop submenu with N categories into Navigation",
192
+ "data": {
193
+ "homePageHadPlaceholders": true,
194
+ "featuredProductsWired": true,
195
+ "featuredProductsCount": 4,
196
+ "categoryCardsFound": 3,
197
+ "categoryCardsMatched": 2,
198
+ "categoryCardsFallbackToProducts": 1,
199
+ "navSubmenuCategoryCount": 0
200
+ },
201
+ "files": [
202
+ "src/pages/index.astro",
203
+ "src/components/Navigation.astro"
204
+ ],
205
+ "errors": []
206
+ }
207
+ ```
208
+
209
+ ## Scope boundaries (reinforced)
210
+
211
+ - **Do NOT edit** home page layout, copy, hero text, newsletter section, or decorative SVGs.
212
+ - **Do NOT add** new sections the designer didn't include.
213
+ - **Do NOT mutate** categories in the catalog — read-only.
214
+ - **Do NOT touch** `Navigation.astro` outside the `<!-- nav:links -->` marker. Other vertical packs use the same marker model and write siblings.
215
+ - **Do NOT touch** `CartBadge.tsx` or `CartView.tsx` — owned by ecom.
216
+ - **Do NOT rewrite** `src/utils/categories.ts` or `src/components/CategoryRail.astro` — owned by `pages-categories`.
217
+ - If home page already has a live query (another agent wired it), leave alone and note in return.
218
+
219
+ ## Anti-patterns
220
+
221
+ | WRONG | CORRECT |
222
+ |-------|---------|
223
+ | Replace entire `index.astro` contents | Use `Edit` to patch only the stores-related sections |
224
+ | Call `/stores/v3/categories/query` | Use `categoriesV3` SDK, or fall back to `/categories/v1/categories/query` |
225
+ | Invent category slugs that don't exist | Match real categories; fall back to `/products` for unmatched |
226
+ | Pass flat props (`name={p.name}`) when ProductCard expects `product={...}` object | ProductCard is a template — always `<ProductCard product={p} />` with the raw SDK object |
227
+ | `featured = products.map(p => ({name: p.name, ...}))` — flat-mapping SDK results | Store raw products: `featured = featuredProducts ?? []` as `any[]` |