@wix/agent-skills 1.21.0 → 1.23.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 (269) hide show
  1. package/package.json +1 -1
  2. package/skills/wix-app/SKILL.md +71 -7
  3. package/skills/wix-app/references/APP_VALIDATION.md +16 -10
  4. package/skills/wix-app/references/DASHBOARD_PAGE.md +11 -25
  5. package/skills/wix-app/references/DATA_COLLECTION.md +16 -219
  6. package/skills/wix-app/references/SDK_MODULE_MAP.md +2 -0
  7. package/skills/wix-app/references/dashboard-page/DATA_SOURCES.md +182 -0
  8. package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE.md +97 -0
  9. package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_COLLECTION.md +184 -0
  10. package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_ROUTER.md +203 -0
  11. package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_SETTINGS.md +44 -0
  12. package/skills/wix-app/references/dashboard-page/QUERY_AND_PAGING.md +182 -0
  13. package/skills/wix-app/references/dashboard-page/TABLE_STATE.md +133 -0
  14. package/skills/wix-app/references/dashboard-page/UX_SUCCESS_MODEL.md +10 -5
  15. package/skills/wix-app/references/data-collection/LIFECYCLE.md +68 -0
  16. package/skills/wix-app/references/data-collection/PERMISSIONS.md +47 -0
  17. package/skills/wix-app/references/data-collection/SCHEMA.md +181 -0
  18. package/skills/wix-app/references/data-collection/WIX_DATA.md +38 -66
  19. package/skills/wix-headless-fast/SKILL.md +95 -230
  20. package/skills/wix-headless-fast/cold-start/bootstrap.mjs +156 -0
  21. package/skills/wix-headless-fast/{entry/skill.md → cold-start/cold-start.md} +17 -14
  22. package/skills/wix-headless-fast/guides/existing-site.md +78 -0
  23. package/skills/wix-headless-fast/guides/migration.md +43 -0
  24. package/skills/wix-headless-fast/guides/reference-mode.md +100 -0
  25. package/skills/wix-headless-fast/install/AGENTS.md +9 -4
  26. package/skills/wix-headless-fast/install/agents-md.mjs +5 -1
  27. package/skills/wix-headless-fast/install/attach.mjs +25 -47
  28. package/skills/wix-headless-fast/install/check.mjs +87 -0
  29. package/skills/wix-headless-fast/install/context.mjs +126 -0
  30. package/skills/wix-headless-fast/install/deploy.mjs +106 -80
  31. package/skills/wix-headless-fast/install/lock.mjs +55 -0
  32. package/skills/wix-headless-fast/install/setup.mjs +83 -23
  33. package/skills/wix-headless-fast/install/templates.mjs +168 -0
  34. package/skills/wix-manage/SKILL.md +3 -3
  35. package/skills/wix-manage/references/app-installation/install-wix-apps.md +68 -2
  36. package/skills/wix-manage/references/contacts/bulk-label-and-unlabel-contacts.md +37 -4
  37. package/skills/wix-manage/references/ecommerce/ecom-pricing.md +29 -3
  38. package/skills/wix-manage/references/google-ads/google-ads-dashboard-navigation.md +27 -0
  39. package/skills/wix-manage/references/google-ads/manage-campaign-success-guide.md +83 -37
  40. package/skills/wix-manage/references/sites/site-import.md +101 -37
  41. package/skills/wix-headless-fast/references/blog/INSTRUCTIONS.md +0 -303
  42. package/skills/wix-headless-fast/references/blog/app/components/blog/BlogFeedView.tsx +0 -136
  43. package/skills/wix-headless-fast/references/blog/app/components/blog/PostView.tsx +0 -112
  44. package/skills/wix-headless-fast/references/blog/app/components/blog/RichContent.tsx +0 -42
  45. package/skills/wix-headless-fast/references/blog/app/hooks/blog/useBlogFeed.ts +0 -31
  46. package/skills/wix-headless-fast/references/blog/app/hooks/blog/usePost.ts +0 -22
  47. package/skills/wix-headless-fast/references/blog/app/wix/blog/blog-feed-store.ts +0 -137
  48. package/skills/wix-headless-fast/references/blog/app/wix/blog/post-store.ts +0 -78
  49. package/skills/wix-headless-fast/references/blog/app/wix/blog/posts-core.ts +0 -117
  50. package/skills/wix-headless-fast/references/blog/app/wix/blog/posts.ts +0 -52
  51. package/skills/wix-headless-fast/references/blog/app/wix/blog/taxonomy-core.ts +0 -47
  52. package/skills/wix-headless-fast/references/blog/app/wix/blog/taxonomy.ts +0 -58
  53. package/skills/wix-headless-fast/references/blog/app/wix/blog/types.ts +0 -62
  54. package/skills/wix-headless-fast/references/blog/app-astro/layouts/SiteLayout.astro +0 -40
  55. package/skills/wix-headless-fast/references/blog/app-astro/pages/blog/[...slug].astro +0 -97
  56. package/skills/wix-headless-fast/references/blog/app-astro/pages/blog.astro +0 -24
  57. package/skills/wix-headless-fast/references/blog/lock/astro/package-lock.json +0 -16156
  58. package/skills/wix-headless-fast/references/blog/rest/posts.ts +0 -42
  59. package/skills/wix-headless-fast/references/blog/rest/taxonomy.ts +0 -62
  60. package/skills/wix-headless-fast/references/blog/seed/SEED.md +0 -81
  61. package/skills/wix-headless-fast/references/blog/seed/read-site.mjs +0 -22
  62. package/skills/wix-headless-fast/references/blog/seed/seed-blog.mjs +0 -287
  63. package/skills/wix-headless-fast/references/bookings/INSTRUCTIONS.md +0 -277
  64. package/skills/wix-headless-fast/references/bookings/app/components/bookings/ServiceBookingView.tsx +0 -144
  65. package/skills/wix-headless-fast/references/bookings/app/components/bookings/ServicesView.tsx +0 -119
  66. package/skills/wix-headless-fast/references/bookings/app/hooks/bookings/useBookingFlow.ts +0 -32
  67. package/skills/wix-headless-fast/references/bookings/app/hooks/bookings/useServices.ts +0 -23
  68. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/booking-core.ts +0 -218
  69. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/booking-flow-store.ts +0 -169
  70. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/booking.ts +0 -121
  71. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/services-core.ts +0 -92
  72. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/services-store.ts +0 -90
  73. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/services.ts +0 -57
  74. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/types.ts +0 -72
  75. package/skills/wix-headless-fast/references/bookings/app-astro/layouts/SiteLayout.astro +0 -40
  76. package/skills/wix-headless-fast/references/bookings/app-astro/pages/services/[slug].astro +0 -76
  77. package/skills/wix-headless-fast/references/bookings/app-astro/pages/services.astro +0 -22
  78. package/skills/wix-headless-fast/references/bookings/lock/astro/package-lock.json +0 -11962
  79. package/skills/wix-headless-fast/references/bookings/rest/booking.ts +0 -113
  80. package/skills/wix-headless-fast/references/bookings/rest/services.ts +0 -55
  81. package/skills/wix-headless-fast/references/bookings/seed/SEED.md +0 -71
  82. package/skills/wix-headless-fast/references/bookings/seed/read-site.mjs +0 -28
  83. package/skills/wix-headless-fast/references/bookings/seed/seed-bookings.mjs +0 -302
  84. package/skills/wix-headless-fast/references/cms/INSTRUCTIONS.md +0 -355
  85. package/skills/wix-headless-fast/references/cms/app/hooks/cms/useCollection.ts +0 -50
  86. package/skills/wix-headless-fast/references/cms/app/hooks/cms/useItem.ts +0 -37
  87. package/skills/wix-headless-fast/references/cms/app/wix/cms/collection-store.ts +0 -158
  88. package/skills/wix-headless-fast/references/cms/app/wix/cms/item-store.ts +0 -93
  89. package/skills/wix-headless-fast/references/cms/app/wix/cms/items-core.ts +0 -177
  90. package/skills/wix-headless-fast/references/cms/app/wix/cms/items.ts +0 -123
  91. package/skills/wix-headless-fast/references/cms/app/wix/cms/types.ts +0 -75
  92. package/skills/wix-headless-fast/references/cms/app-astro/layouts/SiteLayout.astro +0 -41
  93. package/skills/wix-headless-fast/references/cms/lock/astro/package-lock.json +0 -11262
  94. package/skills/wix-headless-fast/references/cms/rest/items.ts +0 -125
  95. package/skills/wix-headless-fast/references/cms/seed/SEED.md +0 -112
  96. package/skills/wix-headless-fast/references/cms/seed/read-site.mjs +0 -20
  97. package/skills/wix-headless-fast/references/cms/seed/seed-cms.mjs +0 -324
  98. package/skills/wix-headless-fast/references/events/INSTRUCTIONS.md +0 -307
  99. package/skills/wix-headless-fast/references/events/app/components/events/EventConfirmationView.tsx +0 -66
  100. package/skills/wix-headless-fast/references/events/app/components/events/EventRegistrationView.tsx +0 -178
  101. package/skills/wix-headless-fast/references/events/app/components/events/EventsView.tsx +0 -118
  102. package/skills/wix-headless-fast/references/events/app/hooks/events/useEventRegistration.ts +0 -35
  103. package/skills/wix-headless-fast/references/events/app/hooks/events/useEvents.ts +0 -24
  104. package/skills/wix-headless-fast/references/events/app/wix/events/events-core.ts +0 -130
  105. package/skills/wix-headless-fast/references/events/app/wix/events/events-store.ts +0 -97
  106. package/skills/wix-headless-fast/references/events/app/wix/events/events.ts +0 -55
  107. package/skills/wix-headless-fast/references/events/app/wix/events/registration-core.ts +0 -113
  108. package/skills/wix-headless-fast/references/events/app/wix/events/registration-store.ts +0 -156
  109. package/skills/wix-headless-fast/references/events/app/wix/events/registration.ts +0 -97
  110. package/skills/wix-headless-fast/references/events/app/wix/events/types.ts +0 -61
  111. package/skills/wix-headless-fast/references/events/app-astro/layouts/SiteLayout.astro +0 -40
  112. package/skills/wix-headless-fast/references/events/app-astro/pages/event-confirmation.astro +0 -12
  113. package/skills/wix-headless-fast/references/events/app-astro/pages/events/[slug].astro +0 -80
  114. package/skills/wix-headless-fast/references/events/app-astro/pages/events.astro +0 -21
  115. package/skills/wix-headless-fast/references/events/lock/astro/package-lock.json +0 -11884
  116. package/skills/wix-headless-fast/references/events/rest/events.ts +0 -57
  117. package/skills/wix-headless-fast/references/events/rest/registration.ts +0 -83
  118. package/skills/wix-headless-fast/references/events/seed/SEED.md +0 -95
  119. package/skills/wix-headless-fast/references/events/seed/read-site.mjs +0 -26
  120. package/skills/wix-headless-fast/references/events/seed/seed-events.mjs +0 -276
  121. package/skills/wix-headless-fast/references/forms/INSTRUCTIONS.md +0 -340
  122. package/skills/wix-headless-fast/references/forms/app/hooks/forms/useWixForm.ts +0 -85
  123. package/skills/wix-headless-fast/references/forms/app/wix/forms/form-store.ts +0 -332
  124. package/skills/wix-headless-fast/references/forms/app/wix/forms/forms-core.ts +0 -238
  125. package/skills/wix-headless-fast/references/forms/app/wix/forms/forms.ts +0 -54
  126. package/skills/wix-headless-fast/references/forms/app/wix/forms/submissions-core.ts +0 -216
  127. package/skills/wix-headless-fast/references/forms/app/wix/forms/submissions.ts +0 -59
  128. package/skills/wix-headless-fast/references/forms/app/wix/forms/types.ts +0 -135
  129. package/skills/wix-headless-fast/references/forms/lock/astro/package-lock.json +0 -10593
  130. package/skills/wix-headless-fast/references/forms/rest/forms.ts +0 -34
  131. package/skills/wix-headless-fast/references/forms/rest/submissions.ts +0 -56
  132. package/skills/wix-headless-fast/references/forms/seed/SEED.md +0 -116
  133. package/skills/wix-headless-fast/references/forms/seed/read-site.mjs +0 -20
  134. package/skills/wix-headless-fast/references/forms/seed/seed-forms.mjs +0 -327
  135. package/skills/wix-headless-fast/references/members/INSTRUCTIONS.md +0 -316
  136. package/skills/wix-headless-fast/references/members/app/components/members/AccountView.tsx +0 -60
  137. package/skills/wix-headless-fast/references/members/app/components/members/LoginForm.tsx +0 -155
  138. package/skills/wix-headless-fast/references/members/app/components/members/MemberMenu.tsx +0 -78
  139. package/skills/wix-headless-fast/references/members/app/components/members/RequireAuth.tsx +0 -47
  140. package/skills/wix-headless-fast/references/members/app/hooks/members/useMember.ts +0 -66
  141. package/skills/wix-headless-fast/references/members/app/wix/members/auth-core.ts +0 -105
  142. package/skills/wix-headless-fast/references/members/app/wix/members/auth.ts +0 -59
  143. package/skills/wix-headless-fast/references/members/app/wix/members/client.ts +0 -53
  144. package/skills/wix-headless-fast/references/members/app/wix/members/member-store.ts +0 -122
  145. package/skills/wix-headless-fast/references/members/app/wix/members/members-core.ts +0 -43
  146. package/skills/wix-headless-fast/references/members/app/wix/members/members.ts +0 -29
  147. package/skills/wix-headless-fast/references/members/app/wix/members/types.ts +0 -21
  148. package/skills/wix-headless-fast/references/members/app-astro/layouts/SiteLayout.astro +0 -42
  149. package/skills/wix-headless-fast/references/members/app-astro/pages/account.astro +0 -10
  150. package/skills/wix-headless-fast/references/members/app-astro/pages/login.astro +0 -11
  151. package/skills/wix-headless-fast/references/members/lock/astro/package-lock.json +0 -10329
  152. package/skills/wix-headless-fast/references/members/rest/auth.ts +0 -215
  153. package/skills/wix-headless-fast/references/members/rest/members.ts +0 -26
  154. package/skills/wix-headless-fast/references/members/seed/SEED.md +0 -39
  155. package/skills/wix-headless-fast/references/members/seed/read-site.mjs +0 -15
  156. package/skills/wix-headless-fast/references/members/seed/seed-members.mjs +0 -94
  157. package/skills/wix-headless-fast/references/portfolio/INSTRUCTIONS.md +0 -315
  158. package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/CollectionProjectsView.tsx +0 -110
  159. package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/CollectionsView.tsx +0 -90
  160. package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/GalleryMedia.tsx +0 -35
  161. package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/ProjectDetailView.tsx +0 -85
  162. package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useCollectionProjects.ts +0 -32
  163. package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useCollections.ts +0 -21
  164. package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useProjectDetail.ts +0 -31
  165. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/collection-projects-store.ts +0 -82
  166. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/collections-store.ts +0 -58
  167. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/portfolio-core.ts +0 -177
  168. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/portfolio.ts +0 -78
  169. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/project-detail-store.ts +0 -81
  170. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/types.ts +0 -55
  171. package/skills/wix-headless-fast/references/portfolio/app-astro/layouts/SiteLayout.astro +0 -40
  172. package/skills/wix-headless-fast/references/portfolio/app-astro/pages/portfolio/[slug].astro +0 -30
  173. package/skills/wix-headless-fast/references/portfolio/app-astro/pages/portfolio.astro +0 -21
  174. package/skills/wix-headless-fast/references/portfolio/app-astro/pages/projects/[slug].astro +0 -29
  175. package/skills/wix-headless-fast/references/portfolio/lock/astro/package-lock.json +0 -10197
  176. package/skills/wix-headless-fast/references/portfolio/rest/portfolio.ts +0 -75
  177. package/skills/wix-headless-fast/references/portfolio/seed/SEED.md +0 -86
  178. package/skills/wix-headless-fast/references/portfolio/seed/read-site.mjs +0 -20
  179. package/skills/wix-headless-fast/references/portfolio/seed/seed-portfolio.mjs +0 -256
  180. package/skills/wix-headless-fast/references/pricing-plans/INSTRUCTIONS.md +0 -296
  181. package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/PlanDetailView.tsx +0 -47
  182. package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/PlansView.tsx +0 -101
  183. package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/SubscribeButton.tsx +0 -41
  184. package/skills/wix-headless-fast/references/pricing-plans/app/hooks/pricing-plans/usePlanPurchase.ts +0 -16
  185. package/skills/wix-headless-fast/references/pricing-plans/app/hooks/pricing-plans/usePlans.ts +0 -22
  186. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plan-purchase-store.ts +0 -54
  187. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plans-core.ts +0 -106
  188. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plans-store.ts +0 -64
  189. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plans.ts +0 -27
  190. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/purchase-core.ts +0 -43
  191. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/purchase.ts +0 -22
  192. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/types.ts +0 -30
  193. package/skills/wix-headless-fast/references/pricing-plans/app-astro/layouts/SiteLayout.astro +0 -41
  194. package/skills/wix-headless-fast/references/pricing-plans/app-astro/pages/plans/[slug].astro +0 -40
  195. package/skills/wix-headless-fast/references/pricing-plans/app-astro/pages/plans.astro +0 -21
  196. package/skills/wix-headless-fast/references/pricing-plans/lock/astro/package-lock.json +0 -11226
  197. package/skills/wix-headless-fast/references/pricing-plans/rest/plans.ts +0 -31
  198. package/skills/wix-headless-fast/references/pricing-plans/rest/purchase.ts +0 -20
  199. package/skills/wix-headless-fast/references/pricing-plans/seed/SEED.md +0 -79
  200. package/skills/wix-headless-fast/references/pricing-plans/seed/read-site.mjs +0 -21
  201. package/skills/wix-headless-fast/references/pricing-plans/seed/seed-pricing-plans.mjs +0 -279
  202. package/skills/wix-headless-fast/references/restaurants/INSTRUCTIONS.md +0 -360
  203. package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/MenuView.tsx +0 -142
  204. package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/OrderCartButton.tsx +0 -26
  205. package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/OrderCartDrawer.tsx +0 -121
  206. package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/ReservationView.tsx +0 -155
  207. package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useMenus.ts +0 -34
  208. package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useOrderCart.ts +0 -43
  209. package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useReservation.ts +0 -34
  210. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/menu-core.ts +0 -155
  211. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/menu-store.ts +0 -89
  212. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/menu.ts +0 -71
  213. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/order-store.ts +0 -103
  214. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/ordering-core.ts +0 -124
  215. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/ordering.ts +0 -185
  216. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/reservation-store.ts +0 -193
  217. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/reservations-core.ts +0 -94
  218. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/reservations.ts +0 -74
  219. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/types.ts +0 -168
  220. package/skills/wix-headless-fast/references/restaurants/app-astro/layouts/SiteLayout.astro +0 -47
  221. package/skills/wix-headless-fast/references/restaurants/app-astro/pages/menu.astro +0 -22
  222. package/skills/wix-headless-fast/references/restaurants/app-astro/pages/reservations.astro +0 -12
  223. package/skills/wix-headless-fast/references/restaurants/lock/astro/package-lock.json +0 -12560
  224. package/skills/wix-headless-fast/references/restaurants/rest/menu.ts +0 -60
  225. package/skills/wix-headless-fast/references/restaurants/rest/ordering.ts +0 -169
  226. package/skills/wix-headless-fast/references/restaurants/rest/reservations.ts +0 -68
  227. package/skills/wix-headless-fast/references/restaurants/seed/SEED.md +0 -89
  228. package/skills/wix-headless-fast/references/restaurants/seed/read-site.mjs +0 -25
  229. package/skills/wix-headless-fast/references/restaurants/seed/seed-restaurants.mjs +0 -499
  230. package/skills/wix-headless-fast/references/shared/CONTENT.md +0 -22
  231. package/skills/wix-headless-fast/references/shared/CUSTOM_OPERATIONS.md +0 -73
  232. package/skills/wix-headless-fast/references/shared/DESIGN.md +0 -26
  233. package/skills/wix-headless-fast/references/shared/SUPPLIED-CONTENT.md +0 -23
  234. package/skills/wix-headless-fast/references/shared/app/styles/global.css +0 -52
  235. package/skills/wix-headless-fast/references/shared/app/wix/config.ts +0 -15
  236. package/skills/wix-headless-fast/references/shared/app/wix/media.ts +0 -81
  237. package/skills/wix-headless-fast/references/shared/app/wix/money.ts +0 -24
  238. package/skills/wix-headless-fast/references/shared/app/wix/sdk.ts +0 -89
  239. package/skills/wix-headless-fast/references/shared/capabilities/media-upload/app/wix/media-upload/client.ts +0 -46
  240. package/skills/wix-headless-fast/references/shared/capabilities/media-upload/app-astro/pages/api/wix/media-upload.ts +0 -46
  241. package/skills/wix-headless-fast/references/shared/rest/client.ts +0 -155
  242. package/skills/wix-headless-fast/references/shared/rest/config.ts +0 -3
  243. package/skills/wix-headless-fast/references/shared/rest/media.ts +0 -65
  244. package/skills/wix-headless-fast/references/shared/seed/images.mjs +0 -145
  245. package/skills/wix-headless-fast/references/shared/seed/read-site.mjs +0 -99
  246. package/skills/wix-headless-fast/references/storefront/INSTRUCTIONS.md +0 -612
  247. package/skills/wix-headless-fast/references/storefront/app/components/storefront/CartButton.tsx +0 -26
  248. package/skills/wix-headless-fast/references/storefront/app/components/storefront/CartDrawer.tsx +0 -155
  249. package/skills/wix-headless-fast/references/storefront/app/components/storefront/FilterPanel.tsx +0 -266
  250. package/skills/wix-headless-fast/references/storefront/app/components/storefront/OptionPicker.tsx +0 -95
  251. package/skills/wix-headless-fast/references/storefront/app/components/storefront/QuickAdd.tsx +0 -136
  252. package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useCart.ts +0 -48
  253. package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useProductDetail.ts +0 -39
  254. package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useShop.ts +0 -34
  255. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart-core.ts +0 -121
  256. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart-store.ts +0 -107
  257. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart.ts +0 -138
  258. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/catalog-core.ts +0 -314
  259. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/catalog.ts +0 -133
  260. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/product-detail-store.ts +0 -147
  261. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/shop-store.ts +0 -289
  262. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/types.ts +0 -169
  263. package/skills/wix-headless-fast/references/storefront/app-astro/layouts/SiteLayout.astro +0 -65
  264. package/skills/wix-headless-fast/references/storefront/lock/astro/package-lock.json +0 -12247
  265. package/skills/wix-headless-fast/references/storefront/rest/cart.ts +0 -132
  266. package/skills/wix-headless-fast/references/storefront/rest/catalog.ts +0 -123
  267. package/skills/wix-headless-fast/references/storefront/seed/SEED.md +0 -130
  268. package/skills/wix-headless-fast/references/storefront/seed/read-site.mjs +0 -38
  269. package/skills/wix-headless-fast/references/storefront/seed/seed-store.mjs +0 -561
@@ -7,10 +7,16 @@
7
7
  //
8
8
  // - `wix.config.json` present → refuses. The folder is already a Wix project; deploy.mjs adds
9
9
  // this skill's code or a solution to it, then one install, then the seed if there is content.
10
+ // One exception: a config and NO project whose `.env.local` (`wix env pull`, run here) declares a
11
+ // MIGRATION PREVIEW — the config names a site created only to host the deployment, the env names
12
+ // the site being migrated. Then → MIGRATE: the composed template is copied in around the config,
13
+ // the code deploys with the parent's app as its client, the install starts, and NO seed runs: the
14
+ // parent owns its content. Release still goes where the config says (install/context.mjs).
10
15
  // - a project but no `wix.config.json` (a package.json, or an index.html at the root) → CONNECT:
11
16
  // `npm create @wix/new@latest init` in place creates the site and the config, then deploy.
12
- // - otherwise (empty, or loose files such as a CSV or a brief) → CREATE: scaffold the Wix CLI's
13
- // Astro template and place it in the current directory (`--business-name` required).
17
+ // - otherwise (empty, or loose files such as a CSV or a brief) → CREATE: `wix create` with the
18
+ // vertical's composed template (templates/<vertical>/project: the CLI's blank scaffold with the
19
+ // vertical deployed and a lockfile), placed in the current directory (`--business-name` required).
14
20
  //
15
21
  // The script reads file markers only (wix.config.json, a package.json or index.html); everything
16
22
  // else is the agent's call: when connecting, `--stack` is required and comes from SKILL.md step 1,
@@ -22,10 +28,12 @@
22
28
  // steps — the dependency install and the seed — running detached in the background (logs and
23
29
  // completion markers in the final event), so the caller can build the brand layer while they finish.
24
30
  import { spawn, spawnSync } from "node:child_process";
25
- import { existsSync, openSync, readFileSync, readdirSync, renameSync, rmSync } from "node:fs";
31
+ import { cpSync, existsSync, openSync, readFileSync, readdirSync, renameSync, rmSync, writeFileSync } from "node:fs";
26
32
  import { basename, dirname, join, resolve } from "node:path";
27
33
  import { fileURLToPath } from "node:url";
28
34
  import { AGENT_CONFIG_FILES, writeAgentsMd } from "./agents-md.mjs";
35
+ import { listVerticals, templatesDir } from "./templates.mjs";
36
+ import { siteContext } from "./context.mjs";
29
37
 
30
38
  const SKILL_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..");
31
39
 
@@ -47,9 +55,10 @@ const vertical = flag("vertical");
47
55
  const stackFlag = flag("stack");
48
56
  // Opt-in: keep a CREATE's project in a subfolder instead of the current directory.
49
57
  const subfolder = argv.includes("--subfolder");
50
- const knownVerticals = readdirSync(join(SKILL_ROOT, "references"), { withFileTypes: true })
51
- .filter((d) => d.isDirectory() && d.name !== "shared" && existsSync(join(SKILL_ROOT, "references", d.name, "app")))
52
- .map((d) => d.name);
58
+ // The shipped code: the repository's templates/ (a checkout, the cache, or fetched now, in a second).
59
+ let TEMPLATES;
60
+ try { TEMPLATES = templatesDir(); } catch (e) { fail("templates", e.message); }
61
+ const knownVerticals = listVerticals(TEMPLATES);
53
62
  const usage = `usage: setup.mjs --vertical <${knownVerticals.join("|")}> [--plan plan.json] [--business-name "<Brand>"] [--stack astro|react|lib|static] [--subfolder]`;
54
63
  // --vertical is REQUIRED: a defaulted vertical deploys the wrong code and runs the wrong seed.
55
64
  if (!vertical) fail("args", usage);
@@ -64,17 +73,23 @@ if (planPath && !existsSync(planPath)) fail("args", `plan file not found: ${plan
64
73
  // ---- 0 · read the folder --------------------------------------------------------------------------
65
74
  const cwd = process.cwd();
66
75
  const has = (p) => existsSync(join(cwd, p));
67
- if (has("wix.config.json")) {
68
- fail("place", "this folder is already a Wix project (wix.config.json): nothing to set up. deploy.mjs <vertical> adds this skill's code or a solution to it; then ONE npm install; then the vertical's seed module if there is content to create");
69
- }
70
76
  const pkg = has("package.json") ? JSON.parse(readFileSync(join(cwd, "package.json"), "utf8")) : null;
71
77
  const hasProject = !!pkg || has("index.html");
72
- const mode = hasProject ? "connect" : "create";
78
+ // A config here: refuse, unless it is a migration preview with no project yet (the site context
79
+ // pulls .env.local when missing — that is where the migration is declared).
80
+ let ctx = null;
81
+ if (has("wix.config.json")) {
82
+ ctx = siteContext({ cwd });
83
+ if (hasProject || !ctx.migration.active) {
84
+ fail("place", "this folder is already a Wix project (wix.config.json): nothing to set up. deploy.mjs <vertical> adds this skill's code or a solution to it; then ONE npm install; then the vertical's seed module if there is content to create. A config with no project is attach.mjs's case (SKILL.md step 3)" + (ctx.pullError ? ` — note: env pull failed here (${ctx.pullError.slice(0, 120)})` : ""));
85
+ }
86
+ }
87
+ const mode = ctx ? "migrate" : hasProject ? "connect" : "create";
73
88
  if (mode === "connect" && !stackFlag) {
74
89
  fail("args", "connecting a project on disk needs --stack astro|react|lib|static — the stack you resolved in SKILL.md step 1 for this project");
75
90
  }
76
91
  const stack = stackFlag ?? "astro";
77
- emit("folder", { mode, stack, project: hasProject ? (pkg?.name ?? basename(cwd)) : null });
92
+ emit("folder", { mode, stack, project: hasProject ? (pkg?.name ?? basename(cwd)) : null, ...(ctx ? { migration: ctx.migration, deploySiteId: ctx.deploy.siteId, warnings: ctx.warnings } : {}) });
78
93
 
79
94
  let projectDir = cwd;
80
95
  let folderName = null;
@@ -92,7 +107,13 @@ if (mode === "create") {
92
107
  if (existsSync(join(projectDir, "wix.config.json"))) {
93
108
  emit("scaffold_skipped", { reason: "project already exists", folder: folderName });
94
109
  } else {
95
- emit("scaffolding", { folder: folderName });
110
+ // The composed template: the CLI copies it in place of its blank one, creates the site and
111
+ // writes wix.config.json; the vertical's code and its lockfile arrive with it. Any other
112
+ // stack takes the CLI's blank Astro scaffold, as before, and deploy below adds the code.
113
+ // The composed project is the one part of the templates a project's repository does not keep;
114
+ // a committed copy fetches it here, at the commit the rest came from.
115
+ const template = stack === "astro" ? join(templatesDir({ need: `${vertical}/project` }), vertical, "project") : null;
116
+ emit("scaffolding", { folder: folderName, template });
96
117
  const scaffold = spawnSync(
97
118
  "npm",
98
119
  // --skip-git: this wrapper composes its own steps and leaves version control to
@@ -102,13 +123,33 @@ if (mode === "create") {
102
123
  // same reason: deps install in a detached step below.
103
124
  ["create", "@wix/new@latest", "--", "headless",
104
125
  "--folder-name", folderName, "--business-name", businessName,
105
- "--site-template", "--skip-install", "--skip-git", "--no-publish"],
126
+ "--site-template", "blank", ...(template ? ["--template-path", template] : []),
127
+ "--skip-install", "--skip-git", "--no-publish"],
106
128
  { env: { ...process.env, CI: "1" }, encoding: "utf8", timeout: 300_000 },
107
129
  );
108
130
  if (scaffold.status !== 0 || !existsSync(join(projectDir, "wix.config.json"))) {
109
131
  fail("scaffold", (scaffold.stderr || scaffold.stdout || "scaffold produced no wix.config.json — is the Wix CLI logged in? (npx @wix/cli@latest whoami)").slice(-600));
110
132
  }
111
133
  }
134
+ } else if (mode === "migrate") {
135
+ // ---- 1 · a migration preview: the config and credentials came with the folder -------------------
136
+ // No site is created and nothing is provisioned: `wix.config.json` already names the deploy site
137
+ // and its app, `.env.local` the parent's. Managed Astro gets the vertical's composed template copied
138
+ // in around them (what `wix create` would have copied; the config and env are never overwritten);
139
+ // any other stack is code-only and deploy below adds it.
140
+ if (planPath) emit("seed_skipped", { reason: `migration preview of site ${ctx.migration.parentSiteId}: the site owns its content and nothing is seeded — the plan is ignored` });
141
+ if (stack === "astro") {
142
+ const template = join(templatesDir({ need: `${vertical}/project` }), vertical, "project");
143
+ emit("scaffolding", { folder: cwd, template, from: "migration preview" });
144
+ cpSync(template, cwd, { recursive: true, force: false, errorOnExist: false });
145
+ const pkgPath = join(cwd, "package.json");
146
+ const scaffolded = JSON.parse(readFileSync(pkgPath, "utf8"));
147
+ scaffolded.name = basename(cwd).toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "") || "site";
148
+ writeFileSync(pkgPath, JSON.stringify(scaffolded, null, 2) + "\n");
149
+ }
150
+ const gi = join(cwd, ".gitignore");
151
+ const cur = existsSync(gi) ? readFileSync(gi, "utf8") : "";
152
+ if (!/\.env/.test(cur)) writeFileSync(gi, cur + "\n# local env (pulled from Wix)\n.env.local\n.env\n");
112
153
  } else {
113
154
  // ---- 1 · init in place --------------------------------------------------------------------------
114
155
  // The CLI's `init` links the folder to a NEW site: creates the site and its OAuth app, writes
@@ -123,12 +164,25 @@ if (mode === "create") {
123
164
  }
124
165
  const wixConfig = JSON.parse(readFileSync(join(projectDir, "wix.config.json"), "utf8"));
125
166
  const siteId = wixConfig.siteId ?? wixConfig.projectId;
126
- emit(mode === "create" ? "scaffolded" : "connected", { folder: folderName ?? cwd, siteId, stack });
167
+ // Static: `wix release` uploads the output folder whole, so the project root (config, plan, seed
168
+ // output, the skills) must not be it. The site lives in site/: the config points there and the REST
169
+ // layer deploys into it; the pages, styles and assets are the agent's to move (the `next` says so).
170
+ const STATIC_OUT = "site";
171
+ if (stack === "static") {
172
+ wixConfig.site = { ...(wixConfig.site ?? {}), outputDirectory: `./${STATIC_OUT}` };
173
+ writeFileSync(join(projectDir, "wix.config.json"), JSON.stringify(wixConfig, null, 2) + "\n");
174
+ }
175
+ emit(mode === "create" ? "scaffolded" : mode === "migrate" ? "migration_preview" : "connected", {
176
+ folder: folderName ?? cwd, stack,
177
+ ...(ctx ? { deploySiteId: ctx.deploy.siteId, contentSiteId: ctx.content.siteId } : { siteId }),
178
+ });
127
179
 
128
- // ---- 2 · deploy shipped code + deps + lockfile ---------------------------------------------------
180
+ // ---- 2 · deploy shipped code + deps ---------------------------------------------------------------
181
+ // A CREATE from the composed template already holds the code and the lock: deploy adds nothing and
182
+ // reports the project; a CONNECT gets the code and its dependencies here.
129
183
  const deploy = spawnSync(
130
184
  "node",
131
- [join(SKILL_ROOT, "install", "deploy.mjs"), vertical, "--stack", stack, ...(planPath ? ["--plan", resolve(planPath)] : [])],
185
+ [join(SKILL_ROOT, "install", "deploy.mjs"), vertical, "--stack", stack, ...(stack === "static" ? ["--out", STATIC_OUT] : []), ...(planPath ? ["--plan", resolve(planPath)] : [])],
132
186
  { cwd: projectDir, encoding: "utf8", timeout: 60_000 },
133
187
  );
134
188
  if (deploy.status !== 0) fail("deploy", deploy.stderr || deploy.stdout);
@@ -169,7 +223,7 @@ if (mode === "create" && !subfolder && projectDir !== cwd) {
169
223
  // ---- 2d · the agent config files `wix create` would have written --------------------------------
170
224
  // Skipped by the CLI because of --skip-install. Fill-only: a project that has its own AGENTS.md
171
225
  // keeps it (the event says `kept`).
172
- emit("agent_configs", writeAgentsMd(projectDir, { skill: basename(SKILL_ROOT), stack }));
226
+ emit("agent_configs", writeAgentsMd(projectDir, { skill: basename(SKILL_ROOT), stack, ...(ctx ? { migration: { parentSiteId: ctx.migration.parentSiteId, deploySiteId: ctx.deploy.siteId } } : {}) }));
173
227
 
174
228
  // ---- 3 · start the dependency install, detached --------------------------------------------------
175
229
  // ONE install, here, for any project with a package.json (deploy patched it). The static stack has
@@ -195,8 +249,8 @@ if (stack !== "static" && existsSync(join(projectDir, "package.json"))) {
195
249
  // result JSON + exit-code marker land as files the caller syncs on before release. Seeding is
196
250
  // additive: it never deletes or overwrites what the site holds.
197
251
  let seed = null;
198
- if (planPath) {
199
- const seedDir = join(SKILL_ROOT, "references", vertical, "seed");
252
+ if (planPath && mode !== "migrate") {
253
+ const seedDir = join(TEMPLATES, vertical, "seed");
200
254
  const seedName = existsSync(seedDir)
201
255
  ? readdirSync(seedDir).find((f) => f.startsWith("seed-") && f.endsWith(".mjs"))
202
256
  : undefined;
@@ -218,22 +272,28 @@ const release = {
218
272
  astro: "npx @wix/cli@latest build, then npx @wix/cli@latest release",
219
273
  react: "the project's own build, then npx @wix/cli@latest release of the build folder named in wix.config.json (what Wix hosting serves and how routes must be shaped: SKILL.md step 1)",
220
274
  lib: "the project's own build, then npx @wix/cli@latest release of the build folder named in wix.config.json (SKILL.md step 1)",
221
- static: "npx @wix/cli@latest release — no build; wix.config.json site.outputDirectory points at the folder the pages live in",
275
+ static: `npx @wix/cli@latest release — no build; it uploads ${STATIC_OUT}/ whole (wix.config.json site.outputDirectory), so the pages, styles and assets move into ${STATIC_OUT}/ first and import the modules from ./js/wix/ there; the root keeps the config, the plan, the seed output and the skills`,
222
276
  }[stack];
277
+ // On a migration preview the links and `siteId` are the PARENT's — the site whose content the pages
278
+ // show and whose dashboard manages it; `deploySiteId` is where `wix release` goes.
223
279
  emit("ready_for_brand_layer", {
224
280
  mode,
225
281
  stack,
226
282
  projectDir,
227
- siteId,
283
+ siteId: ctx ? ctx.content.siteId : siteId,
284
+ ...(ctx ? { deploySiteId: ctx.deploy.siteId, migration: { parentSiteId: ctx.migration.parentSiteId } } : {}),
228
285
  dashboardUrl: deployResult.dashboardUrl,
229
286
  productsUrl: deployResult.productsUrl,
230
287
  categoriesUrl: deployResult.categoriesUrl,
231
288
  install,
232
289
  seed,
233
290
  next:
234
- (planPath
291
+ (mode === "migrate"
292
+ ? "a migration preview: the site being migrated owns its content (read it with the vertical's read-site.mjs when the brief allows probing; never seed it); theme + write the home page; "
293
+ : planPath
235
294
  ? "theme + write the home page; "
236
295
  : "the site is new and empty — seed it (a plan per step 2, the vertical's seed module) or say so; theme + write the home page; ") +
237
296
  (install || seed ? "then wait for the done markers" + (seed ? ", verify .seed-exit is 0 (else read seed.log and re-run the seed module)" : "") + "; " : "") +
238
- `then ${release}`,
297
+ `then ${release}` +
298
+ (mode === "migrate" ? "; the release is the PREVIEW on the deploy site — close with its URL and the parent's dashboard, say the original site is unchanged and that completing the migration is the user's next step in the Wix CLI once they approve" : ""),
239
299
  });
@@ -0,0 +1,168 @@
1
+ // Where the shipped code is. The verticals live in the skill's repository under `templates/`
2
+ // (each with its code layers, its tools and a composed project with a lockfile), not in the skill
3
+ // folder: the skill stays small and the code is fetched once, when first needed.
4
+ //
5
+ // node <SKILL_ROOT>/install/templates.mjs [--refresh] # prints {templates, source, verticals}
6
+ //
7
+ // Resolution, in order:
8
+ // 1. a checkout of the repository itself (the skill folder sits in it): `<repo>/templates/`.
9
+ // 2. the cache `<SKILL_ROOT>/templates/`, filled by an earlier call (`--refresh` refetches).
10
+ // 3. a fetch: a sparse, shallow clone of `templates/` from the repository the skill was installed
11
+ // from (skills-lock.json's `source`, default wix/skills), at the branch or tag the install
12
+ // named (its `ref`, falling back to the default branch when that ref no longer exists) or the
13
+ // repository's default branch. The lock records no commit, so there is nothing more exact to
14
+ // pin to; `WIX_HEADLESS_FAST_TEMPLATES_REF=<branch|tag|sha>` overrides the ref.
15
+ // The cache stays with the project: its `.gitignore` leaves out only the composed `project/`
16
+ // folders (the scaffolds with their lockfiles, read once, at create or attach) and the repository
17
+ // tooling, so the code layers, playbooks, seeds and readers are committed at the commit the project
18
+ // was built from, recorded in `.source`. A caller that needs a `project/` folder passes it as
19
+ // `need`; when a committed copy lacks it, that part is fetched at the same commit.
20
+ import { cpSync, existsSync, mkdtempSync, mkdirSync, readdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
21
+ import { tmpdir } from "node:os";
22
+ import { dirname, join, resolve } from "node:path";
23
+ import { spawnSync } from "node:child_process";
24
+ import { fileURLToPath } from "node:url";
25
+
26
+ export const SKILL_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..");
27
+ export const DEFAULT_REPO = "https://github.com/wix/skills.git";
28
+
29
+ const git = (args, opts = {}) => spawnSync("git", args, { encoding: "utf8", timeout: 180_000, ...opts });
30
+
31
+ // The repository and ref the skill was installed from: the nearest skills-lock.json above the
32
+ // skill folder, its entry for this skill. "wix/skills" → the default branch of that repository;
33
+ // "https://github.com/owner/repo/tree/<ref>" → that ref.
34
+ export function installSource() {
35
+ const skill = SKILL_ROOT.split("/").pop();
36
+ let dir = SKILL_ROOT;
37
+ for (let i = 0; i < 6; i++) {
38
+ const p = join(dir, "skills-lock.json");
39
+ if (existsSync(p)) {
40
+ try {
41
+ const entry = JSON.parse(readFileSync(p, "utf8")).skills?.[skill];
42
+ if (typeof entry?.source === "string" && entry.source) {
43
+ const parsed = parseSource(entry.source);
44
+ // `ref` is the branch or tag the install named (skills-lock.json v1 keeps it beside `source`)
45
+ return { ...parsed, ref: parsed.ref ?? (typeof entry.ref === "string" && entry.ref ? entry.ref : null) };
46
+ }
47
+ } catch { /* fall through to the default */ }
48
+ break;
49
+ }
50
+ const up = dirname(dir);
51
+ if (up === dir) break;
52
+ dir = up;
53
+ }
54
+ return { repo: DEFAULT_REPO, ref: null };
55
+ }
56
+
57
+ function parseSource(src) {
58
+ const m = src.match(/^(?:https?:\/\/github\.com\/)?([^/\s]+)\/([^/\s#@]+?)(?:\.git)?(?:\/tree\/([^\s]+))?$/);
59
+ if (!m) return { repo: DEFAULT_REPO, ref: null };
60
+ return { repo: `https://github.com/${m[1]}/${m[2]}.git`, ref: m[3] ?? null };
61
+ }
62
+
63
+ export function listVerticals(dir) {
64
+ return readdirSync(dir, { withFileTypes: true })
65
+ .filter((d) => d.isDirectory() && d.name !== "shared" && d.name !== "blank" && existsSync(join(dir, d.name, "app")))
66
+ .map((d) => d.name)
67
+ .sort();
68
+ }
69
+
70
+ export function templatesDir({ refresh = false, need = null } = {}) {
71
+ const checkout = resolve(SKILL_ROOT, "..", "..", "templates");
72
+ if (existsSync(join(checkout, "shared", "app"))) return checkout;
73
+ const cache = join(SKILL_ROOT, "templates");
74
+ if (!refresh && existsSync(join(cache, "shared", "app"))) {
75
+ if (need && !existsSync(join(cache, need))) fetchIgnoredPart(cache, need);
76
+ return cache;
77
+ }
78
+ fetchTemplates(cache);
79
+ return cache;
80
+ }
81
+
82
+ // What a project's repository does not carry: the composed scaffolds (heavy, read once) and the
83
+ // repository's own tooling. Everything else in the cache is committed with the project.
84
+ const IGNORED = ["*/project/", "blank/", "compose.mjs"];
85
+
86
+ // A committed copy lacks the ignored parts. Fetch them at the commit the copy came from, so the
87
+ // scaffold a create copies matches the code committed beside it; the committed files are untouched.
88
+ function fetchIgnoredPart(cache, need) {
89
+ const src = templatesSource(cache);
90
+ const { repo } = installSource();
91
+ const r = cloneSparse(src.repo ?? repo, src.commit ?? process.env.WIX_HEADLESS_FAST_TEMPLATES_REF ?? null);
92
+ const tmp = r.tmp;
93
+ if (r.status !== 0 || !existsSync(join(tmp, "templates", need))) {
94
+ rmSync(tmp, { recursive: true, force: true });
95
+ throw new Error(`could not fetch templates/${need} from ${src.repo ?? repo}${src.commit ? ` @ ${src.commit.slice(0, 7)}` : ""}: ${(r.stderr || r.stdout || "not in the clone").trim().slice(-300)}`);
96
+ }
97
+ for (const part of ["blank", ...readdirSync(join(tmp, "templates"), { withFileTypes: true }).filter((d) => d.isDirectory() && existsSync(join(tmp, "templates", d.name, "project"))).map((d) => `${d.name}/project`)]) {
98
+ const from = join(tmp, "templates", part);
99
+ if (existsSync(from) && !existsSync(join(cache, part))) cpSync(from, join(cache, part), { recursive: true });
100
+ }
101
+ rmSync(tmp, { recursive: true, force: true });
102
+ }
103
+
104
+ export function templatesSource(dir) {
105
+ const p = join(dir, ".source");
106
+ if (existsSync(p)) { try { return JSON.parse(readFileSync(p, "utf8")); } catch { /* below */ } }
107
+ return { checkout: dir };
108
+ }
109
+
110
+ function fetchTemplates(cache) {
111
+ const { repo, ref: lockRef } = installSource();
112
+ const envRef = process.env.WIX_HEADLESS_FAST_TEMPLATES_REF || null;
113
+ let ref = envRef || lockRef || null;
114
+ let r = cloneSparse(repo, ref);
115
+ // The branch the skill was installed from can be gone by the time the code is first needed
116
+ // (merged and deleted). The lock's ref then falls back to the default branch; an explicit env
117
+ // ref does not.
118
+ let fellBack = false;
119
+ if (r.status !== 0 && ref && !envRef && /not found|couldn't find remote ref|unknown revision/i.test(r.stderr || "")) {
120
+ rmSync(r.tmp, { recursive: true, force: true });
121
+ fellBack = true; ref = null;
122
+ r = cloneSparse(repo, null);
123
+ }
124
+ const tmp = r.tmp;
125
+ if (r.error?.code === "ENOENT") {
126
+ rmSync(tmp, { recursive: true, force: true });
127
+ throw new Error("git is not installed or not on PATH; the shipped code is fetched with a git clone of the skill's repository");
128
+ }
129
+ if (r.status !== 0 || !existsSync(join(tmp, "templates", "shared", "app"))) {
130
+ rmSync(tmp, { recursive: true, force: true });
131
+ throw new Error(`could not fetch templates/ from ${repo}${ref ? ` @ ${ref}` : ""}: ${(r.stderr || r.stdout || "no templates/shared/app in the clone").trim().slice(-400)}`);
132
+ }
133
+ const commit = git(["-C", tmp, "rev-parse", "HEAD"]).stdout.trim();
134
+ rmSync(cache, { recursive: true, force: true });
135
+ mkdirSync(dirname(cache), { recursive: true });
136
+ try { renameSync(join(tmp, "templates"), cache); }
137
+ catch { cpSync(join(tmp, "templates"), cache, { recursive: true }); }
138
+ rmSync(tmp, { recursive: true, force: true });
139
+ writeFileSync(join(cache, ".gitignore"), IGNORED.join("\n") + "\n");
140
+ writeFileSync(join(cache, ".source"), JSON.stringify({ repo, ref: ref ?? (fellBack ? `default branch (${lockRef} not found)` : "default branch"), commit, fetchedAt: new Date().toISOString() }, null, 2) + "\n");
141
+ }
142
+
143
+ // A sparse, shallow clone of templates/ at a ref (branch, tag, or commit id) into a temp dir.
144
+ function cloneSparse(repo, ref) {
145
+ const tmp = mkdtempSync(join(tmpdir(), "wix-headless-fast-templates-"));
146
+ let r;
147
+ if (ref && /^[0-9a-f]{40}$/i.test(ref)) {
148
+ // a commit: shallow-fetch just it (GitHub serves any reachable commit by id)
149
+ for (const args of [["init", "-q", tmp], ["-C", tmp, "remote", "add", "origin", repo], ["-C", tmp, "fetch", "-q", "--depth", "1", "--filter=blob:none", "origin", ref], ["-C", tmp, "sparse-checkout", "set", "templates"], ["-C", tmp, "checkout", "-q", "FETCH_HEAD"]]) {
150
+ r = git(args);
151
+ if (r.status !== 0) break;
152
+ }
153
+ } else {
154
+ r = git(["clone", "--quiet", "--depth", "1", "--filter=blob:none", "--sparse", ...(ref ? ["-b", ref] : []), repo, tmp]);
155
+ if (r.status === 0) r = git(["-C", tmp, "sparse-checkout", "set", "templates"]);
156
+ }
157
+ return { ...r, tmp };
158
+ }
159
+
160
+ if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
161
+ try {
162
+ const dir = templatesDir({ refresh: process.argv.includes("--refresh") });
163
+ console.log(JSON.stringify({ templates: dir, source: templatesSource(dir), verticals: listVerticals(dir) }));
164
+ } catch (e) {
165
+ console.log(JSON.stringify({ error: e.message }));
166
+ process.exit(1);
167
+ }
168
+ }
@@ -163,7 +163,7 @@ Create and modify CMS collection structures. Covers listing collections, creatin
163
163
  Deletes multiple contacts using filter-based bulk delete. Covers safe deletion patterns, GDPR compliance, soft delete alternatives, and batch processing strategies.
164
164
 
165
165
  ### [Bulk Label and Unlabel Contacts](references/contacts/bulk-label-and-unlabel-contacts.md)
166
- Adds/removes labels from multiple contacts using Contacts API bulk operations. Covers label creation, contact filtering, batch processing, and rate limit handling.
166
+ Creates contact label definitions or adds/removes labels from matching contacts. Use Find or Create Label for label creation alone; use bulk labeling only when the user requests contact assignments.
167
167
 
168
168
  ### [Create a Contact](references/contacts/create-a-contact.md)
169
169
  Creates a contact with the Contacts API. Covers the minimum identifying fields, the single-object shape of `email` and `phone`, and adding a physical address with the ISO 3166-2 subdivision format required for state, region, and province codes.
@@ -211,7 +211,7 @@ Buy a domain through Wix or connect one the user already owns — intent, availa
211
211
  **Entry point for all eCommerce recommendation requests.** Unified skill that analyzes site data across ALL domains (discounts + shipping + gift cards), generates up to 5 cross-domain recommendations, and persists them to the tracking database. Covers discount strategies (seasonal, upsell, stock mover, bundling), shipping optimization (coverage gaps, free shipping, rate strategy, carrier backup), AND selling gift cards (denominations sized from the site's own AOV and catalog prices). Use this for business improvement requests about earning more from existing visitors. **Traffic acquisition (SEO, ads, social, content) is out of scope** — route "grow my traffic" to marketing.
212
212
 
213
213
  ### [Pricing & Promotions](references/ecommerce/ecom-pricing.md)
214
- **Dispatcher** — routes coupon/discount/sale/ribbon/bundle requests to the right leaf recipe (create coupon, create discount rule, troubleshoot discount-not-applying), and routes strategic "run a sale / boost sales" requests to `recommend-ecommerce-strategy`.
214
+ Routes discounts, coupons, sales and bundles to promotion recipes, and visual product ribbons to the Catalog Ribbons API. Load this dispatcher for mixed pricing/refund/payment/product-price/shipping requests to choose the appropriate APIs.
215
215
 
216
216
  ### [Shipping](references/ecommerce/ecom-shipping.md)
217
217
  **Dispatcher** — routes shipping-setup requests (rates, regions, pickup, free shipping, fix coverage, optimize rates) to the right leaf recipe. The Shipping Options + Delivery Profiles APIs have no public docs page; `ecom-shipping-api.md` is the authoritative inline reference.
@@ -422,7 +422,7 @@ List, count, and find the sites in a Wix account. Covers the namespace filter fo
422
422
  Probe a Wix site or account for full context in one call — installed apps by display name, locale, currency, timezone, and status. Account token + siteId targets one site; account token alone returns up to 10; site-scoped token alone returns the site it is scoped to.
423
423
 
424
424
  ### [Site Import](references/sites/site-import.md)
425
- Drive the Wix Site Import agent to migrate an existing store or site from another platform (Shopify, WooCommerce, Magento, or any URL) into Wix, or to import from CSV/TSV export files with no source site. Use this skill whenever the user wants to import, migrate, or clone a store/site into Wix, mentions moving off Shopify/WooCommerce/Magento, or gives a source store URL and asks to bring it into Wix. Covers starting the import, polling progress, answering the agent's mid-import questions, handling deploy/failure/auth-expiry states, and sending post-deploy follow-up changes.
425
+ Drive the Wix Site Import agent to migrate an existing store or site from another platform (Shopify, WooCommerce, Magento, or any URL) into Wix — as a brand-new site or into the user's existing one — or to import from CSV/TSV export files with no source site. Use this skill whenever the user wants to import, migrate, or clone a store/site into Wix, mentions moving off Shopify/WooCommerce/Magento, or gives a source store URL and asks to bring it into Wix. Covers starting the import, polling progress, answering the agent's mid-import questions, handling deploy/failure/auth-expiry states, and sending post-deploy follow-up changes.
426
426
 
427
427
  ### [Sites Dashboard Navigation](references/sites/sites-dashboard-navigation.md)
428
428
  "Builds direct links to the account-level sites pages on manage.wix.com — the My Sites list (all sites in the account) and each site's own dashboard. Pairs the site list with the Query Sites read API. Use when the user asks where something is in the Wix dashboard, wants a direct link to a dashboard page, or you need a dashboard URL to include with the result of an API operation."
@@ -107,15 +107,81 @@ Some common apps:
107
107
  - NEVER guess the `appDefId`. For Wix-built apps, use the table above. For any other app, resolve the ID using Step 0 (Search Market Listings).
108
108
  - The `tenantType` MUST be `SITE`
109
109
  - The `id` in tenant is the site's metaSiteId
110
+ - The endpoint, request body, and appDefId table above are complete and canonical for a listed Wix-built app — don't re-verify them with a separate REST/API doc search first; that's a redundant round-trip.
111
+ - Don't spend a call checking whether the app is already installed before installing it. If the task or the error you're handling already tells you it isn't installed (e.g. a fresh site, or a `*_NOT_INSTALLED` error), just call install directly.
110
112
 
111
113
  ---
112
114
 
113
115
  ## Error Handling
114
116
 
115
117
  ### App Not Installed Error
116
- If you receive an error indicating a required app is not installed, use this recipe to install it before proceeding.
118
+ If you receive an error indicating a required app is not installed (e.g. a `428` or a `*_NOT_INSTALLED` error code), install the app it names using its appDefId, then retry the call that failed. If the user's own request already implies this app is needed — i.e. doing what they asked requires a feature only that app provides — just install it as part of doing that task; don't stop to ask permission or name the app first. Confirm first only when the app isn't implied by anything the user asked for.
119
+
120
+ **Example** (install the missing app, then retry the call that surfaced the error — all in one script):
121
+ ```javascript
122
+ async function() {
123
+ const siteId = "<SITE_ID>";
124
+
125
+ await wix.request({
126
+ method: "POST",
127
+ url: "https://www.wixapis.com/apps-installer-service/v1/app-instance/install",
128
+ body: {
129
+ tenant: { tenantType: "SITE", id: siteId },
130
+ appInstance: { appDefId: "<APP_DEF_ID>" }
131
+ }
132
+ });
133
+
134
+ return await wix.request({
135
+ method: "<METHOD>",
136
+ url: "<ORIGINAL_URL_THAT_FAILED>",
137
+ body: { /* original request body */ }
138
+ });
139
+ }
140
+ ```
141
+
142
+ ### App-Dependent Call Fails Right After Install (Propagation Delay)
143
+ Installing an app and then immediately calling one of its own APIs — e.g. calling Set Multilingual Mode right after installing Wix Multilingual — can race the platform's install propagation, surfacing as a not-found error on the dependent call even though the install itself already succeeded.
144
+
145
+ **Example** (retry with backoff past the propagation delay instead of surfacing the error, all in one script):
146
+ ```javascript
147
+ async function() {
148
+ const siteId = "<SITE_ID>";
149
+
150
+ async function requestWithRetry(requestOptions, delaysMs = [1000, 2000, 4000]) {
151
+ let lastError;
152
+ try {
153
+ return await wix.request(requestOptions);
154
+ } catch (err) {
155
+ lastError = err;
156
+ }
157
+ for (const delayMs of delaysMs) {
158
+ await new Promise(resolve => setTimeout(resolve, delayMs));
159
+ try {
160
+ return await wix.request(requestOptions);
161
+ } catch (err) {
162
+ lastError = err;
163
+ }
164
+ }
165
+ throw lastError;
166
+ }
117
167
 
118
- If Locale Settings or Locales APIs return `428 MULTILINGUAL_NOT_INSTALLED`, install **Wix Multilingual** using appDefId `14d84998-ae09-1abf-c6fc-3f3cace5bf19`, then retry enabling multilingual mode or creating locales. Confirm with the user before installing unless they already explicitly asked you to install Wix Multilingual.
168
+ await wix.request({
169
+ method: "POST",
170
+ url: "https://www.wixapis.com/apps-installer-service/v1/app-instance/install",
171
+ body: {
172
+ tenant: { tenantType: "SITE", id: siteId },
173
+ appInstance: { appDefId: "14d84998-ae09-1abf-c6fc-3f3cace5bf19" }
174
+ }
175
+ });
176
+
177
+ return await requestWithRetry({
178
+ method: "POST",
179
+ url: "https://www.wixapis.com/locale-settings/v2/settings/mode",
180
+ body: { multilingualModeEnabled: true }
181
+ });
182
+ }
183
+ ```
184
+ Chain any further calls inside this same function through the same `requestWithRetry` helper, after the first one succeeds.
119
185
 
120
186
  ---
121
187
 
@@ -1,12 +1,29 @@
1
1
  ---
2
2
  name: "Bulk Label and Unlabel Contacts"
3
- description: Adds/removes labels from multiple contacts using Contacts API bulk operations. Covers label creation, contact filtering, batch processing, and rate limit handling.
3
+ description: Creates contact label definitions or adds/removes labels from matching contacts. Use Find or Create Label for label creation alone; use bulk labeling only when the user requests contact assignments.
4
4
  ---
5
5
  # Bulk Label And Unlabel Contacts
6
6
 
7
7
  ## Description
8
8
  Adds and removes labels from multiple contacts using the Wix Contacts REST API.
9
9
 
10
+ ## Create labels or assign labels?
11
+
12
+ If the user asks to **create a label** (for example, "Create VIP, Wholesale, and Newsletter labels"), use [Find or Create Label](https://dev.wix.com/docs/api-reference/crm/members-contacts/contacts/labels/find-or-create-label) directly. Creating a label definition does not require finding contacts or starting a bulk labeling job.
13
+
14
+ ```http
15
+ POST https://www.wixapis.com/contacts/v4/labels
16
+ Content-Type: application/json
17
+
18
+ {"displayName":"VIP"}
19
+ ```
20
+
21
+ Use the returned `label` and its `key`; `newLabel` distinguishes a newly created label from an existing one. For several names, make one call per name and check each result. Stop here when the request is only to create labels: do not assign them to contacts.
22
+
23
+ If the user asks to **label or unlabel contacts**, resolve the requested label keys first, then follow the bulk assignment flow below. Create a missing label only when that is part of the authorized request. An explicit request to create labels or apply them to a specified set of contacts authorizes that operation; otherwise confirm the target and intended change before mutating.
24
+
25
+ ## Bulk assignment flow
26
+
10
27
  Labels are added to and removed from all contacts that meet the specified `filter` and `search` criteria.
11
28
  The request should specify a `filter` value, a `search` value, or both.
12
29
  To perform a dry run, call [Query Contacts](https://dev.wix.com/docs/api-reference/crm/members-contacts/contacts/contacts/contact-v4/query-contacts) with the intended filter options.
@@ -17,6 +34,22 @@ The job's status can be retrieved with [Get Bulk Job](https://dev.wix.com/docs/a
17
34
 
18
35
  **IMPORTANT NOTE:** When specific contacts are to be labeled, they should be filtered by id.
19
36
 
37
+ ### Steps
38
+
39
+ 1. **Resolve label keys.** When adding, Find or Create Label (above) returns the `key`. To remove a label, or to
40
+ use only a label that already exists, look it up by name instead of creating it:
41
+ `POST https://www.wixapis.com/contacts/v4/labels/query` with
42
+ `{"query":{"filter":{"displayName":{"$eq":"Newsletter"}}}}`, and take each returned label's `key`.
43
+ 2. **Resolve named contacts to IDs** with Search Contacts, as in
44
+ [Update a Contact](update-a-contact.md) — Query Contacts cannot filter on a name:
45
+ `POST https://www.wixapis.com/contacts/v5/contacts/search` with `{"search":{"search":{"expression":"Leo Marsh"}}}`.
46
+ Each result in `contacts` has an `id` and `name.first` / `name.last`; keep only exact name matches. If none or
47
+ more than one contact matches, stop and ask the user.
48
+ 3. **Start the job** with the endpoint below, filtering by the resolved IDs:
49
+ `{"filter":{"id":{"$in":["<CONTACT_ID>"]}},"labelKeysToAdd":["<LABEL_KEY>"]}` (or `labelKeysToRemove`).
50
+ 4. **Confirm the job finished** with `GET https://www.wixapis.com/contacts/v4/bulk/jobs/{jobId}`; repeat until
51
+ `job.status` is `COMPLETED`, then report `job.successTotal` and `job.failedTotal`.
52
+
20
53
  ## API Endpoint
21
54
  `POST https://www.wixapis.com/contacts/v4/bulk/contacts/add-remove-labels`
22
55
 
@@ -29,10 +62,10 @@ curl -X POST \
29
62
  -H 'Content-Type: application/json' \
30
63
  -d '{
31
64
  "filter": {
32
- "info.name.first": "John"
65
+ "id": { "$in": ["<CONTACT_ID_1>", "<CONTACT_ID_2>"] }
33
66
  },
34
- "labelKeysToAdd": ["custom.name-john", "custom.name-starts-with-J"],
35
- "labelKeysToRemove": ["custom.last-name-smith"]
67
+ "labelKeysToAdd": ["custom.newsletter"],
68
+ "labelKeysToRemove": ["custom.prospect"]
36
69
  }'
37
70
  ```
38
71
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: "Pricing & Promotions"
3
- description: Pricing & Promotions boundary owner — discounts, coupons, sales, ribbons, bundles. **Always load this dispatcher first when a question touches both discount work and refunds, payments, product-price edits, or shipping rates** — the rules for which side owns each topic live in this file, not in this README line.
3
+ description: Routes discounts, coupons, sales and bundles to promotion recipes, and visual product ribbons to the Catalog Ribbons API. Load this dispatcher for mixed pricing/refund/payment/product-price/shipping requests to choose the appropriate APIs.
4
4
  ---
5
5
 
6
6
  # Pricing & Promotions
@@ -14,7 +14,9 @@ Discount rules, coupon codes, sales, ribbons, bundles, tiered pricing, and the s
14
14
  - A standing $0 shipping option/region rate → see **Shipping & fulfillment**.
15
15
  - Refunding a previous discounted order → route to verified Get Paid/payment docs or Dashboard guidance.
16
16
 
17
- > **Before dispatching** — confirm MerchantContext is loaded. If `siteData.country` is not in your conversation context, load it via [Load Merchant Context](https://dev.wix.com/docs/api-reference/business-solutions/e-commerce/skills/e-commerce-load-context). Skip if already loaded.
17
+ > **Ribbon-only requests** — go directly to the ribbon path below; skip MerchantContext and promotion-strategy discovery.
18
+ >
19
+ > **Before dispatching promotion requests** — confirm MerchantContext is loaded. If `siteData.country` is not in your conversation context, load it via [Load Merchant Context](https://dev.wix.com/docs/api-reference/business-solutions/e-commerce/skills/e-commerce-load-context). Skip if already loaded.
18
20
  >
19
21
  > **Promotion dispatch.** Score each entry below by (a) the merchant's query → `intent:*` tags, (b) MerchantContext → context tags. Load the **highest-scoring** entry. Ties → highest `priority`. No match → follow the base recipe at the bottom.
20
22
  >
@@ -24,9 +26,33 @@ Discount rules, coupon codes, sales, ribbons, bundles, tiered pricing, and the s
24
26
 
25
27
  > - [Create coupon](https://dev.wix.com/docs/api-reference/business-solutions/e-commerce/skills/pricing-create-coupon) — tags: `[intent:create-coupon]` · priority 0
26
28
  > - [Create discount rule (auto-apply)](https://dev.wix.com/docs/api-reference/business-solutions/e-commerce/skills/pricing-create-discount-rule) — tags: `[intent:create-discount-rule]` · priority 0
27
- > - [Add sale ribbon / new ribbon](https://dev.wix.com/docs/api-reference/business-solutions/e-commerce/skills/pricing-create-discount-rule) — tags: `[intent:add-ribbon]` · priority 0 · *ribbons are configured via Discount Rules; same recipe*
29
+ > - [Create or reuse a Catalog V3 ribbon](https://dev.wix.com/docs/api-reference/business-solutions/stores/catalog-v3/ribbons-v3/get-or-create-ribbon) — tags: `[intent:add-ribbon]` · priority 0 · *a ribbon is a visual product label, not a discount rule; follow the ribbon path below*
28
30
  > - [Schedule a future sale](https://dev.wix.com/docs/api-reference/business-solutions/e-commerce/skills/pricing-create-discount-rule) — tags: `[intent:schedule-sale]` · priority 0 · *uses Discount Rules with `startTime` in the future*
29
31
 
32
+ ### Ribbon path
33
+
34
+ For a Catalog V3 request such as "Create a Bestseller ribbon", use the idempotent name-based [Get or Create Ribbon](https://dev.wix.com/docs/api-reference/business-solutions/stores/catalog-v3/ribbons-v3/get-or-create-ribbon) method:
35
+
36
+ ```http
37
+ POST https://www.wixapis.com/stores/v3/ribbons/get-or-create
38
+ Content-Type: application/json
39
+
40
+ {"ribbonName":"Bestseller"}
41
+ ```
42
+
43
+ Read the returned `ribbon.id`. If the user requested only the ribbon definition, report that result and stop. If they also requested assignment to a product, read the product's current `revision` with `GET https://www.wixapis.com/stores/v3/products/{productId}`, as in [Update Product with Options](../stores/update-product-with-options.md). Then send only the ribbon with that `revision` through [Update Product](https://dev.wix.com/docs/api-reference/business-solutions/stores/catalog-v3/products-v3/update-product); fields you omit are left unchanged:
44
+
45
+ ```http
46
+ PATCH https://www.wixapis.com/stores/v3/products/{productId}
47
+ Content-Type: application/json
48
+
49
+ {"product":{"id":"<PRODUCT_ID>","revision":"<CURRENT_REVISION>","ribbon":{"id":"<RIBBON_ID>"}}}
50
+ ```
51
+
52
+ This path covers Catalog V3.
53
+
54
+ Do not create a coupon, discount rule, or price change just because a ribbon says "Sale". Those require a separate discount request. An explicit ribbon creation or assignment request authorizes that operation; otherwise confirm the intended change first. Merchant context needed for promotion recommendations is not a prerequisite to creating a named visual ribbon.
55
+
30
56
  ### Business flows — the orchestrator
31
57
 
32
58
  The single business-flow orchestrator (`recommend-ecommerce-strategy`) handles all strategic discount intents. It classifies internally (SEASONAL / UPSELL_BOOST / STOCK_MOVER / BUNDLE_AND_SAVE / ABANDONED_CART) and loads its `goal-*` / `flow-*` support files from the kept ecommerce-root siblings.