@wix/agent-skills 1.13.0 → 1.15.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 (250) hide show
  1. package/README.md +4 -1
  2. package/package.json +1 -1
  3. package/skills/README.md +23 -0
  4. package/skills/wix-app/SKILL.md +10 -2
  5. package/skills/wix-app/references/AUTO_PATTERNS_DASHBOARD.md +326 -0
  6. package/skills/wix-app/references/CODE_QUALITY.md +1 -0
  7. package/skills/wix-app/references/CUSTOM_ELEMENT_WIDGET.md +124 -115
  8. package/skills/wix-app/references/DASHBOARD_PAGE.md +3 -0
  9. package/skills/wix-app/references/EDITOR_REACT_COMPONENT.md +23 -9
  10. package/skills/wix-app/references/SITE_PLUGIN.md +1 -1
  11. package/skills/wix-app/references/auto-patterns-dashboard/action-cell.md +115 -0
  12. package/skills/wix-app/references/auto-patterns-dashboard/app-config-structure.md +264 -0
  13. package/skills/wix-app/references/auto-patterns-dashboard/app-context.md +37 -0
  14. package/skills/wix-app/references/auto-patterns-dashboard/bulk-actions.md +86 -0
  15. package/skills/wix-app/references/auto-patterns-dashboard/collection-page-actions.md +119 -0
  16. package/skills/wix-app/references/auto-patterns-dashboard/collection-page.md +103 -0
  17. package/skills/wix-app/references/auto-patterns-dashboard/custom-actions-override.md +76 -0
  18. package/skills/wix-app/references/auto-patterns-dashboard/custom-columns-override.md +82 -0
  19. package/skills/wix-app/references/auto-patterns-dashboard/custom-components-override.md +89 -0
  20. package/skills/wix-app/references/auto-patterns-dashboard/custom-header-override.md +124 -0
  21. package/skills/wix-app/references/auto-patterns-dashboard/custom-sections-override.md +91 -0
  22. package/skills/wix-app/references/auto-patterns-dashboard/custom-slots-override.md +71 -0
  23. package/skills/wix-app/references/auto-patterns-dashboard/entity-page-actions.md +70 -0
  24. package/skills/wix-app/references/auto-patterns-dashboard/entity-page-view-actions.md +73 -0
  25. package/skills/wix-app/references/auto-patterns-dashboard/entity-page.md +98 -0
  26. package/skills/wix-app/references/auto-patterns-dashboard/example-patterns.json +278 -0
  27. package/skills/wix-app/references/auto-patterns-dashboard/pages-configuration.md +94 -0
  28. package/skills/wix-app/references/auto-patterns-dashboard/resolved-action.md +43 -0
  29. package/skills/wix-app/references/auto-patterns-dashboard/sdk-utilities.md +66 -0
  30. package/skills/wix-app/references/auto-patterns-dashboard/views.md +76 -0
  31. package/skills/wix-app/references/editor-react-component/ACCESSIBILITY.md +1 -14
  32. package/skills/wix-app/references/editor-react-component/COMPONENT-API.md +54 -29
  33. package/skills/wix-app/references/editor-react-component/COMPONENT-CONFIGURATION.md +2 -2
  34. package/skills/wix-app/references/editor-react-component/CSS-GUIDELINES.md +17 -105
  35. package/skills/wix-app/references/editor-react-component/DESIGN-STATES.md +127 -0
  36. package/skills/wix-app/references/editor-react-component/PARTS.md +2 -1
  37. package/skills/wix-app/references/editor-react-component/REACT-GUIDELINES.md +15 -15
  38. package/skills/wix-app/references/editor-react-component/REACT-PATTERNS.md +25 -53
  39. package/skills/wix-app/scripts/generate-auto-patterns.js +510 -0
  40. package/skills/wix-auth/SKILL.md +12 -0
  41. package/skills/wix-auth/references/device-flow.md +140 -0
  42. package/skills/wix-docs/SKILL.md +188 -0
  43. package/skills/wix-docs/references/API_SPEC_SEARCH.md +213 -0
  44. package/skills/wix-docs/references/EXTRACTING.md +120 -0
  45. package/skills/wix-headless/SKILL.md +84 -130
  46. package/skills/wix-headless/entry/bootstrap.mjs +93 -0
  47. package/skills/wix-headless/entry/skill.md +78 -0
  48. package/skills/wix-headless/references/AI_FEATURES.md +178 -0
  49. package/skills/wix-headless/references/CAPABILITIES.md +84 -0
  50. package/skills/wix-headless/references/DISCOVERY.md +34 -56
  51. package/skills/wix-headless/references/DOC_DISCOVERY.md +37 -0
  52. package/skills/wix-headless/references/FEEDBACK.md +118 -0
  53. package/skills/wix-headless/references/IMAGE_GENERATION.md +69 -0
  54. package/skills/wix-headless/references/SDK_HANDOFF.md +97 -0
  55. package/skills/wix-headless/references/SEED.md +44 -188
  56. package/skills/wix-headless/references/SETUP.md +32 -103
  57. package/skills/wix-headless/references/astro.md +98 -0
  58. package/skills/wix-headless/references/inline-recipes/how-to-code-a-blog.md +196 -0
  59. package/skills/wix-headless/references/inline-recipes/how-to-code-a-store.md +236 -0
  60. package/skills/wix-headless/references/inline-recipes/how-to-code-bookings.md +279 -0
  61. package/skills/wix-headless/references/inline-recipes/how-to-code-cms.md +163 -0
  62. package/skills/wix-headless/references/inline-recipes/how-to-code-events.md +203 -0
  63. package/skills/wix-headless/references/inline-recipes/how-to-code-forms.md +222 -0
  64. package/skills/wix-headless/references/inline-recipes/how-to-code-members-astro.md +124 -0
  65. package/skills/wix-headless/references/inline-recipes/how-to-code-members-custom-login.md +160 -0
  66. package/skills/wix-headless/references/inline-recipes/how-to-code-members-non-astro.md +118 -0
  67. package/skills/wix-headless/references/inline-recipes/how-to-code-portfolio.md +132 -0
  68. package/skills/wix-headless/references/inline-recipes/how-to-code-pricing-plans.md +124 -0
  69. package/skills/wix-headless/references/inline-recipes/how-to-code-restaurant-orders.md +188 -0
  70. package/skills/wix-headless/references/inline-recipes/how-to-code-restaurant-reservations.md +173 -0
  71. package/skills/wix-headless/references/inline-recipes/how-to-code-restaurants.md +161 -0
  72. package/skills/wix-headless/references/inline-recipes/setup-blog.md +175 -0
  73. package/skills/wix-headless/references/inline-recipes/setup-bookings.md +228 -0
  74. package/skills/wix-headless/references/inline-recipes/setup-cms.md +200 -0
  75. package/skills/wix-headless/references/inline-recipes/setup-events.md +196 -0
  76. package/skills/wix-headless/references/inline-recipes/setup-forms.md +174 -0
  77. package/skills/wix-headless/references/inline-recipes/setup-online-store.md +176 -0
  78. package/skills/wix-headless/references/inline-recipes/setup-portfolio.md +153 -0
  79. package/skills/wix-headless/references/inline-recipes/setup-pricing-plans.md +229 -0
  80. package/skills/wix-headless/references/inline-recipes/setup-restaurant-orders.md +161 -0
  81. package/skills/wix-headless/references/inline-recipes/setup-restaurant-reservations.md +117 -0
  82. package/skills/wix-headless/references/inline-recipes/setup-restaurants.md +152 -0
  83. package/skills/wix-headless/references/managed/AUTHENTICATION.md +57 -0
  84. package/skills/wix-headless/references/managed/CONNECT.md +74 -0
  85. package/skills/wix-headless/references/managed/CREATE.md +130 -0
  86. package/skills/wix-headless/references/managed/DEPLOYMENT.md +57 -0
  87. package/skills/wix-headless/references/non-astro.md +59 -0
  88. package/skills/wix-headless/references/self-managed/AUTHENTICATION.md +22 -0
  89. package/skills/wix-headless/references/self-managed/DEPLOYMENT.md +7 -0
  90. package/skills/wix-headless/references/stripe/AUTHENTICATION.md +55 -0
  91. package/skills/wix-headless/references/stripe/DEPLOYMENT.md +63 -0
  92. package/skills/wix-manage/SKILL.md +24 -1
  93. package/skills/wix-manage/references/analytics/query-site-analytics.md +241 -0
  94. package/skills/wix-manage/references/bookings/create-and-update-booking-services.md +1 -1
  95. package/skills/wix-manage/references/bookings/diagnose-availability-issues.md +265 -0
  96. package/skills/wix-manage/references/marketing/create-and-publish-social-post.md +436 -0
  97. package/skills/wix-manage/references/marketing/generate-and-publish-marketing-plan.md +209 -0
  98. package/skills/wix-manage/references/rich-content/author-ricos-rich-content.md +249 -0
  99. package/skills/wix-manage/references/stores/create-product-with-options-catalog-v3.md +51 -0
  100. package/skills/wix-vibe-headless/SKILL.md +136 -0
  101. package/skills/wix-vibe-headless/references/blog/INSTRUCTIONS.md +128 -0
  102. package/skills/wix-vibe-headless/references/blog/wix-blog.js +217 -0
  103. package/skills/wix-vibe-headless/references/bookings/INSTRUCTIONS.md +153 -0
  104. package/skills/wix-vibe-headless/references/bookings/wix-bookings-checkout.js +147 -0
  105. package/skills/wix-vibe-headless/references/bookings/wix-bookings-services.js +215 -0
  106. package/skills/wix-vibe-headless/references/cms/INSTRUCTIONS.md +154 -0
  107. package/skills/wix-vibe-headless/references/cms/wix-cms.js +186 -0
  108. package/skills/wix-vibe-headless/references/events/INSTRUCTIONS.md +142 -0
  109. package/skills/wix-vibe-headless/references/events/wix-events-browse.js +135 -0
  110. package/skills/wix-vibe-headless/references/events/wix-events-registration.js +187 -0
  111. package/skills/wix-vibe-headless/references/members/INSTRUCTIONS.md +211 -0
  112. package/skills/wix-vibe-headless/references/members/wix-members-auth.js +387 -0
  113. package/skills/wix-vibe-headless/references/portfolio/INSTRUCTIONS.md +111 -0
  114. package/skills/wix-vibe-headless/references/portfolio/wix-portfolio.js +194 -0
  115. package/skills/wix-vibe-headless/references/pricing-plans/INSTRUCTIONS.md +127 -0
  116. package/skills/wix-vibe-headless/references/pricing-plans/wix-pricing-plans.js +157 -0
  117. package/skills/wix-vibe-headless/references/restaurants/INSTRUCTIONS.md +138 -0
  118. package/skills/wix-vibe-headless/references/restaurants/wix-restaurants-menu.js +224 -0
  119. package/skills/wix-vibe-headless/references/restaurants/wix-restaurants-ordering.js +156 -0
  120. package/skills/wix-vibe-headless/references/restaurants/wix-restaurants-reservations.js +107 -0
  121. package/skills/wix-vibe-headless/references/shared/wix-client.js +186 -0
  122. package/skills/wix-vibe-headless/references/storefront/INSTRUCTIONS.md +155 -0
  123. package/skills/wix-vibe-headless/references/storefront/wix-store-cart.js +147 -0
  124. package/skills/wix-vibe-headless/references/storefront/wix-store-catalog.js +142 -0
  125. package/skills/wix-headless/references/BUILD-astro.md +0 -244
  126. package/skills/wix-headless/references/BUILD-own-build.md +0 -167
  127. package/skills/wix-headless/references/BUILD.md +0 -105
  128. package/skills/wix-headless/references/DESIGN_SYSTEM.md +0 -165
  129. package/skills/wix-headless/references/DISCOVERY-connect.md +0 -55
  130. package/skills/wix-headless/references/DISCOVERY-create.md +0 -238
  131. package/skills/wix-headless/references/PLAN-connect.md +0 -19
  132. package/skills/wix-headless/references/PLAN-create.md +0 -17
  133. package/skills/wix-headless/references/PLAN.md +0 -92
  134. package/skills/wix-headless/references/astro/blog/BLOG_PAGES.md +0 -300
  135. package/skills/wix-headless/references/astro/blog/BLOG_SETUP.md +0 -218
  136. package/skills/wix-headless/references/astro/bookings/COMPONENTS.md +0 -45
  137. package/skills/wix-headless/references/astro/bookings/SERVICES_PAGES.md +0 -77
  138. package/skills/wix-headless/references/astro/cms/CMS_FOUNDATIONS.md +0 -214
  139. package/skills/wix-headless/references/astro/cms/FAQ_KNOWLEDGE_BASE.md +0 -231
  140. package/skills/wix-headless/references/astro/cms/PORTFOLIO.md +0 -453
  141. package/skills/wix-headless/references/astro/cms/RESOURCE_LIBRARY.md +0 -354
  142. package/skills/wix-headless/references/astro/cms/TEAM_DIRECTORY.md +0 -299
  143. package/skills/wix-headless/references/astro/designer/INSTRUCTIONS.md +0 -351
  144. package/skills/wix-headless/references/astro/ecom/CART_PAGES.md +0 -119
  145. package/skills/wix-headless/references/astro/ecom/CART_WIRING.md +0 -103
  146. package/skills/wix-headless/references/astro/ecom/COMPONENTS_CSS.md +0 -132
  147. package/skills/wix-headless/references/astro/forms/CONTACT_FORM.md +0 -463
  148. package/skills/wix-headless/references/astro/gift-cards/COMPONENTS.md +0 -119
  149. package/skills/wix-headless/references/astro/gift-cards/PAGES.md +0 -129
  150. package/skills/wix-headless/references/astro/stores/BACK_IN_STOCK.md +0 -178
  151. package/skills/wix-headless/references/astro/stores/CATEGORY_PAGES.md +0 -85
  152. package/skills/wix-headless/references/astro/stores/COMPONENTS_CSS.md +0 -129
  153. package/skills/wix-headless/references/astro/stores/HOME_AND_NAV.md +0 -229
  154. package/skills/wix-headless/references/astro/stores/PRODUCT_PAGES.md +0 -215
  155. package/skills/wix-headless/references/astro/stores/SHARED_WIRING.md +0 -165
  156. package/skills/wix-headless/references/astro/templates/Footer.astro +0 -27
  157. package/skills/wix-headless/references/astro/templates/Layout.astro +0 -132
  158. package/skills/wix-headless/references/astro/templates/Navigation.astro +0 -38
  159. package/skills/wix-headless/references/astro/templates/astro.config.mjs +0 -41
  160. package/skills/wix-headless/references/astro/templates/bookings/AvailabilityCalendar.tsx +0 -374
  161. package/skills/wix-headless/references/astro/templates/bookings/BookingForm.tsx +0 -136
  162. package/skills/wix-headless/references/astro/templates/bookings/SeoTags.astro +0 -25
  163. package/skills/wix-headless/references/astro/templates/bookings/ServiceBookingFlow.tsx +0 -71
  164. package/skills/wix-headless/references/astro/templates/bookings/ServiceCard.astro +0 -54
  165. package/skills/wix-headless/references/astro/templates/bookings/booking-confirmation.astro +0 -49
  166. package/skills/wix-headless/references/astro/templates/bookings/bookingDriver.ts +0 -245
  167. package/skills/wix-headless/references/astro/templates/bookings/components-bookings.css +0 -424
  168. package/skills/wix-headless/references/astro/templates/bookings/services/[slug].astro +0 -176
  169. package/skills/wix-headless/references/astro/templates/bookings/services/index.astro +0 -181
  170. package/skills/wix-headless/references/astro/templates/ecom/CartBadge.tsx +0 -84
  171. package/skills/wix-headless/references/astro/templates/ecom/CartView.tsx +0 -543
  172. package/skills/wix-headless/references/astro/templates/ecom/cart.astro +0 -13
  173. package/skills/wix-headless/references/astro/templates/ecom/components-ecom.css +0 -302
  174. package/skills/wix-headless/references/astro/templates/ecom/discounts.ts +0 -71
  175. package/skills/wix-headless/references/astro/templates/ecom/thank-you.astro +0 -24
  176. package/skills/wix-headless/references/astro/templates/gift-cards/GiftCardPurchase.tsx +0 -172
  177. package/skills/wix-headless/references/astro/templates/gift-cards/_home-teaser-snippet.astro +0 -42
  178. package/skills/wix-headless/references/astro/templates/gift-cards/_nav-snippet.astro +0 -11
  179. package/skills/wix-headless/references/astro/templates/gift-cards/components-gift-cards.css +0 -220
  180. package/skills/wix-headless/references/astro/templates/gift-cards/gift-cards.astro +0 -51
  181. package/skills/wix-headless/references/astro/templates/gift-cards/gift-cards.ts +0 -75
  182. package/skills/wix-headless/references/astro/templates/global.css +0 -288
  183. package/skills/wix-headless/references/astro/templates/index.astro +0 -56
  184. package/skills/wix-headless/references/astro/templates/stores/AddToCartButton.tsx +0 -77
  185. package/skills/wix-headless/references/astro/templates/stores/BackInStockForm.tsx +0 -176
  186. package/skills/wix-headless/references/astro/templates/stores/CategoryRail.astro +0 -69
  187. package/skills/wix-headless/references/astro/templates/stores/ProductCard.astro +0 -79
  188. package/skills/wix-headless/references/astro/templates/stores/ProductPurchase.tsx +0 -397
  189. package/skills/wix-headless/references/astro/templates/stores/SeoTags.astro +0 -21
  190. package/skills/wix-headless/references/astro/templates/stores/back-in-stock.ts +0 -67
  191. package/skills/wix-headless/references/astro/templates/stores/categories.ts +0 -155
  192. package/skills/wix-headless/references/astro/templates/stores/category/[slug].astro +0 -130
  193. package/skills/wix-headless/references/astro/templates/stores/components-stores.css +0 -400
  194. package/skills/wix-headless/references/astro/templates/stores/products/[slug].astro +0 -128
  195. package/skills/wix-headless/references/astro/templates/stores/products/index.astro +0 -101
  196. package/skills/wix-headless/references/blog/BLOG_CONTENT.md +0 -161
  197. package/skills/wix-headless/references/blog/INSTRUCTIONS.md +0 -32
  198. package/skills/wix-headless/references/bookings/FLOW.md +0 -246
  199. package/skills/wix-headless/references/bookings/INSTRUCTIONS.md +0 -95
  200. package/skills/wix-headless/references/bookings/SERVICES_DATA.md +0 -355
  201. package/skills/wix-headless/references/cms/CMS_FOUNDATIONS.md +0 -176
  202. package/skills/wix-headless/references/cms/INSTRUCTIONS.md +0 -71
  203. package/skills/wix-headless/references/commands/known-apps.json +0 -6
  204. package/skills/wix-headless/references/custom/CONNECTION_PLAN.md +0 -142
  205. package/skills/wix-headless/references/custom/INSTRUCTIONS.md +0 -88
  206. package/skills/wix-headless/references/custom/blog/WIRING.md +0 -52
  207. package/skills/wix-headless/references/custom/bookings/WIRING.md +0 -197
  208. package/skills/wix-headless/references/custom/cms/WIRING.md +0 -97
  209. package/skills/wix-headless/references/custom/ecom/WIRING.md +0 -67
  210. package/skills/wix-headless/references/custom/forms/WIRING.md +0 -101
  211. package/skills/wix-headless/references/custom/stores/WIRING.md +0 -80
  212. package/skills/wix-headless/references/ecom/INSTRUCTIONS.md +0 -59
  213. package/skills/wix-headless/references/forms/INSTRUCTIONS.md +0 -43
  214. package/skills/wix-headless/references/gift-cards/INSTRUCTIONS.md +0 -51
  215. package/skills/wix-headless/references/images/INSTRUCTIONS.md +0 -357
  216. package/skills/wix-headless/references/seed-recipes.md +0 -49
  217. package/skills/wix-headless/references/shared/AGENTS_MD.md +0 -47
  218. package/skills/wix-headless/references/shared/AUTHENTICATION.md +0 -108
  219. package/skills/wix-headless/references/shared/BUILD_NOISE.md +0 -8
  220. package/skills/wix-headless/references/shared/DESIGN_MD.md +0 -84
  221. package/skills/wix-headless/references/shared/DOCS_SEARCH.md +0 -41
  222. package/skills/wix-headless/references/shared/IMAGE_GENERATION.md +0 -186
  223. package/skills/wix-headless/references/shared/IMPLEMENTER.md +0 -206
  224. package/skills/wix-headless/references/shared/PRODUCTION_SHARP_EDGES.md +0 -97
  225. package/skills/wix-headless/references/shared/RETURN_CONTRACT.md +0 -143
  226. package/skills/wix-headless/references/shared/STYLING.md +0 -141
  227. package/skills/wix-headless/references/stores/INSTRUCTIONS.md +0 -126
  228. package/skills/wix-headless/references/stores/PRODUCT_CATALOG_DATA.md +0 -252
  229. package/skills/wix-headless/references/verticals/_schema.json +0 -74
  230. package/skills/wix-headless/references/verticals/_schema.md +0 -95
  231. package/skills/wix-headless/references/verticals/blog.md +0 -31
  232. package/skills/wix-headless/references/verticals/bookings.md +0 -41
  233. package/skills/wix-headless/references/verticals/cms.md +0 -30
  234. package/skills/wix-headless/references/verticals/ecom.md +0 -25
  235. package/skills/wix-headless/references/verticals/forms.md +0 -26
  236. package/skills/wix-headless/references/verticals/gift-cards.md +0 -24
  237. package/skills/wix-headless/references/verticals/stores.md +0 -33
  238. package/skills/wix-headless/scripts/check-manifest.mjs +0 -335
  239. package/skills/wix-headless/scripts/compose.mjs +0 -525
  240. package/skills/wix-headless/scripts/emit-design-tokens.mjs +0 -157
  241. package/skills/wix-headless/scripts/flatten.sh +0 -61
  242. package/skills/wix-headless/scripts/generate-images.mjs +0 -242
  243. package/skills/wix-headless/scripts/patch-decorative-slots.mjs +0 -148
  244. package/skills/wix-headless/scripts/plan-entity-image-waves.mjs +0 -190
  245. package/skills/wix-headless/scripts/scaffold.sh +0 -139
  246. package/skills/wix-headless/scripts/seed-utilities.sh +0 -93
  247. package/skills/wix-headless/scripts/write-decorative-json.mjs +0 -62
  248. package/skills/wix-headless/shared-utilities/analytics.ts +0 -40
  249. package/skills/wix-headless/shared-utilities/ricos.ts +0 -179
  250. package/skills/wix-headless/shared-utilities/wix-image.ts +0 -72
@@ -1,229 +0,0 @@
1
- # Phase 4 Home Page + Nav — Stores
2
-
3
- Scope: `pages-home-and-nav` — dispatched as its **own serialized shell-patcher agent** in the build wave (NOT merged into the stores private-files agent, because it patches the shared shells). Imports the orchestrator-pre-copied `categories.ts` helper and the `CategoryRail`/`ProductCard` the stores private agent writes — **resolved at build time, so no write-ordering against that agent.** Patches the home page's stores-related placeholder data with live `productsV3` queries AND inserts the Shop submenu (categories list) into the persisted Navigation at the `<!-- nav:links -->` marker. (The `CartBadge` mount at `<!-- nav:actions -->` is ecom's; you own only `<!-- nav:links -->`.) Read your seeded slice from `.wix/seeded.json` (`seeded.stores`).
4
-
5
- > **You patch the shared `Navigation.astro` + `index.astro` shells**, which other packs (ecom at `nav:actions`, gift-cards, blog) also patch at their own markers. **Touch only your markers and preserve every other scope's siblings — never rewrite either file.** (Flow is the conductor's job: it serializes the shell-patching agents so concurrent marker edits don't collide — BUILD-astro.md § "Step 4.5", the serialized shell chain.)
6
-
7
- ## Scope
8
-
9
- Files this agent PATCHES (does NOT rewrite):
10
-
11
- - `src/pages/index.astro` — only the stores-related sections (featured products grid, category cards)
12
- - `src/components/Navigation.astro` — only at the `<!-- nav:links -->` marker; insert the Shop link + categories submenu
13
-
14
- Files this agent MUST NOT touch:
15
- - Any other part of `index.astro` — hero, copy, newsletter, decorative ornaments are designer-owned
16
- - Any part of `Navigation.astro` outside the `<!-- nav:links -->` marker — designer/ecom-owned (the marker model lets multiple verticals contribute siblings without conflict)
17
- - `src/utils/categories.ts` — pre-copied by the orchestrator; this scope only **imports** `listStoreCategories` from it. `src/components/CategoryRail.astro`, `src/pages/category/[slug].astro` — owned by `pages-categories`
18
- - Any other component, page, or CSS
19
- - `global.css`
20
-
21
- ## Inputs (from parent prompt)
22
-
23
- - **Phase 1 stores return** — `products: [{id, name, slug, ...}]`. Needed for live query on home page; also useful for deciding how many to feature.
24
- - **Design tokens** — read the design tokens (the DESIGN.md vocabulary) from `.wix/design-tokens.css` (on disk) 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.
25
- - **Designer output summary** — path of `src/pages/index.astro` and `src/components/Navigation.astro`, with notes on what placeholder data exists.
26
- - **Categories (lookup)** — if the designer used category links with hardcoded slugs, call `categoriesV3` SDK to discover real category slugs and rewrite `href`s.
27
-
28
- ## Critical rules
29
-
30
- 1. **Surgical edits only.** Use `Edit` tool, not `Write`. Preserve everything the designer wrote — hero, copy, decorative elements, section structure, class names.
31
- 2. **Do NOT restructure layout.** If the designer didn't include featured products, don't add it.
32
- 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.
33
- 4. **Never improvise category endpoint URLs.** Use `categoriesV3` SDK. If the SDK isn't available, fall back to `curl` with `POST /categories/v1/categories/query` body `{"query":{}}`. Improvised `/stores/v3/categories/...` URLs cause a multi-minute stall.
34
- 5. **If another agent already wired the home page** (e.g., a previous run), leave it alone and note this in the return.
35
- 6. **ProductCard is a template** — always accepts `{ product }`. Pass raw SDK product objects, never flat-map. See § 1a.
36
-
37
- ## When to run the home-page patch
38
-
39
- Skip the home-page patch entirely if the home page has NO stores-consuming components:
40
-
41
- - No `ProductGrid` / `ProductCard` with placeholder products array
42
- - No category cards with hardcoded category slugs (e.g., `/products?category=...`)
43
-
44
- If the home page is purely editorial (hero + copy + newsletter), return with `featuredProductsWired: false` — there's nothing to patch.
45
-
46
- ## Implementation
47
-
48
- ### 1. Home page: featured products
49
-
50
- Find the placeholder products array in `src/pages/index.astro`. Replace with a server-side `productsV3` query; pass the raw product objects to `ProductCard`.
51
-
52
- > **WRONG:** `featured = products.map(p => ({name: p.name, price: ...}))` then `<ProductCard name={p.name} .../>`
53
- > **RIGHT:** `featured = featuredProducts ?? []` as `any[]`, then `<ProductCard product={p} />`
54
- >
55
- > Flat-mapping strips fields that ProductCard needs (`media`, `actualPriceRange`, etc.) and crashes the home page (`product` is `undefined`).
56
-
57
- ```astro
58
- ---
59
- // src/pages/index.astro (frontmatter additions only — keep existing imports)
60
- import { productsV3 } from "@wix/stores";
61
-
62
- // Wrap every SSR await in try/catch — see references/shared/IMPLEMENTER.md
63
- // § "SSR error guards" for the full rule.
64
- let featured: any[] = [];
65
- try {
66
- const { items: featuredProducts } = await productsV3
67
- .queryProducts({ fields: ["CURRENCY"] })
68
- .limit(4)
69
- .find();
70
- featured = featuredProducts ?? [];
71
- } catch (err) {
72
- console.error("[home] featured products query failed:", err);
73
- }
74
- ---
75
- ```
76
-
77
- Then pass each raw product to `ProductCard`. The ribbon is fetched inside ProductCard itself — pages don't wire offers:
78
- ```astro
79
- {featured.map((p) => <ProductCard product={p} />)}
80
- ```
81
-
82
- > **Gift-card mirror filter.** After `featured = featuredProducts ?? []`, apply the same filter the listing template uses:
83
- > ```ts
84
- > featured = featured.filter((p) => p.ribbon?.name !== "Gift Card");
85
- > ```
86
- > 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.
87
-
88
- 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.
89
-
90
- 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.
91
-
92
- ### 1a. ProductCard interface (template — deterministic)
93
-
94
- ProductCard is a **template file** (`templates/ProductCard.astro`). The `product-pages` scope copies it deterministically. The interface is:
95
-
96
- ```astro
97
- interface Props {
98
- product: { _id?: string; name?: string; slug?: string; media?: ...; actualPriceRange?: ... };
99
- index?: number;
100
- }
101
- const { product, index } = Astro.props;
102
- ```
103
-
104
- 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} />`.
105
-
106
- **Do NOT flat-map.** ProductCard handles image resolution, price formatting, and ribbon rendering internally.
107
-
108
- **Verification:** After writing your Edit, grep `ProductCard.astro` for `Astro.props` and confirm the prop name in your `<ProductCard .../>` JSX matches `product`.
109
-
110
- ### 2. Home page: category cards (slug matching)
111
-
112
- 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.
113
-
114
- Handle this:
115
-
116
- 1. **Query real categories** via `@wix/stores` `categoriesV3`:
117
- ```typescript
118
- import { categoriesV3 } from "@wix/stores";
119
- const { items: categories } = await categoriesV3.queryCategories().find();
120
- ```
121
- Fall back to `curl` with `POST https://www.wixapis.com/categories/v1/categories/query` body `{"query":{}}` if the SDK module is unavailable (headers per `AUTHENTICATION.md`).
122
- 2. **Match by name or slug** — case-insensitive substring match is fine (e.g., designer's "rubber" card matches a real category "Rubber Ducks").
123
- 3. **If a match exists** → rewrite the `href` to use the real category slug (and optionally real category name).
124
- 4. **If no match exists** → render the card with `/products` (no filter) rather than a dead filter URL. Keep the visual card intact.
125
- 5. **If fewer real categories exist than cards the designer rendered** → render only matching cards. Do NOT invent categories.
126
-
127
- > Never call `/stores/v3/categories/*` — category endpoints live under `/categories/v1/`. Improvising URLs caused a documented multi-minute stall in past runs.
128
-
129
- ### 3. Navigation: Shop submenu
130
-
131
- 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).
132
-
133
- Import `listStoreCategories` from `src/utils/categories.ts` (already on disk — pre-copied by the orchestrator). At the marker, insert:
134
-
135
- ```astro
136
- ---
137
- // (frontmatter additions to Navigation.astro — keep existing imports)
138
- import { listStoreCategories } from "../utils/categories";
139
-
140
- const navCategories = await listStoreCategories();
141
- ---
142
- ```
143
-
144
- Then replace the `<!-- nav:links -->` marker with:
145
-
146
- ```astro
147
- <li class={`site-nav-item${navCategories.length > 0 ? ' has-submenu' : ''}`}>
148
- <a
149
- href="/products"
150
- class="site-nav-link"
151
- data-astro-prefetch="hover"
152
- aria-current={isActive('/products') || isActive('/category') ? 'page' : undefined}
153
- aria-haspopup={navCategories.length > 0 ? 'true' : undefined}
154
- >Shop</a>
155
- {navCategories.length > 0 && (
156
- <ul class="site-nav-submenu" aria-label="Shop categories">
157
- <li>
158
- <a href="/products" class="site-nav-sublink" data-astro-prefetch="hover">All</a>
159
- </li>
160
- {navCategories.map((cat) => (
161
- <li>
162
- <a
163
- href={`/category/${cat.slug}`}
164
- class="site-nav-sublink"
165
- data-astro-prefetch="hover"
166
- aria-current={Astro.url.pathname === `/category/${cat.slug}` ? 'page' : undefined}
167
- >{cat.name}</a>
168
- </li>
169
- ))}
170
- </ul>
171
- )}
172
- </li>
173
- <!-- nav:links -->
174
- ```
175
-
176
- Keep the marker comment immediately after the inserted `<li>` so other vertical packs (gift-cards, etc.) can still contribute siblings.
177
-
178
- > **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).
179
-
180
- > **`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.
181
-
182
- > **`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.
183
-
184
- > **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" }]`.
185
-
186
- ## Return format
187
-
188
- ```json
189
- {
190
- "status": "complete",
191
- "phase": "stores-pages-home-and-nav",
192
- "scope": "pages-home-and-nav",
193
- "summary": "Wired home page featured products; inserted Shop submenu with N categories into Navigation",
194
- "data": {
195
- "homePageHadPlaceholders": true,
196
- "featuredProductsWired": true,
197
- "featuredProductsCount": 4,
198
- "categoryCardsFound": 3,
199
- "categoryCardsMatched": 2,
200
- "categoryCardsFallbackToProducts": 1,
201
- "navSubmenuCategoryCount": 0
202
- },
203
- "files": [
204
- "src/pages/index.astro",
205
- "src/components/Navigation.astro"
206
- ],
207
- "errors": []
208
- }
209
- ```
210
-
211
- ## Scope boundaries (reinforced)
212
-
213
- - **Do NOT edit** home page layout, copy, hero text, newsletter section, or decorative SVGs.
214
- - **Do NOT add** new sections the designer didn't include.
215
- - **Do NOT mutate** categories in the catalog — read-only.
216
- - **Do NOT touch** `Navigation.astro` outside the `<!-- nav:links -->` marker. Other vertical packs use the same marker model and write siblings.
217
- - **Do NOT touch** `CartBadge.tsx` or `CartView.tsx` — owned by ecom.
218
- - **Do NOT rewrite** `src/utils/categories.ts` (pre-copied by the orchestrator — import only) or `src/components/CategoryRail.astro` (owned by `pages-categories`).
219
- - If home page already has a live query (another agent wired it), leave alone and note in return.
220
-
221
- ## Anti-patterns
222
-
223
- | WRONG | CORRECT |
224
- |-------|---------|
225
- | Replace entire `index.astro` contents | Use `Edit` to patch only the stores-related sections |
226
- | Call `/stores/v3/categories/query` | Use `categoriesV3` SDK, or fall back to `/categories/v1/categories/query` |
227
- | Invent category slugs that don't exist | Match real categories; fall back to `/products` for unmatched |
228
- | Pass flat props (`name={p.name}`) when ProductCard expects `product={...}` object | ProductCard is a template — always `<ProductCard product={p} />` with the raw SDK object |
229
- | `featured = products.map(p => ({name: p.name, ...}))` — flat-mapping SDK results | Store raw products: `featured = featuredProducts ?? []` as `any[]` |
@@ -1,215 +0,0 @@
1
- # Phase 4 Product Pages — Stores
2
-
3
- Scope: `product-pages` (the `pages-products` scope) — written by the stores **merged build agent** (the build wave) *after* its `components` and `pages-categories` scopes. This scope writes the product listing, product detail, and ProductCard component **once** — applying the designer's visual spec (`references/astro/designer/INSTRUCTIONS.md` → `store-pages`) together with live `productsV3` queries in a single pass. Read your seeded slice from `.wix/seeded.json` (`seeded.stores`).
4
-
5
- ## Scope
6
-
7
- Files this agent OWNS (each written once, visual structure + live queries together):
8
-
9
- - `src/pages/products/index.astro` — product listing
10
- - `src/pages/products/[slug].astro` — product detail with `wixMetadata` + SEO tags
11
- - `src/components/ProductCard.astro` — reusable card used by listing + home
12
-
13
- Files this agent MUST NOT touch:
14
- - `src/components/ProductPurchase.tsx`, `src/components/AddToCartButton.tsx` — owned by `components`
15
- - `src/pages/cart.astro`, `src/pages/thank-you.astro` — owned by `cart-checkout`
16
- - `src/pages/index.astro`, `src/components/Navigation.astro` — owned by `pages-home-and-nav`
17
- - `src/components/CategoryRail.astro` — owned by the `pages-categories` scope, which your merged agent writes **before** this one. **Import** from `../../components/CategoryRail.astro`; never `Write` it here. By the time you mount it, the `pages-categories` step has already put it on disk. If it's somehow absent, you wrote your scopes out of order — return `status: "partial"` with `errors: [{ code: "MISSING_PAGES_CATEGORIES_OUTPUT", path: "src/components/CategoryRail.astro" }]` (write `pages-categories` before `pages-products`; never defensively `Write` it from this scope).
18
- - `src/utils/categories.ts` — pre-copied by the orchestrator in the build-wave pre-batch (BUILD-astro.md § "Step 4.5"). **Import** `listStoreCategories`/etc. from `../../utils/categories`; never `Write` it.
19
- - `global.css`, any other `.astro` page, any other component — owned by designers
20
-
21
- ## Inputs (from parent prompt)
22
-
23
- - **Phase 1 return data** — `products: [{id, name, slug, variantId, price, inventory, sku}]` — use slugs when needed (rarely; `queryProducts` returns them already).
24
- - **Design tokens** — read the design tokens (the DESIGN.md vocabulary) from `.wix/design-tokens.css` (on disk) for the published color/spacing/typography vocabulary; compose Tailwind utilities derived from those tokens (`class="py-24 flex flex-col gap-4 font-display"`) at the call site rather than inventing semantic classes for layout/spacing/typography. Retained global semantic classes are limited to compound patterns (`offer-callout`, `cart-summary`), interactive primitives (`btn-primary`, `product-card`), and JS targets — see `references/shared/STYLING.md`.
25
- - **Designer visual spec** — the layout, contract classes, and decorative-slot conventions for `products/index.astro`, `products/[slug].astro`, `ProductCard.astro` (from `references/astro/designer/INSTRUCTIONS.md` → `store-pages`), applied in the same pass as the live queries.
26
-
27
- ## Critical rules (all must be honored)
28
-
29
- 1. **Use `productsV3`, not `products`** — V1 silently returns 0 on V3 catalogs.
30
- 2. **Product detail MUST use `getProductBySlug()`**, not `queryProducts()`. `queryProducts` omits variant data (`options`, `variantsInfo`), making add-to-cart silently fail.
31
- 3. **Product detail MUST export `wixMetadata`** — required for Wix sitemap, SEO editor, and dashboard deep links. Without it, the sitemap has zero product entries.
32
- 4. **Mount `SeoTags` on the detail page** — pipe `product.seoData.tags` through `Layout`'s `head` slot so merchant SEO edits in the Wix dashboard reach the live site. `seoData` is returned by default — no `fields` flag needed.
33
- 5. **Mount `ProductPurchase` with `client:load` and a single `product` prop, plus the back-in-stock probe + price props.** `<ProductPurchase client:load product={product} inventoryByVariant={inventoryByVariant} backInStockEnabled={backInStockEnabled} priceAmount={priceAmount} />`. The component destructures internally; passing flat props (`productId={product._id}`, `options={product.options}`, …) silently renders nothing because the new contract expects `product`. The `backInStockEnabled` boolean comes from `await getBackInStockEnabled()` (template imports it from `../../utils/back-in-stock`); `priceAmount` is the numeric price already computed in the frontmatter. See `BACK_IN_STOCK.md` for why both are needed.
34
- 6. **SSR only — do NOT add `export const prerender = true` or `getStaticPaths()`.** The productsV3 SDK depends on request-context auth (tenant resolution, site headers). At prerender time there is no request, and `.queryProducts().limit()` short-circuits to `"is not a function"`. Keep `[slug].astro` server-rendered with `Astro.params.slug`.
35
- 7. **No HTML comments in `.astro` frontmatter.** Build fails with "Legacy HTML single-line comments are not allowed".
36
- 8. **Default to tokens-as-utilities for layout/spacing/typography.** When you need a section padding, a flex column, a typographic treatment — write Tailwind utilities derived from `@theme` tokens (`<section class="py-24 flex flex-col gap-4">`, `<h1 class="font-display text-4xl">`). Do NOT invent semantic classes like `.featured-section`, `.page-header`, `.products-header-image` — Tailwind v4 silently drops undeclared classes. Use a global semantic class only when one is published in designer `INSTRUCTIONS.md`'s always-required list (`product-card`, `product-card-ribbon`, `offer-callout` family). For one-off page decoration, write a co-located `<style>` block at the bottom of the same `.astro` file using `var(--color-foo)` token references.
37
- 9. **Preserve designer classes.** When the designer used a published global semantic class on existing markup, keep it; don't rename. Add Tailwind utilities alongside if you need additional layout adjustment.
38
-
39
- ## Wix Site Structure — `wixMetadata` + `@wix/astro-pages`
40
-
41
- `@wix/astro-pages` is already wired into the blank scaffold's `astro.config.mjs` as `wixPages()`. It injects a `/_wix/pages.json` endpoint enumerating every page and reading each page's `wixMetadata` export. Wix platform services use this JSON to:
42
-
43
- - Generate server-side sitemap entries for dynamic product URLs (via `@wix/auto_sdk_seo_seo-sitemap-entries`)
44
- - Power the dashboard SEO editor ("Edit SEO for Product pages")
45
- - Resolve deep links from dashboard / email / analytics surfaces back to the right headless URL
46
-
47
- > **Two different Stores appDefIds — do not confuse:**
48
- > - `215238eb-22a5-4c36-9e7b-e7c08025e04e` — for `catalogReference.appId` in cart operations (same value used for app install in Phase 1).
49
- > - `1380b703-ce81-ff05-f115-39571d94dfcd` — for **`wixMetadata.appDefId`** on Stores sub-pages (product, category).
50
- >
51
- > Both are correct. They identify different entities.
52
-
53
- ## Template files
54
-
55
- This scope uses **template files** instead of inline code. For each file below:
56
-
57
- 1. Read the template from `<Agent location>/templates/<path>`
58
- 2. Write it to the project at the target path
59
- 3. Adapt class names only if the styling contract maps them differently than the defaults
60
-
61
- Do NOT modify logic, imports, SDK calls, `wixMetadata` export, or prop-passing. The templates encode non-negotiable Wix platform integrations (sitemap registration, inventoryItemsV3 OOS truth, SSR-only constraint, analytics payloads).
62
-
63
- ## Implementation
64
-
65
- > Every Wix SDK `await` in the templates is already wrapped in try/catch — keep those guards when adapting. See `references/shared/IMPLEMENTER.md` § "SSR error guards" for the underlying rule and rationale.
66
-
67
- ### 1. `src/pages/products/index.astro` — product listing
68
-
69
- Use template `templates/products/index.astro`.
70
-
71
- Applies the designer's page structure (class names, layout) and binds a guarded, **cursor-paginated** `productsV3.queryProducts({ fields: ["CURRENCY"] }).limit(24).skipTo(cursor).find()` (cursor read from `?cursor=` on the URL; Prev/Next anchors built from `result.cursors.next` / `.prev`). Mounts the shared `<CategoryRail/>` (written by `pages-categories`) above the grid, passing `activeSlug={null}` and the prev/next hrefs. Emits the `AddProductImpression` analytics event from a client-side script that reads a JSON payload serialized at SSR.
72
-
73
- > **Imports you must NOT write.** `<CategoryRail/>` (`../../components/CategoryRail.astro`) is written by the `pages-categories` scope your merged agent runs *before* this one; `listStoreCategories` (`../../utils/categories`) is pre-copied by the orchestrator. Both are on disk by the time you mount them. If either fails to resolve, return `status: "partial"` with `errors: [{ code: "MISSING_PAGES_CATEGORIES_OUTPUT", path: "<missing path>" }]` — that means your agent wrote `pages-products` before `pages-categories`, or the pre-copy was skipped.
74
-
75
- > **Page size 24** — multiple of the 2/3/4-column grid, well under Wix's per-request cap of 100. Do not change without updating `CATEGORY_PAGES.md` to match.
76
-
77
- > **No client-side filter.** Do not ship every product and hide non-matching cards via JS — it doesn't scale and breaks SEO. Do not add `data-category-ids` on `<ProductCard>` or any DOM-hide script. Filtering is done by navigating to `/category/<slug>` (a real route), and `<ClientRouter />` from the designer's Layout handles the swap.
78
-
79
- > **Why the double-script pattern:** Listing page is server-rendered but `AddProductImpression` must fire in the browser. The server-computed payload is serialized into an inert JSON `<script>` (`is:inline`) and read by a separate processed `<script>` (bundled by Astro — has ES `import`). `define:vars` + inline-script combinations cannot do ES imports.
80
-
81
- > **Gift-card mirror filter (do not remove).** The template applies `productList = productList.filter(p => p.ribbon?.name !== "Gift Card")` after building the result list. When the dashboard's Wix Gift Card app is enabled, it auto-creates 5 mirror Stores products (one per denomination, `productType: "DIGITAL"`, ribbon name `"Gift Card"`). Buying a mirror yields a dud DIGITAL line item that does NOT trigger gift-card issuance — the customer-facing surface for gift cards is `/gift-cards` (gift-cards pack), not `/products`. The filter holds whether or not the gift-cards pack is loaded for this site, so a future site that drops gift-cards but still has the dashboard app stays clean.
82
-
83
- ### 2. `src/components/ProductCard.astro` — reusable card
84
-
85
- Use template `templates/ProductCard.astro`.
86
-
87
- The template:
88
- - Accepts a single `{ product }` prop — the full Wix product object from `productsV3`
89
- - Resolves product images via `resolveWixImageUrl` (imported from the seeded shared util at `../utils/wix-image`)
90
- - Applies `product-card` contract class
91
- - Includes delegated click analytics (`ClickProduct` event via data attributes)
92
-
93
- Class from contract: `productCard` → `"product-card"`. If the designer already added the class, don't duplicate.
94
-
95
- ### 3. `src/pages/products/[slug].astro` — product detail
96
-
97
- Use template `templates/products/[slug].astro`.
98
-
99
- The template:
100
- - Exports `wixMetadata` with the Stores sub-page appDefId (`1380b703-…`) and `STORES.PRODUCT.SLUG` token for platform expansion
101
- - Uses `getProductBySlug()` (NOT `queryProducts()` — it omits variant data)
102
- - Queries `inventoryItemsV3.queryInventoryItems({ filter: { productId } })` and builds a `variantId → { quantity, trackQuantity, preorderEnabled }` map. This is the AUTHORITATIVE OOS signal; `variantsInfo[].inventoryStatus.inStock` is a stale cached flag.
103
- - Pipes `product.seoData.tags` through Layout's `head` slot via `<SeoTags slot="head" tags={seoTags} />` (rendered only when any tag is visible)
104
- - Calls `await getBackInStockEnabled()` from `../../utils/back-in-stock` to learn whether the dashboard's "Start Collecting Requests" toggle is on for Wix Stores; passes the boolean and `priceAmount` to `<ProductPurchase>`. The back-in-stock subscribe form renders inside ProductPurchase's three OOS branches when the prop is true. See `BACK_IN_STOCK.md` for the app-id discrepancy and the bare-fields rule.
105
- - Mounts `<ProductPurchase client:load product={product} inventoryByVariant={inventoryByVariant} backInStockEnabled={backInStockEnabled} priceAmount={priceAmount} />` with the canonical `{ product }` contract
106
- - Wraps both SDK awaits in try/catch so an SDK error produces a 404 redirect (product fetch) or an empty inventory map (inventory fetch), never a torn page (the back-in-stock probe is internally wrapped — it returns `false` on any failure, so it doesn't need an outer try/catch)
107
-
108
- **Critical details on `wixMetadata`:**
109
-
110
- - **Required for Wix platform indexing.** Without it, the product detail route is invisible to Wix's sitemap generator, SEO editor, and deep-link resolver.
111
- - **`appDefId`: `1380b703-ce81-ff05-f115-39571d94dfcd`** is the Stores page-registration defId — do NOT confuse with the Stores install/catalog defId (`215238eb-...`) used in Phase 1 and `catalogReference.appId`.
112
- - **`pageIdentifier`: `"wix.stores.sub_pages.product"`** is the canonical Wix identifier — constant.
113
- - **`identifiers.slug`**: maps the Astro route param to Wix's identifier token. Route is `[slug].astro`, so key is `slug`. Value `"STORES.PRODUCT.SLUG"` tells Wix to expand with each product's slug.
114
-
115
- **Layout `head` slot** — the `Layout.astro` written by the Design System phase must accept a `head` slot and a `hasSeoTags` prop. When `hasSeoTags` is true, the Layout omits its default `<title>`/`<meta description>` and instead renders the `head` slot contents into `<head>`. This lets `SeoTags` entirely replace the default metadata. If the Layout signature doesn't match, the Design System brief is missing it — flag this in the return's `errors` array and continue with a fallback (non-merchant-editable) title.
116
-
117
- ## Live offers (discount-rule indicators)
118
-
119
- The promotion ribbon on each product card is **owned by `ProductCard.astro` itself** — the component imports `fetchLiveOffers` + `offersForProduct` from `src/utils/discounts.ts` (shipped by the ecom `components` scope) and renders its own ribbon. Pages that mount `ProductCard` do NOT pass an `offers` prop and do NOT fetch offers themselves. This concentrates the wiring in one place — page-level wiring forced every page that renders ProductCard to remember it, and category pages would silently ship without ribbons.
120
-
121
- `fetchLiveOffers` is memoized per request via `auth.elevate`'s caching, so rendering N ProductCards in one page does NOT fan out N discount-rule queries.
122
-
123
- **Listing (`products/index.astro`)** — just `<ProductCard product={product} index={idx} />`. No offers wiring required.
124
-
125
- **Detail (`products/[slug].astro`)** — the detail page renders a richer offer callout above `<ProductPurchase>`. That callout still belongs to this scope (it's not part of the card). After the product is loaded:
126
-
127
- ```ts
128
- import { fetchLiveOffers, offersForProduct } from "../../utils/discounts";
129
- const offers = await fetchLiveOffers();
130
- const productOffers = offersForProduct(offers, product._id);
131
- ```
132
-
133
- ```astro
134
- {productOffers.length > 0 && (
135
- <div class="offer-callout">
136
- {productOffers.map((o) => (
137
- <div class="offer-callout-item">
138
- <span class="offer-callout-badge">Offer</span>
139
- <div>
140
- <p class="offer-callout-name">{o.name}</p>
141
- {o.offer && o.offer !== o.name && (
142
- <p class="offer-callout-detail">{o.offer}</p>
143
- )}
144
- </div>
145
- </div>
146
- ))}
147
- <p class="offer-callout-foot">Applied automatically at checkout.</p>
148
- </div>
149
- )}
150
-
151
- <ProductPurchase client:load product={product} inventoryByVariant={inventoryByVariant} />
152
- ```
153
-
154
- The `.offer-callout*` classes are owned by `src/styles/components-stores.css` (written by the stores Phase 3 components agent), NOT by the designer. Use `{o.offer}` for the body text — that's the dashboard-authored offer string (e.g. `"Buy 1 item\nAll products\n\nGet 1 item for free"`) which Wix formats with `\n` line breaks; the CSS includes `white-space: pre-line` so those render as line breaks.
155
-
156
- **Do NOT** hit `discountRules.queryDiscountRules` directly from this scope — always go through `fetchLiveOffers()`. The helper wraps the call with `auth.elevate()` (the endpoint requires `ECOM.DISCOUNT_RULES_READ`, visitor clients return nothing silently) and normalizes the scope-id field (`_id` vs `id`) which trips up naive matching.
157
-
158
- When the site has no active rules (first deploys, or the user hasn't created any in the dashboard yet), `offers` comes back as `[]`, `offersForProduct(...)` returns `[]`, the ribbon and callout both render nothing — no code path to guard for.
159
-
160
- ## Analytics fired from this scope
161
-
162
- | Event | Fires from | When | Payload |
163
- |-------|------------|------|---------|
164
- | `AddProductImpression` | `products/index.astro` | Listing page load | `{ contents: [{id, name, price, currency, position}], origin: "Product Listing" }` |
165
- | `ClickProduct` | `ProductCard.astro` | Delegated click on any card | `{ id, name, price, currency, origin: "Product Listing" }` |
166
- | `ViewContent` | `products/[slug].astro` | Detail page load | `{ id, name, price, currency, origin: "Product Page" }` |
167
-
168
- `AddToCart` fires from `AddToCartButton.tsx` (written by `components`) — not this scope.
169
-
170
- ## Return format
171
-
172
- ```json
173
- {
174
- "status": "complete",
175
- "phase": "stores-pages-products",
176
- "scope": "product-pages",
177
- "summary": "Wired product listing + detail + ProductCard to productsV3; wixMetadata + SeoTags mounted",
178
- "data": {
179
- "pagesWired": 2,
180
- "wixMetadataExported": true,
181
- "seoTagsMounted": true,
182
- "useGetProductBySlug": true,
183
- "analyticsEvents": ["AddProductImpression", "ClickProduct", "ViewContent"]
184
- },
185
- "files": [
186
- "src/pages/products/index.astro",
187
- "src/pages/products/[slug].astro",
188
- "src/components/ProductCard.astro"
189
- ],
190
- "errors": []
191
- }
192
- ```
193
-
194
- If any of `wixMetadataExported`, `seoTagsMounted`, `useGetProductBySlug` ends up `false`, set `status: "partial"` and populate `errors` with the specific issue. These three are non-negotiable for a merchant-grade site.
195
-
196
- ## Anti-patterns
197
-
198
- | WRONG | CORRECT |
199
- |-------|---------|
200
- | `import { products }` from `@wix/stores` | `productsV3` |
201
- | Use `queryProducts()` on detail page | `getProductBySlug()` — `queryProducts` omits variant data |
202
- | `export const prerender = true` + `getStaticPaths()` on `[slug].astro` | SSR only — productsV3 needs request-context auth; prerender short-circuits it |
203
- | Pass flat props to `<ProductPurchase>` (`productId`, `options`, `variantsInfo`, …) | Pass the whole product: `<ProductPurchase client:load product={product} inventoryByVariant={inventoryByVariant} />` |
204
- | Hardcode `<title>` from `product.name` | Pipe `product.seoData.tags` through `SeoTags` slot, fall back to `product.name` only when tags are empty/disabled |
205
- | Omit `wixMetadata` export | Required — platform indexing breaks silently without it |
206
- | Add `fields: ["SEO_DATA"]` | `seoData` is returned by default — no such enum value exists |
207
- | Write `src/utils/wix-image.ts` inline | Import `resolveWixImageUrl` from `../utils/wix-image` — shared util already exposes it |
208
- | `ls src/` to find designer output | Parent prompt lists every existing `src/` file — read directly |
209
- | Rename designer class names | Keep them; use contract classes when ADDING new markup |
210
- | HTML `<!-- comment -->` in `.astro` frontmatter | `//` or `/* */` — frontmatter is TypeScript |
211
- | Mount React island without `client:load` | Options + cart state needs hydration |
212
- | Pass `"INVENTORY"` in the `fields` array | No such enum value exists for `productsV3`. Valid values: `URL`, `CURRENCY`, `INFO_SECTION`, `MERCHANT_DATA`, `PLAIN_DESCRIPTION`, `INFO_SECTION_PLAIN_DESCRIPTION`, `SUBSCRIPTION_PRICES_INFO`, `BREADCRUMBS_INFO`, `WEIGHT_MEASUREMENT_UNIT_INFO`, `VARIANT_OPTION_CHOICE_NAMES`, `MEDIA_ITEMS_INFO`, `DESCRIPTION`, `DIRECT_CATEGORIES_INFO`, `ALL_CATEGORIES_INFO`, `INFO_SECTION_DESCRIPTION`, `THUMBNAIL`, `PRODUCT_CHOICES_MEDIA_REFERENCES`. Passing an invalid value makes the query throw. |
213
- | Trust `variantsInfo[].inventoryStatus.inStock` as the OOS gate | It's a stale cached flag — a variant with real quantity 0 can still report `inStock: true`. Query `inventoryItemsV3.queryInventoryItems({ filter: { productId } })` at SSR and pass a `variantId → { quantity, trackQuantity, preorderEnabled }` map into `ProductPurchase`. The template already does this. |
214
- | Skip the `backInStockEnabled` prop on `<ProductPurchase>` | Always pass it (template already imports `getBackInStockEnabled`). When the prop is missing, the OOS subscribe form never renders even if the merchant has enabled collecting requests. |
215
- | Pass the formatted price string (`"$695"`) as `priceAmount` | Pass the numeric `priceAmount` already computed in frontmatter. The Wix back-in-stock service rejects formatted prices with `400 DECIMAL_GTE`. |
@@ -1,165 +0,0 @@
1
- # Phase 3 Components — Stores (TSX/Astro)
2
-
3
- This is the **components** portion of the stores **merged build agent** (the build wave — `BUILD-astro.md` § "Step 4.5"). Your agent writes these islands **first**, then the stores pages (`pages-categories`, `pages-products`) that mount them — so the islands are on disk before the page code references them. The code here depends on the **design tokens** (read from `.wix/design-tokens.css` on disk) but NOT on page markup.
4
-
5
- > **CSS is pre-copied, not authored.** `src/styles/components-stores.css` ships from the skill template, copied by the orchestrator in the build-wave pre-batch (see `./COMPONENTS_CSS.md`). This scope does NOT write the CSS file. Reference its contract class names from the design tokens here; the pre-copied stylesheet defines the rules.
6
-
7
- ## Scope
8
-
9
- Files this agent OWNS (creates fresh, no designer output to read):
10
-
11
- - `src/components/SeoTags.astro` — Renders `product.seoData.tags` into `<head>`
12
- - `src/components/AddToCartButton.tsx` — React island; optimistic add-to-cart
13
- - `src/components/ProductPurchase.tsx` — React island; option selectors + variant resolution + wraps AddToCartButton
14
- - `src/components/BackInStockForm.tsx` — React island; back-in-stock subscription form
15
-
16
- Files this agent MUST NOT touch:
17
- - `src/styles/components-stores.css` — owned by the **`components-css`** sibling scope (see `./COMPONENTS_CSS.md`). Reference its class names; do not write the file.
18
- - `src/utils/wix-image.ts` — **shared utility shipped by the build skill.** Import `resolveWixImageUrl` from `../utils/wix-image`; do NOT write your own copy (would shadow the shared util and drop other verticals' callers). The canonical source lives at `<SKILL_ROOT>/shared-utilities/wix-image.ts`; it's copied into projects by `seed-utilities.sh` during Setup.
19
- - `src/components/CartView.tsx`, `src/components/CartBadge.tsx`, `src/utils/analytics.ts`, `src/styles/components-ecom.css` — owned by ecom
20
- - `src/utils/back-in-stock.ts` — **pre-copied by the orchestrator** in the build-wave pre-batch (BUILD-astro.md § "Step 4.5"), same as `categories.ts`. Import `getBackInStockEnabled`/the app-id constants from `../utils/back-in-stock`; never `Write` it (see `./BACK_IN_STOCK.md`).
21
- - Any `.astro` page — written by your agent's `pages-*` scopes (after the islands) or by another vertical
22
- - `src/styles/global.css` — owned by designer foundation
23
- - `src/layouts/Layout.astro` — owned by designer foundation (including the `components-stores.css` import line)
24
- - Any designed component (`ProductCard.astro`, `Navigation.astro`, etc.) — owned by designers
25
-
26
- ## Coordination: design tokens
27
-
28
- Read the design tokens from `.wix/design-tokens.css` (on disk, gate-verified present before the wave). The parent skill serializes your launch behind the designer foundation specifically so this file is already written when you start.
29
-
30
- Reference the ACTUAL class names from the contract in React components (e.g. `className="add-to-cart-btn"`, not `className="addToCartButton"` or an invented name). See `references/shared/IMPLEMENTER.md` § "Contract class-name adaptation" for the full rule.
31
-
32
- ## Critical rules
33
-
34
- 1. **Import `productsV3`, never `products`** — V1 silently returns 0 results on V3 catalogs (used in `ProductPurchase.tsx` type definitions).
35
- 2. **Always include `variantId` in `catalogReference.options`** — even single-variant products have one. Without it, `addToCurrentCart` returns 200 OK but silently adds nothing.
36
- 3. **No HTML comments in `.astro` frontmatter** — frontmatter is TypeScript; use `//` or `/* */`. Build-fails with "Legacy HTML single-line comments are not allowed".
37
- 4. **Use brand-token Tailwind utilities on React islands** (e.g., `bg-bark`, `text-cream`), never default Tailwind colors (`bg-green-50`, `text-red-600`). See IMPLEMENTER.md § "Contract class-name adaptation" for the class-name rule itself.
38
- 5. **Analytics is fire-and-forget** — see `references/shared/IMPLEMENTER.md` § "Fire-and-forget analytics".
39
-
40
- ## Template files
41
-
42
- This scope uses **template files** instead of inline code. For each file below:
43
-
44
- 1. Read the template from `<Agent location>/templates/<filename>`
45
- 2. Write it to the project at the target path
46
- 3. Adapt CSS class names if the design tokens maps them differently than the defaults
47
-
48
- Do NOT modify logic, imports, or component structure.
49
-
50
- ## Implementation
51
-
52
- ### 1. `src/styles/components-stores.css` — not owned by this scope
53
-
54
- > Owned by the **`components-css`** sibling scope. See `./COMPONENTS_CSS.md`. Reference the contract class names from the design tokens in your TSX/Astro files; the CSS sibling defines the rules.
55
-
56
- ### 2. `src/utils/analytics.ts` — not owned by this scope
57
-
58
- > Import from it (`import { trackEvent } from "../utils/analytics"`) but do not write it. Shipped by the build skill as a seeded shared utility.
59
-
60
- ### 3. `src/utils/wix-image.ts` — not owned by this scope
61
-
62
- > Import `resolveWixImageUrl` from `../utils/wix-image` but do not write it. Shipped by the build skill as a seeded shared utility that already exposes `resolveWixImageUrl(image, width?, height?)`. Writing your own copy shadows and breaks callers in other verticals (blog, cms).
63
-
64
- ### 4. `src/components/SeoTags.astro`
65
-
66
- Use template `templates/SeoTags.astro`.
67
-
68
- Renders merchant-edited SEO from the Wix dashboard into `<head>`. Mounted on the product detail page (by `product-pages` scope) via `Layout`'s `head` slot.
69
-
70
- `product.seoData` is returned by default from `getProductBySlug` — no `fields` flag needed.
71
-
72
- ### 5. `src/components/AddToCartButton.tsx`
73
-
74
- Use template `templates/AddToCartButton.tsx`.
75
-
76
- Optimistic add-to-cart button. Shows "Added ✓" immediately; fires API in background; reverts on failure. Dispatches `cart-updated` events so CartBadge can update badge count instantly.
77
-
78
- Uses `@wix/ecom` `currentCart.addToCurrentCart`. `WIX_STORES_APP_ID` is the Stores appDefId constant (`215238eb-22a5-4c36-9e7b-e7c08025e04e`) used in `catalogReference.appId`.
79
-
80
- **Modifier support** — accepts pre-flattened `modifierChoices` and `customTextFields` from ProductPurchase and merges them into `catalogReference.options` per the Wix Stores Catalog V3 contract. ProductPurchase owns the flattening; this component just passes them through.
81
-
82
- Class from contract: `addToCartButton` → `"add-to-cart-btn"`.
83
-
84
- ### 6. `src/components/CartBadge.tsx` — not owned by this scope
85
-
86
- > Do not write this file. AddToCartButton dispatches `cart-updated` CustomEvents that CartBadge (owned by ecom) listens for.
87
-
88
- ### 7. `src/components/ProductPurchase.tsx`
89
-
90
- Use template `templates/ProductPurchase.tsx`.
91
-
92
- Handles variant selection, quantity selector, stock awareness, and wraps `AddToCartButton`. Mounted on product detail pages (by `product-pages` scope) as:
93
-
94
- ```tsx
95
- <ProductPurchase client:load product={product} inventoryByVariant={inventoryByVariant} />
96
- ```
97
-
98
- **Prop contract — single `product` object.** The template accepts the full productsV3 product and destructures internally. This mirrors `ProductCard.astro`'s `{ product }` contract so both stores components take the same shape (prevents a shape mismatch where a fallback-written `[slug].astro` passes `product` as a whole while the component expects flat props).
99
-
100
- Key behaviors:
101
- - `hasMeaningfulOptions` — a product has meaningful options only when at least one option has >1 choice. Dummy single-choice options (e.g., "Type: Standard") are treated as no options.
102
- - Out of stock → renders just the message, no button.
103
- - No meaningful options → renders quantity + AddToCartButton with default variant ID.
104
- - Has options → renders pill selectors + quantity + AddToCartButton with resolved variant ID.
105
- - **Modifiers** — customization choices that do NOT create separate variants. Pills for `modifierRenderType === "TEXT_CHOICES"` / `"SWATCH_CHOICES"`, textarea for `"FREE_TEXT"`. Mandatory modifiers must have a value before add-to-cart is enabled. Selections flatten into `{ options: { [modifier.key]: choice.key }, customTextFields: { [modifier.freeTextSettings.key]: text } }` before being handed to AddToCartButton.
106
- - **OOS gating** — source of truth is `inventoryByVariant` (from `inventoryItemsV3`). `variantsInfo[].inventoryStatus.inStock` is a stale cached flag and is only used when the live map is empty. See PRODUCT_PAGES.md for the detail-page query that populates `inventoryByVariant`.
107
-
108
- Classes from contract (stores pack):
109
-
110
- - **Global** (CSS in foundation's `global.css`):
111
- - `productPurchase` → `"product-purchase"` (outer wrapper — use on the root `<div>`)
112
- - **Scoped** (CSS in `components-stores.css`, owned by the `components-css` sibling scope — see `./COMPONENTS_CSS.md`):
113
- - `optionGroup` → `"option-group"`
114
- - `optionLabel` → `"option-label"`
115
- - `optionChoices` → `"option-choices"`
116
- - `optionPill` → `"option-pill"` (state modifier `.selected` for active choice)
117
- - `quantitySelector` → `"quantity-selector"`
118
- - `quantityBtn` → `"quantity-btn"`
119
- - `quantityValue` → `"quantity-value"`
120
- - `stockStatus` → `"stock-status"`
121
-
122
- **Do not invent new class names** — if a new interactive control needs a class, add it to the pack's `contractKeys.scoped` first.
123
-
124
- ### 8. `src/components/CartView.tsx` — not owned by this scope
125
-
126
- > Do not write this file.
127
-
128
- ## Return format
129
-
130
- ```json
131
- {
132
- "status": "complete",
133
- "phase": "stores-components",
134
- "scope": "components",
135
- "summary": "Wrote React islands and Astro components from templates (CSS handled by components-css sibling)",
136
- "data": {
137
- "islands": ["ProductPurchase.tsx", "AddToCartButton.tsx", "BackInStockForm.tsx"],
138
- "astroComponents": ["SeoTags.astro"],
139
- "globalContractClassesReferenced": ["addToCartButton", "productPurchase"],
140
- "scopedContractClassesReferenced": ["optionGroup", "optionLabel", "optionChoices", "optionPill", "stockStatus", "quantitySelector", "quantityBtn", "quantityValue"]
141
- },
142
- "files": [
143
- "src/components/SeoTags.astro",
144
- "src/components/AddToCartButton.tsx",
145
- "src/components/ProductPurchase.tsx",
146
- "src/components/BackInStockForm.tsx"
147
- ],
148
- "errors": []
149
- }
150
- ```
151
-
152
- ## Anti-patterns
153
-
154
- | WRONG | CORRECT |
155
- |-------|---------|
156
- | Read designer `.astro` files | Not needed — this scope doesn't touch pages |
157
- | Import `products` from `@wix/stores` | Use `productsV3` |
158
- | Write `src/utils/wix-image.ts` | Import from it — shared util already exposes `resolveWixImageUrl` |
159
- | Hardcode `className="btn-primary"` | Use contract class `className="add-to-cart-btn"` |
160
- | Default Tailwind color utilities on React islands (`bg-green-50`, `bg-blue-500`) | Brand `@theme` utilities (`bg-bark`, `text-cream`) or contract class names |
161
- | `<!--` HTML comments in `.astro` frontmatter | `//` or `/* */` — frontmatter is TypeScript |
162
- | Omit `WIX_STORES_APP_ID` constant | Hardcoded `215238eb-22a5-4c36-9e7b-e7c08025e04e` in AddToCartButton for `catalogReference.appId` |
163
- | Introspect `node_modules/@wix/*` | All symbols are documented here; if missing, use docs-search REST (see `DOCS_SEARCH.md`) |
164
- | Write `CartView.tsx`, `CartBadge.tsx`, or `analytics.ts` | Not owned by this scope — do not write |
165
- | Pass flat props to `ProductPurchase` (`productId`, `options`, `variantsInfo`, …) | Pass the whole product: `<ProductPurchase product={product} inventoryByVariant={inventoryByVariant} />` |