@wix/agent-skills 1.16.3 → 1.18.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 (283) hide show
  1. package/package.json +1 -1
  2. package/skills/wix-app/SKILL.md +115 -12
  3. package/skills/wix-app/references/APP_MARKET_REVIEW.md +1 -1
  4. package/skills/wix-app/references/BACKEND_API.md +18 -0
  5. package/skills/wix-app/references/CUSTOM_ELEMENT_WIDGET.md +6 -0
  6. package/skills/wix-app/references/DASHBOARD_MODAL.md +10 -2
  7. package/skills/wix-app/references/DASHBOARD_PAGE.md +32 -70
  8. package/skills/wix-app/references/EDITOR_REACT_COMPONENT.md +145 -127
  9. package/skills/wix-app/references/SITE_PLUGIN.md +14 -2
  10. package/skills/wix-app/references/WIX_PATTERNS_DOCS.md +74 -68
  11. package/skills/wix-app/references/backend-event/COMMON-EVENTS.md +2 -2
  12. package/skills/wix-app/references/dashboard-page/COLLECTION_TOOLKIT.md +79 -0
  13. package/skills/wix-app/references/dashboard-page/ENTITY_PAGE_TOOLKIT.md +73 -0
  14. package/skills/wix-app/references/dashboard-page/PATTERNS_BUNDLE_READING.md +52 -0
  15. package/skills/wix-app/references/dashboard-page/UX_SUCCESS_MODEL.md +184 -0
  16. package/skills/wix-app/references/editor-react-component/ACCESSIBILITY.md +182 -99
  17. package/skills/wix-app/references/editor-react-component/ANIMATED-COMPONENTS.md +94 -49
  18. package/skills/wix-app/references/editor-react-component/BRANDED-COMPONENTS.md +16 -6
  19. package/skills/wix-app/references/editor-react-component/BROWSER-SUPPORT.md +56 -0
  20. package/skills/wix-app/references/editor-react-component/COMPONENT-CONTRACT.md +275 -0
  21. package/skills/wix-app/references/editor-react-component/COMPONENT-PREVIEW.md +35 -40
  22. package/skills/wix-app/references/editor-react-component/CSS-GUIDELINES.md +167 -445
  23. package/skills/wix-app/references/editor-react-component/DESIGN-STATES.md +56 -29
  24. package/skills/wix-app/references/editor-react-component/DIRECTIONALITY.md +53 -158
  25. package/skills/wix-app/references/editor-react-component/EDITOR-EXTENSION-CONFIGURATION.md +78 -0
  26. package/skills/wix-app/references/editor-react-component/FUNCTION-HANDLERS.md +42 -134
  27. package/skills/wix-app/references/editor-react-component/MANIFEST-ERRORS.md +11 -3
  28. package/skills/wix-app/references/editor-react-component/PARTS.md +46 -24
  29. package/skills/wix-app/references/editor-react-component/PROPS-VS-CSS.md +63 -179
  30. package/skills/wix-app/references/editor-react-component/REACT-GUIDELINES.md +79 -163
  31. package/skills/wix-app/references/editor-react-component/SITE-CONTEXT-HOOKS.md +36 -21
  32. package/skills/wix-app/references/editor-react-component/SSR.md +30 -99
  33. package/skills/wix-base44-connector/SKILL.md +156 -50
  34. package/skills/wix-base44-connector/references/CAPABILITY_MAP.md +78 -0
  35. package/skills/wix-base44-connector/scripts/utils.js +239 -45
  36. package/skills/wix-headless/entry/bootstrap.mjs +9 -2
  37. package/skills/wix-headless/entry/skill.md +1 -1
  38. package/skills/wix-headless/references/CAPABILITIES.md +9 -1
  39. package/skills/wix-headless/references/DESIGN.md +1 -0
  40. package/skills/wix-headless/references/DISCOVERY.md +2 -1
  41. package/skills/wix-headless/references/IMAGE_GENERATION.md +1 -0
  42. package/skills/wix-headless/references/SDK_HANDOFF.md +5 -2
  43. package/skills/wix-headless/references/SEED.md +2 -1
  44. package/skills/wix-headless/references/SETUP.md +1 -0
  45. package/skills/wix-headless/references/inline-recipes/how-to-code-a-blog.md +2 -2
  46. package/skills/wix-headless/references/inline-recipes/how-to-code-a-store.md +68 -31
  47. package/skills/wix-headless/references/inline-recipes/how-to-code-forms.md +26 -10
  48. package/skills/wix-headless/references/inline-recipes/how-to-code-members-astro.md +8 -8
  49. package/skills/wix-headless/references/inline-recipes/how-to-code-members-custom-login.md +1 -1
  50. package/skills/wix-headless/references/inline-recipes/how-to-code-members-non-astro.md +1 -1
  51. package/skills/wix-headless/references/inline-recipes/how-to-code-pricing-plans.md +10 -8
  52. package/skills/wix-headless/references/inline-recipes/how-to-code-rentals.md +254 -0
  53. package/skills/wix-headless/references/inline-recipes/how-to-code-restaurant-orders.md +27 -24
  54. package/skills/wix-headless/references/inline-recipes/setup-online-store.md +13 -0
  55. package/skills/wix-headless/references/inline-recipes/setup-rentals.md +254 -0
  56. package/skills/wix-headless/references/managed/AUTHENTICATION.md +5 -0
  57. package/skills/wix-headless/references/non-astro.md +1 -1
  58. package/skills/wix-headless-fast/SKILL.md +166 -0
  59. package/skills/wix-headless-fast/entry/skill.md +99 -0
  60. package/skills/wix-headless-fast/install/deploy.mjs +433 -0
  61. package/skills/wix-headless-fast/install/fast-path.mjs +141 -0
  62. package/skills/wix-headless-fast/references/blog/INSTRUCTIONS.md +137 -0
  63. package/skills/wix-headless-fast/references/blog/app/components/blog/BlogFeedView.tsx +137 -0
  64. package/skills/wix-headless-fast/references/blog/app/components/blog/PostView.tsx +113 -0
  65. package/skills/wix-headless-fast/references/blog/app/components/blog/RichContent.tsx +42 -0
  66. package/skills/wix-headless-fast/references/blog/app/hooks/blog/useBlogFeed.ts +123 -0
  67. package/skills/wix-headless-fast/references/blog/app/hooks/blog/usePost.ts +70 -0
  68. package/skills/wix-headless-fast/references/blog/app/wix/blog/posts.ts +99 -0
  69. package/skills/wix-headless-fast/references/blog/app/wix/blog/taxonomy.ts +76 -0
  70. package/skills/wix-headless-fast/references/blog/app/wix/blog/types.ts +62 -0
  71. package/skills/wix-headless-fast/references/blog/app-astro/layouts/SiteLayout.astro +40 -0
  72. package/skills/wix-headless-fast/references/blog/app-astro/pages/blog/[...slug].astro +99 -0
  73. package/skills/wix-headless-fast/references/blog/app-astro/pages/blog.astro +24 -0
  74. package/skills/wix-headless-fast/references/blog/lock/astro/package-lock.json +16156 -0
  75. package/skills/wix-headless-fast/references/blog/seed/SEED.md +72 -0
  76. package/skills/wix-headless-fast/references/blog/seed/seed-blog.mjs +287 -0
  77. package/skills/wix-headless-fast/references/bookings/INSTRUCTIONS.md +129 -0
  78. package/skills/wix-headless-fast/references/bookings/app/components/bookings/ServiceBookingView.tsx +143 -0
  79. package/skills/wix-headless-fast/references/bookings/app/components/bookings/ServicesView.tsx +119 -0
  80. package/skills/wix-headless-fast/references/bookings/app/hooks/bookings/useBookingFlow.ts +138 -0
  81. package/skills/wix-headless-fast/references/bookings/app/hooks/bookings/useServices.ts +54 -0
  82. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/booking.ts +206 -0
  83. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/services.ts +96 -0
  84. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/types.ts +70 -0
  85. package/skills/wix-headless-fast/references/bookings/app-astro/layouts/SiteLayout.astro +40 -0
  86. package/skills/wix-headless-fast/references/bookings/app-astro/pages/services/[slug].astro +76 -0
  87. package/skills/wix-headless-fast/references/bookings/app-astro/pages/services.astro +22 -0
  88. package/skills/wix-headless-fast/references/bookings/lock/astro/package-lock.json +11962 -0
  89. package/skills/wix-headless-fast/references/bookings/seed/SEED.md +61 -0
  90. package/skills/wix-headless-fast/references/bookings/seed/seed-bookings.mjs +302 -0
  91. package/skills/wix-headless-fast/references/cms/INSTRUCTIONS.md +179 -0
  92. package/skills/wix-headless-fast/references/cms/app/hooks/cms/useCollection.ts +83 -0
  93. package/skills/wix-headless-fast/references/cms/app/hooks/cms/useItem.ts +57 -0
  94. package/skills/wix-headless-fast/references/cms/app/wix/cms/items.ts +151 -0
  95. package/skills/wix-headless-fast/references/cms/app/wix/cms/types.ts +75 -0
  96. package/skills/wix-headless-fast/references/cms/app-astro/layouts/SiteLayout.astro +41 -0
  97. package/skills/wix-headless-fast/references/cms/lock/astro/package-lock.json +11262 -0
  98. package/skills/wix-headless-fast/references/cms/seed/SEED.md +103 -0
  99. package/skills/wix-headless-fast/references/cms/seed/seed-cms.mjs +324 -0
  100. package/skills/wix-headless-fast/references/events/INSTRUCTIONS.md +149 -0
  101. package/skills/wix-headless-fast/references/events/app/components/events/EventConfirmationView.tsx +66 -0
  102. package/skills/wix-headless-fast/references/events/app/components/events/EventRegistrationView.tsx +176 -0
  103. package/skills/wix-headless-fast/references/events/app/components/events/EventsView.tsx +118 -0
  104. package/skills/wix-headless-fast/references/events/app/hooks/events/useEventRegistration.ts +117 -0
  105. package/skills/wix-headless-fast/references/events/app/hooks/events/useEvents.ts +59 -0
  106. package/skills/wix-headless-fast/references/events/app/wix/events/events.ts +136 -0
  107. package/skills/wix-headless-fast/references/events/app/wix/events/registration.ts +128 -0
  108. package/skills/wix-headless-fast/references/events/app/wix/events/types.ts +61 -0
  109. package/skills/wix-headless-fast/references/events/app-astro/layouts/SiteLayout.astro +40 -0
  110. package/skills/wix-headless-fast/references/events/app-astro/pages/event-confirmation.astro +12 -0
  111. package/skills/wix-headless-fast/references/events/app-astro/pages/events/[slug].astro +80 -0
  112. package/skills/wix-headless-fast/references/events/app-astro/pages/events.astro +21 -0
  113. package/skills/wix-headless-fast/references/events/lock/astro/package-lock.json +11884 -0
  114. package/skills/wix-headless-fast/references/events/seed/SEED.md +86 -0
  115. package/skills/wix-headless-fast/references/events/seed/seed-events.mjs +276 -0
  116. package/skills/wix-headless-fast/references/forms/INSTRUCTIONS.md +150 -0
  117. package/skills/wix-headless-fast/references/forms/app/hooks/forms/useWixForm.ts +317 -0
  118. package/skills/wix-headless-fast/references/forms/app/wix/forms/forms.ts +269 -0
  119. package/skills/wix-headless-fast/references/forms/app/wix/forms/submissions.ts +231 -0
  120. package/skills/wix-headless-fast/references/forms/app/wix/forms/types.ts +135 -0
  121. package/skills/wix-headless-fast/references/forms/lock/astro/package-lock.json +10593 -0
  122. package/skills/wix-headless-fast/references/forms/seed/SEED.md +108 -0
  123. package/skills/wix-headless-fast/references/forms/seed/seed-forms.mjs +320 -0
  124. package/skills/wix-headless-fast/references/members/INSTRUCTIONS.md +63 -0
  125. package/skills/wix-headless-fast/references/members/app/components/members/AccountView.tsx +60 -0
  126. package/skills/wix-headless-fast/references/members/app/components/members/LoginForm.tsx +155 -0
  127. package/skills/wix-headless-fast/references/members/app/components/members/MemberMenu.tsx +78 -0
  128. package/skills/wix-headless-fast/references/members/app/components/members/RequireAuth.tsx +47 -0
  129. package/skills/wix-headless-fast/references/members/app/hooks/members/useMember.ts +66 -0
  130. package/skills/wix-headless-fast/references/members/app/wix/members/auth.ts +88 -0
  131. package/skills/wix-headless-fast/references/members/app/wix/members/client.ts +53 -0
  132. package/skills/wix-headless-fast/references/members/app/wix/members/member-store.ts +122 -0
  133. package/skills/wix-headless-fast/references/members/app/wix/members/members.ts +50 -0
  134. package/skills/wix-headless-fast/references/members/app/wix/members/types.ts +21 -0
  135. package/skills/wix-headless-fast/references/members/app-astro/layouts/SiteLayout.astro +42 -0
  136. package/skills/wix-headless-fast/references/members/app-astro/pages/account.astro +10 -0
  137. package/skills/wix-headless-fast/references/members/app-astro/pages/login.astro +11 -0
  138. package/skills/wix-headless-fast/references/members/lock/astro/package-lock.json +10329 -0
  139. package/skills/wix-headless-fast/references/members/seed/SEED.md +39 -0
  140. package/skills/wix-headless-fast/references/members/seed/seed-members.mjs +94 -0
  141. package/skills/wix-headless-fast/references/portfolio/INSTRUCTIONS.md +134 -0
  142. package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/CollectionProjectsView.tsx +110 -0
  143. package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/CollectionsView.tsx +90 -0
  144. package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/ProjectDetailView.tsx +115 -0
  145. package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useCollectionProjects.ts +59 -0
  146. package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useCollections.ts +39 -0
  147. package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useProjectDetail.ts +58 -0
  148. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/portfolio.ts +165 -0
  149. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/types.ts +55 -0
  150. package/skills/wix-headless-fast/references/portfolio/app-astro/layouts/SiteLayout.astro +40 -0
  151. package/skills/wix-headless-fast/references/portfolio/app-astro/pages/portfolio/[slug].astro +30 -0
  152. package/skills/wix-headless-fast/references/portfolio/app-astro/pages/portfolio.astro +21 -0
  153. package/skills/wix-headless-fast/references/portfolio/app-astro/pages/projects/[slug].astro +29 -0
  154. package/skills/wix-headless-fast/references/portfolio/lock/astro/package-lock.json +10197 -0
  155. package/skills/wix-headless-fast/references/portfolio/seed/SEED.md +78 -0
  156. package/skills/wix-headless-fast/references/portfolio/seed/seed-portfolio.mjs +258 -0
  157. package/skills/wix-headless-fast/references/pricing-plans/INSTRUCTIONS.md +133 -0
  158. package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/PlanDetailView.tsx +58 -0
  159. package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/PlansView.tsx +126 -0
  160. package/skills/wix-headless-fast/references/pricing-plans/app/hooks/pricing-plans/usePlanPurchase.ts +37 -0
  161. package/skills/wix-headless-fast/references/pricing-plans/app/hooks/pricing-plans/usePlans.ts +39 -0
  162. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plans.ts +75 -0
  163. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/purchase.ts +45 -0
  164. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/types.ts +30 -0
  165. package/skills/wix-headless-fast/references/pricing-plans/app-astro/layouts/SiteLayout.astro +41 -0
  166. package/skills/wix-headless-fast/references/pricing-plans/app-astro/pages/plans/[slug].astro +40 -0
  167. package/skills/wix-headless-fast/references/pricing-plans/app-astro/pages/plans.astro +21 -0
  168. package/skills/wix-headless-fast/references/pricing-plans/lock/astro/package-lock.json +11226 -0
  169. package/skills/wix-headless-fast/references/pricing-plans/seed/SEED.md +71 -0
  170. package/skills/wix-headless-fast/references/pricing-plans/seed/seed-pricing-plans.mjs +279 -0
  171. package/skills/wix-headless-fast/references/restaurants/INSTRUCTIONS.md +165 -0
  172. package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/MenuView.tsx +142 -0
  173. package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/OrderCartButton.tsx +26 -0
  174. package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/OrderCartDrawer.tsx +121 -0
  175. package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/ReservationView.tsx +155 -0
  176. package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useMenus.ts +55 -0
  177. package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useOrderCart.ts +43 -0
  178. package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useReservation.ts +177 -0
  179. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/menu.ts +165 -0
  180. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/order-store.ts +103 -0
  181. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/ordering.ts +254 -0
  182. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/reservations.ts +146 -0
  183. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/types.ts +168 -0
  184. package/skills/wix-headless-fast/references/restaurants/app-astro/layouts/SiteLayout.astro +47 -0
  185. package/skills/wix-headless-fast/references/restaurants/app-astro/pages/menu.astro +22 -0
  186. package/skills/wix-headless-fast/references/restaurants/app-astro/pages/reservations.astro +12 -0
  187. package/skills/wix-headless-fast/references/restaurants/lock/astro/package-lock.json +12560 -0
  188. package/skills/wix-headless-fast/references/restaurants/seed/SEED.md +81 -0
  189. package/skills/wix-headless-fast/references/restaurants/seed/seed-restaurants.mjs +479 -0
  190. package/skills/wix-headless-fast/references/shared/CONTENT.md +22 -0
  191. package/skills/wix-headless-fast/references/shared/CUSTOM_OPERATIONS.md +73 -0
  192. package/skills/wix-headless-fast/references/shared/DESIGN.md +26 -0
  193. package/skills/wix-headless-fast/references/shared/app/styles/global.css +52 -0
  194. package/skills/wix-headless-fast/references/shared/app/wix/config.ts +15 -0
  195. package/skills/wix-headless-fast/references/shared/app/wix/media.ts +27 -0
  196. package/skills/wix-headless-fast/references/shared/app/wix/money.ts +24 -0
  197. package/skills/wix-headless-fast/references/shared/app/wix/sdk.ts +76 -0
  198. package/skills/wix-headless-fast/references/shared/capabilities/media-upload/app/wix/media-upload/client.ts +46 -0
  199. package/skills/wix-headless-fast/references/shared/capabilities/media-upload/app-astro/pages/api/wix/media-upload.ts +46 -0
  200. package/skills/wix-headless-fast/references/shared/seed/images.mjs +145 -0
  201. package/skills/wix-headless-fast/references/storefront/INSTRUCTIONS.md +149 -0
  202. package/skills/wix-headless-fast/references/storefront/app/components/storefront/CartButton.tsx +26 -0
  203. package/skills/wix-headless-fast/references/storefront/app/components/storefront/CartDrawer.tsx +121 -0
  204. package/skills/wix-headless-fast/references/storefront/app/components/storefront/ProductCard.tsx +100 -0
  205. package/skills/wix-headless-fast/references/storefront/app/components/storefront/ProductDetailView.tsx +130 -0
  206. package/skills/wix-headless-fast/references/storefront/app/components/storefront/ProductGrid.tsx +48 -0
  207. package/skills/wix-headless-fast/references/storefront/app/components/storefront/ShopView.tsx +66 -0
  208. package/skills/wix-headless-fast/references/storefront/app/components/storefront/VariantPicker.tsx +103 -0
  209. package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useCart.ts +48 -0
  210. package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useProductDetail.ts +140 -0
  211. package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useShop.ts +80 -0
  212. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart-store.ts +101 -0
  213. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart.ts +221 -0
  214. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/catalog.ts +215 -0
  215. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/types.ts +109 -0
  216. package/skills/wix-headless-fast/references/storefront/app-astro/layouts/SiteLayout.astro +46 -0
  217. package/skills/wix-headless-fast/references/storefront/app-astro/pages/products/[slug].astro +56 -0
  218. package/skills/wix-headless-fast/references/storefront/app-astro/pages/shop.astro +23 -0
  219. package/skills/wix-headless-fast/references/storefront/lock/astro/package-lock.json +12247 -0
  220. package/skills/wix-headless-fast/references/storefront/seed/SEED.md +85 -0
  221. package/skills/wix-headless-fast/references/storefront/seed/seed-store.mjs +415 -0
  222. package/skills/wix-manage/SKILL.md +28 -2
  223. package/skills/wix-manage/references/bookings/booking-system-integration-gaps.md +20 -13
  224. package/skills/wix-manage/references/bookings/end-to-end-booking-flow.md +24 -11
  225. package/skills/wix-manage/references/cms/cms-ecommerce-catalog-integration.md +5 -5
  226. package/skills/wix-manage/references/google-ads/manage-campaign-success-guide.md +141 -0
  227. package/skills/wix-manage/references/google-business-profile/connect-google-business-profile.md +134 -0
  228. package/skills/wix-manage/references/google-business-profile/manage-google-business-profile-locations.md +182 -0
  229. package/skills/wix-manage/references/marketing/create-and-publish-social-post.md +3 -0
  230. package/skills/wix-manage/references/seo/manage-seo-tags.md +315 -0
  231. package/skills/wix-manage/references/seo/manage-url-redirects.md +250 -0
  232. package/skills/wix-manage/references/sites/query-sites.md +72 -161
  233. package/skills/wix-manage/references/stores/create-product-catalog-v3.md +21 -6
  234. package/skills/wix-manage/references/stores/update-product-with-options.md +83 -0
  235. package/skills/wix-replatform/resources/rp-mapper/wix-business-solutions-taxonomy.md +5 -6
  236. package/skills/wix-vibe-headless/SKILL.md +18 -4
  237. package/skills/wix-vibe-headless/install/deploy.cjs +12 -4
  238. package/skills/wix-vibe-headless/install/pin-agents-md.cjs +2 -1
  239. package/skills/wix-vibe-headless/platforms/base44-ecom-light-seed.md +16 -10
  240. package/skills/wix-vibe-headless/platforms/base44-ecom-light.md +13 -8
  241. package/skills/wix-vibe-headless/platforms/base44.md +27 -62
  242. package/skills/wix-vibe-headless/platforms/generic.md +6 -3
  243. package/skills/wix-vibe-headless/references/bookings/INSTRUCTIONS.md +45 -0
  244. package/skills/wix-vibe-headless/references/bookings/app/components/RentalDurationPicker.jsx +67 -0
  245. package/skills/wix-vibe-headless/references/bookings/app/hooks/useRentalDuration.js +128 -0
  246. package/skills/wix-vibe-headless/references/bookings/app/hooks/useServiceDetail.js +5 -3
  247. package/skills/wix-vibe-headless/references/bookings/app/rest/wix-bookings-checkout.js +9 -8
  248. package/skills/wix-vibe-headless/references/bookings/app/rest/wix-bookings-rentals.js +250 -0
  249. package/skills/wix-vibe-headless/references/bookings/app/rest/wix-bookings-services.js +12 -5
  250. package/skills/wix-vibe-headless/references/bookings/seed/SEED.md +41 -0
  251. package/skills/wix-vibe-headless/references/bookings/seed/seed-rentals.js +267 -0
  252. package/skills/wix-vibe-headless/references/cms/INSTRUCTIONS.md +6 -3
  253. package/skills/wix-vibe-headless/references/forms/INSTRUCTIONS.md +470 -0
  254. package/skills/wix-vibe-headless/references/forms/app/hooks/useWixForm.js +425 -0
  255. package/skills/wix-vibe-headless/references/forms/app/lib/wix-form-schema-utils.js +187 -0
  256. package/skills/wix-vibe-headless/references/forms/app/rest/wix-forms-submissions.js +238 -0
  257. package/skills/wix-vibe-headless/references/forms/app/rest/wix-forms.js +108 -0
  258. package/skills/wix-vibe-headless/references/forms/seed/SEED.md +1762 -0
  259. package/skills/wix-vibe-headless/references/rentals/INSTRUCTIONS.md +13 -0
  260. package/skills/wix-vibe-headless/references/restaurants/INSTRUCTIONS.md +4 -1
  261. package/skills/wix-vibe-headless/references/restaurants/app/components/OrderCartDrawer.jsx +23 -11
  262. package/skills/wix-vibe-headless/references/restaurants/app/context/OrderCartContext.jsx +1 -1
  263. package/skills/wix-vibe-headless/references/restaurants/app/rest/wix-restaurants-ordering.js +29 -31
  264. package/skills/wix-vibe-headless/references/storefront/INSTRUCTIONS.md +152 -92
  265. package/skills/wix-vibe-headless/references/storefront/app/components/CartDrawer.jsx +37 -38
  266. package/skills/wix-vibe-headless/references/storefront/app/context/CartContext.jsx +2 -2
  267. package/skills/wix-vibe-headless/references/storefront/app/hooks/useProductDetail.js +15 -8
  268. package/skills/wix-vibe-headless/references/storefront/app/lib/storeImage.js +37 -0
  269. package/skills/wix-vibe-headless/references/storefront/app/rest/wix-store-cart.js +35 -35
  270. package/skills/wix-vibe-headless/references/storefront/app/rest/wix-store-catalog.js +18 -6
  271. package/skills/wix-vibe-headless/references/storefront/seed/SEED.md +30 -7
  272. package/skills/wix-vibe-headless/references/storefront/seed/seed-store.js +46 -10
  273. package/skills/wix-app/references/editor-react-component/A11Y-REVIEW-REFERENCE.md +0 -172
  274. package/skills/wix-app/references/editor-react-component/A11Y-REVIEW.md +0 -143
  275. package/skills/wix-app/references/editor-react-component/COMPONENT-API.md +0 -516
  276. package/skills/wix-app/references/editor-react-component/COMPONENT-CONFIGURATION.md +0 -225
  277. package/skills/wix-app/references/editor-react-component/EDIT-FLOW.md +0 -6
  278. package/skills/wix-app/references/editor-react-component/REACT-PATTERNS.md +0 -95
  279. package/skills/wix-vibe-headless/references/storefront/app/components/ProductCard.jsx +0 -110
  280. package/skills/wix-vibe-headless/references/storefront/app/components/ProductGallery.jsx +0 -51
  281. package/skills/wix-vibe-headless/references/storefront/app/components/ProductGrid.jsx +0 -49
  282. package/skills/wix-vibe-headless/references/storefront/app/components/VariantPicker.jsx +0 -92
  283. package/skills/wix-vibe-headless/references/storefront/app/pages/ProductDetail.jsx +0 -139
@@ -0,0 +1,85 @@
1
+ # Storefront — seeding
2
+
3
+ Seed the Wix Stores catalog by **running `seed-store.mjs` with a plan file** — don't hand-write
4
+ the REST calls. The script mints its own site token via the Wix CLI (requires a logged-in CLI
5
+ session and a `wix.config.json` in the working directory), installs the Stores app if needed,
6
+ waits for the V3 catalog, and creates everything in the right order.
7
+
8
+ **Set each product's type by what the buyer receives** — physical (shipped, has `quantity`) or
9
+ digital (a file they keep, `digitalFilePath`/`digitalFileUrl`, no `quantity`); the plan below shows
10
+ both. *Access* — a membership or an online course/program the buyer enrolls in — is Pricing Plans,
11
+ not a store product.
12
+
13
+ ```bash
14
+ # from the project root (where wix.config.json lives):
15
+ node <SKILL_ROOT>/references/storefront/seed/seed-store.mjs plan.json
16
+ ```
17
+
18
+ `plan.json` is plain data — write it from the brief:
19
+
20
+ ```json
21
+ {
22
+ "products": [
23
+ { "name": "The Glam Rocker", "description": "Sequin-studded velvet legend…",
24
+ "price": 49.99, "quantity": 12, "imageUrl": "https://…" },
25
+ { "name": "The Understudy", "description": "…", "price": 245, "quantity": 8,
26
+ "options": [{ "name": "Color", "type": "color",
27
+ "choices": [{ "name": "Ink", "colorCode": "#1B1B2F" },
28
+ { "name": "Bone", "colorCode": "#EDE6D6" }] }] },
29
+ { "name": "Encore Jacket", "description": "…", "price": 68, "compareAtPrice": 129,
30
+ "quantity": 5 },
31
+ { "name": "Backstage Guide", "description": "…", "price": 12,
32
+ "digitalFilePath": "/Users/me/guide.pdf" }
33
+ ],
34
+ "categories": { "Legends": ["The Glam Rocker"], "Rising Stars": [] }
35
+ }
36
+ ```
37
+
38
+ - `description` — plain text or simple HTML (`<p>`, `<br/>`, `<strong>`, `<em>`); converted to
39
+ Wix rich text so the storefront renders paragraphs and bold, not tag text.
40
+ - `options` — ONLY things the buyer selects-and-buys (Size, Color); they become variants.
41
+ `type: "color"` renders as real swatches (give every color choice a `colorCode`); anything
42
+ else renders as text pills. Variants are expanded automatically (full cross-product, each
43
+ carrying the product's price/compareAtPrice/quantity) — keep option counts small.
44
+ - `compareAtPrice` (> `price`) — the "was" price: strikethrough on the PDP, sale badge data on
45
+ the tile.
46
+ - **Give every product an image** (a store without product images looks broken: gray boxes on
47
+ tiles, PDP, and cart) — the default is an `imagePrompt` (AI-generated, ~1 Wix AI credit
48
+ per image, account-billed): brand-contextual — subject, aesthetic/mood, palette, lighting —
49
+ always ending "no text, no watermarks". At least one image in the set shows the real subject of the business — the actual product/space/service, not abstract decoration. For an asset the user actually supplied use `imagePath` (a file on
50
+ this machine — uploaded to Wix Media) or `imageUrl` (their own hosted URL; verify it with
51
+ `curl -sI` → 200) — never a stock-photo or guessed URL. Images resolve in parallel and never block the seed; a failed image leaves
52
+ that product text-only. Seed text-only only when the user explicitly asks.
53
+ - `digitalFilePath` (a file on this machine) or `digitalFileUrl` — makes the product a digital
54
+ download, uploaded and created with both the file and stock (`quantity` is ignored). It's also the
55
+ only way in: a file-less digital product is created successfully, reads back healthy, and is then
56
+ rejected at add-to-cart as `ITEM_NOT_FOUND_IN_CATALOG`.
57
+ - `categories` — category name → product NAMES. Omit when the brief names none.
58
+
59
+ **Default to 3 products** unless the brief asks for a specific catalog — the seed shows the
60
+ shape, not a full inventory; the owner adds the rest in the dashboard. **Make those 3 exercise
61
+ the shipped UI**: give at least one product a color option and put one product on sale —
62
+ truthfully to the business (a ceramics studio has glaze colors; a bakery doesn't).
63
+
64
+ **Seeding is additive — never delete or overwrite existing content.** No cleanup, no removing
65
+ "sample" data, no resets. If a cleanup genuinely seems needed, ask the user first.
66
+
67
+ Two things this module does not seed (dashboard-only — tell the merchant):
68
+ **ribbons** ("New", "Best Seller") and **per-choice linked media** (color choice → gallery photo).
69
+
70
+ ## Escape hatch — individual functions
71
+
72
+ `setupStore` is built from exported steps; import them only for a partial re-seed or custom
73
+ ordering: `installStoresApp`, `bulkCreateProducts`, `createCategories`,
74
+ `addProductsToCategories`, `attachProductImages` — plus `makeCtx()` for the auth context.
75
+
76
+ ## Reference
77
+
78
+ If a call returns an unexpected shape or you need an operation this module doesn't cover, read
79
+ the live Wix API reference — never guess. The authoritative source recipe is
80
+ `wix-headless/references/inline-recipes/setup-online-store.md`. Key pages:
81
+
82
+ - Bulk Create Products With Inventory: https://dev.wix.com/docs/api-reference/business-solutions/stores/catalog-v3/products-v3/bulk-create-products-with-inventory.md
83
+ - Create Category: https://dev.wix.com/docs/api-reference/business-solutions/stores/catalog-v3/categories/create-category.md
84
+ - Bulk Add Items To Category: https://dev.wix.com/docs/api-reference/business-solutions/stores/catalog-v3/categories/bulk-add-items-to-category.md
85
+ - Bulk Update Products (image attach): https://dev.wix.com/docs/api-reference/business-solutions/stores/catalog-v3/products-v3/bulk-update-products.md
@@ -0,0 +1,415 @@
1
+ // Storefront seed — a BUILD-TIME script, never shipped in the app. Run it from the project
2
+ // root (where wix.config.json lives) with a plan file:
3
+ //
4
+ // node <SKILL_ROOT>/references/storefront/seed/seed-store.mjs plan.json
5
+ //
6
+ // It mints its own site token via the Wix CLI (the token never leaves this process), installs
7
+ // the Wix Stores app if needed, waits for the V3 catalog, bulk-creates products (variants
8
+ // expanded, descriptions converted to rich text), creates categories (serially — the shared
9
+ // tree 409s on concurrent creates), assigns products, and attaches images. Prints a JSON
10
+ // result to stdout.
11
+ //
12
+ // Plan shape (see SEED.md):
13
+ // { "products": [{ "name", "description", "price", "compareAtPrice"?, "quantity",
14
+ // "options"?: [{ "name", "type"?: "text"|"color",
15
+ // "choices": ["S","M"] | [{ "name", "colorCode" }] }],
16
+ // "imageUrl"? | "imagePath"? | "imagePrompt"?, "altText"?,
17
+ // "digitalFileUrl"? | "digitalFilePath"?, "digitalFileName"? }],
18
+ // "categories"?: { "<category name>": ["<product name>", ...] } }
19
+ //
20
+ // Seeding is ADDITIVE — this script never deletes or overwrites existing content.
21
+ // If a call fails with an unexpected shape, read the live API reference (the authoritative
22
+ // source recipe is wix-headless/references/inline-recipes/setup-online-store.md) — never guess.
23
+ import { execFileSync } from "node:child_process";
24
+ import { basename } from "node:path";
25
+ import { readFileSync } from "node:fs";
26
+ import { resolveItemImages } from "../../shared/seed/images.mjs";
27
+
28
+ const API = "https://www.wixapis.com";
29
+ const STORES_APP_ID = "215238eb-22a5-4c36-9e7b-e7c08025e04e";
30
+
31
+ // ---- auth: siteId from wix.config.json, token minted by the Wix CLI ----------------------------
32
+
33
+ export function makeCtx({ cwd = process.cwd() } = {}) {
34
+ const config = JSON.parse(readFileSync(`${cwd}/wix.config.json`, "utf8"));
35
+ const siteId = config.siteId ?? config.projectId;
36
+ if (!siteId) throw new Error("wix.config.json has no siteId — is this a Wix CLI project?");
37
+ // The CLI returns a byte-identical token within a run — mint once, reuse.
38
+ const token = execFileSync("npx", ["@wix/cli@latest", "token", "--site", siteId], {
39
+ encoding: "utf8",
40
+ cwd,
41
+ }).trim();
42
+ if (!token) throw new Error("The Wix CLI returned no token — run `npx @wix/cli@latest login` first.");
43
+ return { token, siteId };
44
+ }
45
+
46
+ // ---- transport ----------------------------------------------------------------------------------
47
+
48
+ async function req(ctx, path, { method = "POST", body } = {}) {
49
+ // Retry while the catalog is still provisioning: right after a fresh Stores install the V3
50
+ // WRITE path becomes usable later than the read path, so the first bulk-create can 428 even
51
+ // after the read probe clears. Wait it out (~80s budget); other errors throw immediately.
52
+ // ⚠️ An errored bulk create (seen live with a bare 429 {}) may still have APPLIED
53
+ // server-side — creation is idempotent by name in setupStore for exactly that reason.
54
+ for (let attempt = 0; ; attempt++) {
55
+ const res = await fetch(API + path, {
56
+ method,
57
+ headers: {
58
+ Authorization: `Bearer ${ctx.token}`,
59
+ "wix-site-id": ctx.siteId,
60
+ "Content-Type": "application/json",
61
+ },
62
+ body: body ? JSON.stringify(body) : undefined,
63
+ });
64
+ const json = await res.json().catch(() => ({}));
65
+ if (res.ok) return json;
66
+ if (isProvisioning(res.status, json) && attempt < 40) {
67
+ await sleep(2000);
68
+ continue;
69
+ }
70
+ throw new Error(`${method} ${path} -> ${res.status}: ${JSON.stringify(json).slice(0, 400)}`);
71
+ }
72
+ }
73
+
74
+ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
75
+
76
+ // A freshly installed catalog signals "not writable yet" with a 428 under (at least) two codes.
77
+ const PROVISIONING_CODES = new Set(["CATALOG_V1_SITE_CALLING_CATALOG_V3_API", "CATALOG_V3_SITE_PROVISIONING"]);
78
+
79
+ function isProvisioning(status, json) {
80
+ if (PROVISIONING_CODES.has(json?.details?.applicationError?.code)) return true;
81
+ return status === 428 && /provision/i.test(json?.message || "");
82
+ }
83
+
84
+ // docs: https://dev.wix.com/docs/api-reference/business-solutions/stores/catalog-v3/products-v3/query-products.md
85
+ async function waitForCatalogV3(ctx, { attempts = 40, delayMs = 2000 } = {}) {
86
+ for (let i = 0; i < attempts; i++) {
87
+ const res = await fetch(`${API}/stores/v3/products/query`, {
88
+ method: "POST",
89
+ headers: { Authorization: `Bearer ${ctx.token}`, "wix-site-id": ctx.siteId, "Content-Type": "application/json" },
90
+ body: JSON.stringify({ query: { paging: { limit: 1 } } }),
91
+ });
92
+ if (res.ok) return;
93
+ const json = await res.json().catch(() => ({}));
94
+ if (!isProvisioning(res.status, json)) return;
95
+ await sleep(delayMs);
96
+ }
97
+ }
98
+
99
+ // ---- description string -> Wix rich-text nodes --------------------------------------------------
100
+ // Descriptions arrive as HTML as often as not. The writable field is `description` (Ricos
101
+ // nodes) — the HTML `plainDescription` the storefront renders is derived from them, so markup
102
+ // dropped into a TEXT node comes back escaped and the PDP shows literal tags. Convert the tags
103
+ // a model actually emits; a tag-free string stays one paragraph.
104
+
105
+ const HTML_ENTITIES = { "&amp;": "&", "&lt;": "<", "&gt;": ">", "&quot;": '"', "&#39;": "'", "&nbsp;": " " };
106
+
107
+ function decodeEntities(s) {
108
+ return s.replace(/&(?:amp|lt|gt|quot|#39|nbsp);/g, (m) => HTML_ENTITIES[m] ?? m);
109
+ }
110
+
111
+ function mkTextNodes(html) {
112
+ const nodes = [];
113
+ let bold = 0, italic = 0, last = 0, m;
114
+ const tag = /<(\/?)(strong|b|em|i)\s*\/?>/gi;
115
+ const push = (raw) => {
116
+ const text = decodeEntities(raw.replace(/<[^>]*>/g, ""));
117
+ if (!text) return;
118
+ const decorations = [];
119
+ if (bold > 0) decorations.push({ type: "BOLD" });
120
+ if (italic > 0) decorations.push({ type: "ITALIC" });
121
+ nodes.push({ type: "TEXT", textData: { text, decorations } });
122
+ };
123
+ while ((m = tag.exec(html)) !== null) {
124
+ push(html.slice(last, m.index));
125
+ const step = m[1] ? -1 : 1;
126
+ if (/^(strong|b)$/i.test(m[2])) bold = Math.max(0, bold + step);
127
+ else italic = Math.max(0, italic + step);
128
+ last = tag.lastIndex;
129
+ }
130
+ push(html.slice(last));
131
+ return nodes.length ? nodes : [{ type: "TEXT", textData: { text: "", decorations: [] } }];
132
+ }
133
+
134
+ function mkDesc(text, i) {
135
+ const blocks = String(text ?? "").split(/<\/p\s*>|<br\s*\/?>/i).map((b) => b.trim()).filter(Boolean);
136
+ return {
137
+ nodes: (blocks.length ? blocks : [""]).map((block, n) => ({
138
+ type: "PARAGRAPH", id: `desc-${i}-${n}`,
139
+ nodes: mkTextNodes(block),
140
+ paragraphData: { textStyle: { textAlignment: "AUTO" } },
141
+ })),
142
+ metadata: { version: 1, id: `desc-meta-${i}` },
143
+ };
144
+ }
145
+
146
+ // ---- options / variants -------------------------------------------------------------------------
147
+
148
+ function buildOptions(options = []) {
149
+ return options.map((o) => {
150
+ const color = o.type === "color";
151
+ return {
152
+ name: o.name,
153
+ optionRenderType: color ? "SWATCH_CHOICES" : "TEXT_CHOICES",
154
+ choicesSettings: {
155
+ choices: o.choices.map((c) =>
156
+ color
157
+ ? { choiceType: "ONE_COLOR", name: c.name, colorCode: c.colorCode }
158
+ : { choiceType: "CHOICE_TEXT", name: typeof c === "string" ? c : c.name }),
159
+ },
160
+ };
161
+ });
162
+ }
163
+
164
+ // Full Cartesian product, each variant priced/stocked from the product; visible:true baked in.
165
+ function expandVariants(options = [], { price, compareAtPrice, quantity }, digitalFileId) {
166
+ const base = {
167
+ price: {
168
+ actualPrice: { amount: String(price) },
169
+ ...(compareAtPrice ? { compareAtPrice: { amount: String(compareAtPrice) } } : {}),
170
+ },
171
+ visible: true,
172
+ ...(digitalFileId
173
+ ? { digitalProperties: { digitalFile: { id: digitalFileId } }, inventoryItem: { inStock: true } }
174
+ : { physicalProperties: {}, inventoryItem: { quantity: quantity ?? 0, preorderInfo: { enabled: false } } }),
175
+ };
176
+ if (!options.length) return [base];
177
+ let combos = [[]];
178
+ for (const o of options) {
179
+ const rt = o.type === "color" ? "SWATCH_CHOICES" : "TEXT_CHOICES";
180
+ const names = o.choices.map((c) => (typeof c === "string" ? c : c.name));
181
+ combos = combos.flatMap((combo) =>
182
+ names.map((choiceName) => [...combo, { optionChoiceNames: { optionName: o.name, choiceName, renderType: rt } }]));
183
+ }
184
+ return combos.map((choices) => ({ ...base, choices }));
185
+ }
186
+
187
+ // ---- operations ---------------------------------------------------------------------------------
188
+
189
+ // docs: https://dev.wix.com/docs/api-reference/articles/work-with-wix-apis/platform/about-apps-created-by-wix.md
190
+ export async function installStoresApp(ctx) {
191
+ try {
192
+ await req(ctx, "/apps-installer-service/v1/app-instance/install", { body: {
193
+ tenant: { tenantType: "SITE", id: ctx.siteId },
194
+ appInstance: { appDefId: STORES_APP_ID, enabled: true },
195
+ } });
196
+ } catch {
197
+ // already installed is fine — the readiness wait below still confirms the V3 catalog is live
198
+ }
199
+ await waitForCatalogV3(ctx);
200
+ }
201
+
202
+ // Existing products by exact name (for idempotent reruns). `name` is NOT filterable on the
203
+ // V3 query — fetch a page and match client-side (seed catalogs are small). Empty map on any
204
+ // failure — falling back to create-everything is the additive behavior we had before.
205
+ export async function queryProductsByNames(ctx, names) {
206
+ const out = new Map();
207
+ if (!names.length) return out;
208
+ try {
209
+ const wanted = new Set(names);
210
+ const r = await req(ctx, "/stores/v3/products/query", { body: { query: { cursorPaging: { limit: 100 } } } });
211
+ for (const p of r.products ?? []) {
212
+ if (wanted.has(p.name) && !out.has(p.name)) out.set(p.name, { id: p.id, slug: p.slug, revision: p.revision });
213
+ }
214
+ } catch (e) {
215
+ console.error(`product name pre-check failed (creating everything): ${String(e.message).slice(0, 120)}`);
216
+ }
217
+ return out;
218
+ }
219
+
220
+ // A digital variant is SELLABLE only with BOTH a file and stock: without the file the cart rejects
221
+ // it as ITEM_NOT_FOUND_IN_CATALOG, without stock as "exceeds available inventory" — and either way
222
+ // the product reads back visible and in the catalog, so nothing surfaces until a buyer tries to buy.
223
+ // A digitalFile* field is the only way into DIGITAL here, which makes the file-less product
224
+ // unbuildable. The bytes are PUT, not imported by url: an uploaded file is READY at once, while an
225
+ // imported one stays PENDING and the cart rejects the product until it settles.
226
+ // docs: https://dev.wix.com/docs/api-reference/assets/media/media-manager/files/generate-file-upload-url.md
227
+ const FILE_MIME = { pdf: "application/pdf", zip: "application/zip", epub: "application/epub+zip",
228
+ mp3: "audio/mpeg", wav: "audio/wav", mp4: "video/mp4", png: "image/png", jpg: "image/jpeg" };
229
+
230
+ async function uploadDigitalFile(ctx, { digitalFileUrl, digitalFilePath, digitalFileName }) {
231
+ const src = digitalFilePath ?? digitalFileUrl;
232
+ const fileName = digitalFileName || decodeURIComponent(basename(new URL(src, "file:").pathname));
233
+ const mimeType = FILE_MIME[fileName.split(".").pop().toLowerCase()];
234
+ if (!mimeType) throw new Error(`digitalFileName needs one of these extensions (${Object.keys(FILE_MIME).join(", ")}): ${fileName}`);
235
+ const bytes = digitalFilePath
236
+ ? readFileSync(digitalFilePath)
237
+ : await fetch(digitalFileUrl).then((r) => {
238
+ if (!r.ok) throw new Error(`digitalFileUrl ${digitalFileUrl} -> ${r.status}`);
239
+ return r.arrayBuffer();
240
+ });
241
+ const { uploadUrl } = await req(ctx, "/site-media/v1/files/generate-upload-url", { body: { mimeType, fileName } });
242
+ const res = await fetch(uploadUrl, { method: "PUT", headers: { "Content-Type": mimeType }, body: bytes });
243
+ const json = await res.json().catch(() => ({}));
244
+ const id = (json.file || json)?.id;
245
+ if (!res.ok || !id) throw new Error(`digital file upload failed (${res.status}): ${JSON.stringify(json).slice(0, 200)}`);
246
+ return id;
247
+ }
248
+
249
+ // docs: https://dev.wix.com/docs/api-reference/business-solutions/stores/catalog-v3/products-v3/bulk-create-products-with-inventory.md
250
+ export async function bulkCreateProducts(ctx, products) {
251
+ const fileIds = await Promise.all(products.map((p) =>
252
+ p.digitalFileUrl || p.digitalFilePath ? uploadDigitalFile(ctx, p) : null));
253
+ const body = {
254
+ returnEntity: true,
255
+ products: products.map((p, i) => ({
256
+ name: p.name,
257
+ // DIGITAL drops physicalProperties and can't be POS-visible (DIGITAL_PRODUCT_CANNOT_BE_VISIBLE_IN_POS).
258
+ ...(fileIds[i]
259
+ ? { productType: "DIGITAL" }
260
+ : { productType: "PHYSICAL", physicalProperties: {}, visibleInPos: true }),
261
+ visible: true,
262
+ description: mkDesc(p.description, i),
263
+ options: buildOptions(p.options),
264
+ variantsInfo: { variants: expandVariants(p.options, p, fileIds[i]) },
265
+ })),
266
+ };
267
+ const r = await req(ctx, "/stores/v3/bulk/products-with-inventory/create", { body });
268
+ // NB: results nest under productResults.results[].item — NOT a top-level `results`.
269
+ const created = (r.productResults?.results ?? []).map((x, i) => ({
270
+ id: x.item?.id, slug: x.item?.slug, revision: x.item?.revision,
271
+ variantId: x.item?.variantsInfo?.variants?.[0]?.id,
272
+ hasOptions: (products[i]?.options?.length ?? 0) > 0,
273
+ isDigital: !!fileIds[i],
274
+ quantity: products[i]?.quantity ?? 0,
275
+ }));
276
+ await stockOptionlessProducts(ctx, created);
277
+ return created.map((p) => ({ id: p.id, slug: p.slug, revision: p.revision }));
278
+ }
279
+
280
+ // The bulk create stocks a variant via its choices; an OPTION-LESS product's single default
281
+ // variant is NOT stocked by it and lands OUT_OF_STOCK — stock those explicitly.
282
+ // docs: https://dev.wix.com/docs/api-reference/business-solutions/stores/catalog-v3/products-v3/query-products.md
283
+ // docs: https://dev.wix.com/docs/api-reference/business-solutions/stores/catalog-v3/inventory-items-v3/bulk-create-inventory-items.md
284
+ async function stockOptionlessProducts(ctx, created) {
285
+ const need = created.filter((p) => !p.hasOptions && !p.isDigital && p.id); // digital variants ship inStock from the create
286
+ if (!need.length) return;
287
+ const missing = need.filter((p) => !p.variantId).map((p) => p.id);
288
+ if (missing.length) {
289
+ const q = await req(ctx, "/stores/v3/products/query", { body: { query: { filter: { id: { $in: missing } }, paging: { limit: missing.length } } } });
290
+ const vById = new Map((q.products ?? []).map((p) => [p.id, p.variantsInfo?.variants?.[0]?.id]));
291
+ need.forEach((p) => { if (!p.variantId) p.variantId = vById.get(p.id); });
292
+ }
293
+ const inventoryItems = need
294
+ .filter((p) => p.variantId)
295
+ .map((p) => ({ productId: p.id, variantId: p.variantId, quantity: p.quantity }));
296
+ if (inventoryItems.length) {
297
+ await req(ctx, "/stores/v3/bulk/inventory-items/create", { body: { inventoryItems } });
298
+ }
299
+ }
300
+
301
+ // Categories share the @wix/stores tree revision — concurrent creates 409, so: sequential.
302
+ // docs: https://dev.wix.com/docs/api-reference/business-solutions/stores/catalog-v3/categories/create-category.md
303
+ export async function createCategories(ctx, names) {
304
+ const out = [];
305
+ for (const name of names) {
306
+ const r = await req(ctx, "/categories/v1/categories", {
307
+ body: { category: { name, visible: true }, treeReference: { appNamespace: "@wix/stores", treeKey: null } },
308
+ });
309
+ out.push({ id: r.category?.id, name });
310
+ }
311
+ return out;
312
+ }
313
+
314
+ // docs: https://dev.wix.com/docs/api-reference/business-solutions/stores/catalog-v3/categories/bulk-add-items-to-category.md
315
+ export async function addProductsToCategories(ctx, mapping) {
316
+ for (const [categoryId, productIds] of Object.entries(mapping)) {
317
+ await req(ctx, `/categories/v1/bulk/categories/${categoryId}/add-items`, {
318
+ body: {
319
+ items: productIds.map((catalogItemId) => ({ catalogItemId, appId: STORES_APP_ID })),
320
+ treeReference: { appNamespace: "@wix/stores", treeKey: null },
321
+ },
322
+ });
323
+ }
324
+ }
325
+
326
+ // Bulk image attach in ONE call. items: [{ id, url, altText }] — no revision to pass: the
327
+ // current revision is read right before the update, so attach any number of times, any pass.
328
+ // Wix re-hosts each url server-side; the media can take a little while to appear on read-back
329
+ // (propagation) — normal, not a failure.
330
+ // docs: https://dev.wix.com/docs/api-reference/business-solutions/stores/catalog-v3/products-v3/bulk-update-products.md
331
+ export async function attachProductImages(ctx, items) {
332
+ if (!items?.length) return;
333
+ const ids = items.map((it) => it.id);
334
+ const q = await req(ctx, "/stores/v3/products/query", { body: { query: { filter: { id: { $in: ids } }, paging: { limit: ids.length } } } });
335
+ const revById = new Map((q.products ?? []).map((p) => [p.id, p.revision]));
336
+ return req(ctx, "/stores/v3/bulk/products/update", {
337
+ body: {
338
+ products: items.map((it) => ({
339
+ product: { id: it.id, revision: revById.get(it.id), media: { itemsInfo: { items: [{ url: it.url, altText: it.altText }] } } },
340
+ })),
341
+ },
342
+ });
343
+ }
344
+
345
+ /**
346
+ * ONE-CALL seed: install → create products → categories → attach images, ids threaded in
347
+ * memory. This is the default path — call it once instead of the individual functions.
348
+ */
349
+ export async function setupStore(ctx, { products = [], categories = {} } = {}) {
350
+ await installStoresApp(ctx);
351
+
352
+ // Idempotent by name: an errored bulk create (429/5xx) may still have applied server-side,
353
+ // and SKILL.md tells the agent to re-run a failed seed — creating only the names that don't
354
+ // exist yet makes that rerun safe instead of a duplicator.
355
+ const existing = await queryProductsByNames(ctx, products.map((p) => p.name));
356
+ const toCreate = products.filter((p) => !existing.has(p.name));
357
+ const created = toCreate.length ? await bulkCreateProducts(ctx, toCreate) : [];
358
+ const createdByName = new Map(created.map((p, i) => [toCreate[i]?.name, p]));
359
+ const withNames = products.map((p) => {
360
+ const hit = createdByName.get(p.name) ?? existing.get(p.name);
361
+ return { ...(hit ?? {}), name: p.name };
362
+ });
363
+ const idByName = new Map(withNames.map((p) => [p.name, p.id]));
364
+
365
+ const names = Object.keys(categories);
366
+ const cats = names.length ? await createCategories(ctx, names) : [];
367
+ if (cats.length) {
368
+ const mapping = {};
369
+ for (const c of cats) {
370
+ const ids = (categories[c.name] || []).map((n) => idByName.get(n)).filter(Boolean);
371
+ if (ids.length) mapping[c.id] = ids;
372
+ }
373
+ if (Object.keys(mapping).length) await addProductsToCategories(ctx, mapping);
374
+ }
375
+
376
+ // Pass 2 — images: resolve (import by url / generate by prompt) in one parallel wave, then
377
+ // bulk-attach. Failures leave the product text-only; the seed's exit never depends on images.
378
+ const files = await resolveItemImages(ctx, withNames.map((p, i) => ({
379
+ url: products[i]?.imageUrl,
380
+ path: products[i]?.imagePath,
381
+ prompt: products[i]?.imagePrompt,
382
+ displayName: `${p.slug || "product"}.png`,
383
+ })));
384
+ const imageItems = withNames
385
+ .map((p, i) => (files[i] && p.id ? { id: p.id, url: files[i].url, altText: products[i]?.altText ?? p.slug } : null))
386
+ .filter(Boolean);
387
+ let imagesAttached = 0;
388
+ try {
389
+ if (imageItems.length) await attachProductImages(ctx, imageItems);
390
+ imagesAttached = imageItems.length;
391
+ } catch {
392
+ /* never block on image failure — the products stay text-only */
393
+ }
394
+
395
+ return { products: withNames, categories: cats, imagesAttached };
396
+ }
397
+
398
+ // ---- CLI entry ----------------------------------------------------------------------------------
399
+
400
+ const invokedDirectly = process.argv[1] && import.meta.url.endsWith(process.argv[1].split("/").pop());
401
+ if (invokedDirectly) {
402
+ const planPath = process.argv[2];
403
+ if (!planPath) {
404
+ console.error("usage: node seed-store.mjs <plan.json> (run from the project root)");
405
+ process.exit(1);
406
+ }
407
+ const plan = JSON.parse(readFileSync(planPath, "utf8"));
408
+ const ctx = makeCtx();
409
+ setupStore(ctx, plan)
410
+ .then((result) => console.log(JSON.stringify(result, null, 2)))
411
+ .catch((e) => {
412
+ console.error(e.message);
413
+ process.exit(1);
414
+ });
415
+ }
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: wix-manage
3
- description: "Wix business solution management recipes — REST API operations for configuring and managing Wix business solutions. Routes to: stores, bookings, get-paid, CMS, contacts, forms, media, app-installation, pricing-plans, restaurants, ricos rich-content, sites, blog, calendar, domains, events, site-properties, ecommerce, marketing, google-ads, analytics, accessibility, dashboard-navigation."
3
+ description: "REST recipes to configure and manage a Wix site's business solutions — stores, bookings, payments, CMS, and more. Open the matching recipe for the exact endpoint, method, and payload before calling — never guess a Wix API. Routes to: stores, bookings, get-paid, CMS, contacts, forms, media, app-installation, pricing-plans, restaurants, ricos rich-content, sites, blog, calendar, domains, events, site-properties, ecommerce, marketing, google-ads, google-business-profile, analytics, accessibility, seo, dashboard-navigation."
4
4
  compatibility: Requires Wix REST API access (API key or OAuth).
5
5
  ---
6
6
 
@@ -34,6 +34,16 @@ These recipes do NOT cover frontend development or SDK usage for displaying data
34
34
 
35
35
  ---
36
36
 
37
+ ## SEO
38
+
39
+ ### [Manage a Wix Site's SEO Tags](references/seo/manage-seo-tags.md)
40
+ **Technical:** Reads and writes SEO tags (titles, descriptions, social tags, structured data, indexing) at three levels: site-wide, page-type patterns, and individual items. Always read before write — every Set replaces in full.
41
+
42
+ ### [Manage URL Redirects on a Wix Site](references/seo/manage-url-redirects.md)
43
+ **Technical:** Reads, creates, and deletes URL redirects through the public SEO Redirects API. Distinguishes exact from group redirects, handles language-scoped redirects on multilingual sites, reads per-item results from bulk responses, and confirms before writes, because creating a redirect can permanently delete an existing one.
44
+
45
+ ---
46
+
37
47
  ## Accessibility
38
48
 
39
49
  ### [Scan a Wix Site for Accessibility Issues](references/accessibility/scan-site-accessibility.md)
@@ -268,6 +278,7 @@ These recipes do NOT cover frontend development or SDK usage for displaying data
268
278
  **Routing — Google paid-advertising campaigns for a site (Smart & Performance Max).** All flows require a Google Ads account, created once via the setup recipe. Budgets are in micros (1,000,000 = 1 currency unit). REST base: `https://www.wixapis.com/google-ads/v1`.
269
279
  - **First-time setup / "connect Google Ads" / `ACCOUNT_NOT_FOUND`** → [Install and Create an Account](references/google-ads/install-and-create-account.md) (do this before anything else).
270
280
  - **Suggested keywords / geo / budget / ad copy / images** → [Get AI Campaign Suggestions](references/google-ads/get-campaign-suggestions.md).
281
+ - **Offer a Success Guide after creating a PMAX Leads campaign (a proactive offer requires approval) / improve it / success guide / says they completed or fixed a guide recommendation / mark or reopen a recommendation** → [Manage a Campaign Success Guide](references/google-ads/manage-campaign-success-guide.md) (a direct improvement/guide request is already approval; works while `LEARNING` and before metrics exist).
271
282
  - **Create a multi-channel / lead-gen / Shopping campaign** → [Create a Performance Max Campaign](references/google-ads/create-performance-max-campaign.md).
272
283
  - **Pause / resume / launch / update budget / delete / history** → [Manage Campaign Lifecycle](references/google-ads/manage-campaign-lifecycle.md).
273
284
  - **Performance, conversions, search terms, per-product / per-asset metrics** → [Query Campaign Performance Analytics](references/google-ads/query-campaign-analytics.md).
@@ -285,6 +296,9 @@ These recipes do NOT cover frontend development or SDK usage for displaying data
285
296
  ### [Manage Campaign Lifecycle](references/google-ads/manage-campaign-lifecycle.md)
286
297
  **Technical:** Lists/gets campaigns and runs lifecycle actions: launch (first activation) vs resume (reactivate after pause), pause (with optional `scheduledResumeDate`/reminder), partial `UpdateCampaign` (name, budget, targeting), delete (irreversible), and read the change log / status history. Covers the 5-live-campaign cap and budget-boundary validation.
287
298
 
299
+ ### [Manage a Campaign Success Guide](references/google-ads/manage-campaign-success-guide.md)
300
+ **Technical:** Retrieves or generates the prioritized success guide for an existing Google Ads Performance Max Leads campaign and updates a returned suggestion's `OPEN` or `COMPLETED` tracking status. Use for "How can I improve my campaign?", "what should I fix next?", "show my campaign success guide", "mark this recommendation complete", and "reopen this recommendation". Also offer it directly after campaign creation—even while `LEARNING` or before metrics exist; only that proactive offer requires user approval before retrieval. A direct improvement or guide request is already approval. A clear statement that the user completed a returned recommendation is an actionable request to mark it `COMPLETED`, even when phrased as an update rather than a question; do not merely acknowledge it or ask for redundant confirmation. Pre-campaign assets, keywords, budgets, and targeting remain in Get AI Campaign Suggestions.
301
+
288
302
  ### [Query Campaign Performance Analytics](references/google-ads/query-campaign-analytics.md)
289
303
  **Technical:** Reads campaign analytics via six endpoints — daily performance metrics (with previous-period trends), conversion metrics (orders/revenue/ROAS from Wix), search terms, per-product shopping performance, and per-asset PMAX-Leads metrics. Explains `campaignResourceName` vs Wix `campaignId`, the `dateRange` shape, field enums, sorting, and paging.
290
304
 
@@ -296,6 +310,18 @@ These recipes do NOT cover frontend development or SDK usage for displaying data
296
310
 
297
311
  ---
298
312
 
313
+ ## Google Business Profile
314
+
315
+ **Routing — how a business appears on Google Search and Maps.** A Google connection is the prerequisite for all Google-backed location work: check it first, and route "connect / reconnect / disconnect Google" to the connection recipe.
316
+
317
+ ### [Connect a Wix Site to Google Business Profile](references/google-business-profile/connect-google-business-profile.md)
318
+ **Technical:** Establishes, checks, and removes the site's Google Business Profile connection. Reads the connection status (`NEVER_CONNECTED` / `VALID` / `NEEDS_RECONNECT`), requests a single-use 15-minute connect URL for the site owner to authorize in their own browser, confirms completion by re-reading the status, and warns before any reconnect that permanently removes the site's imported locations. Never auto-retries the non-idempotent connect-URL call.
319
+
320
+ ### [Manage Google Business Profile Locations for a Wix Site](references/google-business-profile/manage-google-business-profile-locations.md)
321
+ **Technical:** Imports locations from the connected Google account (accounts → unimported locations → bulk create with per-item results), queries them Wix-only or hydrated with live Google data, routes each update to the correct side (Wix row vs Google listing), creates new Google listings, checks profile liveness via Voice of Merchant, and distinguishes un-importing from Wix from deleting the real Google listing. Reports a missing connection as a setup step and respects Google's shared ~10-edits-per-minute budget.
322
+
323
+ ---
324
+
299
325
  ## Marketing
300
326
 
301
327
  ### [Create and Publish a Social Media Post (with AI generation)](references/marketing/create-and-publish-social-post.md)
@@ -407,7 +433,7 @@ These recipes do NOT cover frontend development or SDK usage for displaying data
407
433
  **Technical:** Manages pre-order settings for product variants using V3 Inventory API. Covers enabling/disabling pre-orders, setting messages, configuring limits, and handling trackQuantity requirements.
408
434
 
409
435
  ### [Update Product with Options](references/stores/update-product-with-options.md)
410
- **Technical:** Modifies existing products and variants using Catalog V3 Products API. Covers adding/removing option choices, variant-specific pricing, and revision-based updates to prevent conflicts.
436
+ **Technical:** Modifies existing products and variants using Catalog V3 Products API. Covers adding/removing option choices, and the writable choice/variant fields — media & displayImage, SKU/barcode, price incl. compareAtPrice (sale), visibility — plus revision-based updates and which fields are read-only (choice inStock/visible, variant media/inventory).
411
437
 
412
438
  ### [Stores Dashboard Navigation](references/stores/stores-dashboard-navigation.md)
413
439
  **Technical:** Direct links to Wix Stores and eCommerce dashboard pages on manage.wix.com (products list, edit product, categories, inventory, orders list, order details, abandoned checkouts, gift cards, shipping, tax), pairing each main Stores/eCommerce entity with its read API for "view it in your dashboard" links.