@wix/agent-skills 1.20.1 → 1.22.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 (262) hide show
  1. package/package.json +1 -1
  2. package/skills/wix-app/SKILL.md +71 -113
  3. package/skills/wix-app/references/APP_TOOLS.md +2 -1
  4. package/skills/wix-app/references/BACKEND_EVENT.md +3 -3
  5. package/skills/wix-app/references/CUSTOM_ELEMENT_WIDGET.md +41 -152
  6. package/skills/wix-app/references/DASHBOARD_MODAL.md +4 -4
  7. package/skills/wix-app/references/DASHBOARD_PAGE.md +11 -25
  8. package/skills/wix-app/references/DATA_COLLECTION.md +16 -219
  9. package/skills/wix-app/references/SDK_MODULE_MAP.md +44 -0
  10. package/skills/wix-app/references/SITE_PLUGIN.md +36 -190
  11. package/skills/wix-app/references/app-tools/TOOLS.md +3 -1
  12. package/skills/wix-app/references/custom-element-widget/SETTINGS_PANEL.md +21 -0
  13. package/skills/wix-app/references/dashboard-page/DATA_SOURCES.md +182 -0
  14. package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE.md +97 -0
  15. package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_COLLECTION.md +184 -0
  16. package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_ROUTER.md +203 -0
  17. package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_SETTINGS.md +44 -0
  18. package/skills/wix-app/references/dashboard-page/ECOM_NAVIGATION.md +17 -0
  19. package/skills/wix-app/references/dashboard-page/QUERY_AND_PAGING.md +182 -0
  20. package/skills/wix-app/references/dashboard-page/TABLE_STATE.md +133 -0
  21. package/skills/wix-app/references/dashboard-page/UX_SUCCESS_MODEL.md +10 -5
  22. package/skills/wix-app/references/dashboard-plugin/SLOTS.md +4 -18
  23. package/skills/wix-app/references/data-collection/LIFECYCLE.md +68 -0
  24. package/skills/wix-app/references/data-collection/PERMISSIONS.md +47 -0
  25. package/skills/wix-app/references/data-collection/SCHEMA.md +181 -0
  26. package/skills/wix-app/references/data-collection/WIX_DATA.md +38 -66
  27. package/skills/wix-app/references/site-plugin/EXAMPLES.md +1 -1
  28. package/skills/wix-headless-fast/SKILL.md +144 -221
  29. package/skills/wix-headless-fast/cold-start/bootstrap.mjs +156 -0
  30. package/skills/wix-headless-fast/{entry/skill.md → cold-start/cold-start.md} +15 -15
  31. package/skills/wix-headless-fast/guides/existing-site.md +76 -0
  32. package/skills/wix-headless-fast/guides/reference-mode.md +97 -0
  33. package/skills/wix-headless-fast/install/AGENTS.md +35 -0
  34. package/skills/wix-headless-fast/install/agents-md.mjs +39 -0
  35. package/skills/wix-headless-fast/install/attach.mjs +161 -86
  36. package/skills/wix-headless-fast/install/deploy.mjs +21 -60
  37. package/skills/wix-headless-fast/install/lock.mjs +55 -0
  38. package/skills/wix-headless-fast/install/setup.mjs +259 -0
  39. package/skills/wix-headless-fast/install/templates.mjs +168 -0
  40. package/skills/wix-manage/references/ecommerce/pricing-promotions/ecom-pricing-create-coupon.md +10 -19
  41. package/skills/wix-manage/references/events/create-wix-event.md +5 -1
  42. package/skills/wix-manage/references/google-ads/google-ads-dashboard-navigation.md +27 -0
  43. package/skills/wix-manage/references/google-ads/manage-campaign-success-guide.md +83 -37
  44. package/skills/wix-headless-fast/install/fast-path.mjs +0 -181
  45. package/skills/wix-headless-fast/references/blog/INSTRUCTIONS.md +0 -301
  46. package/skills/wix-headless-fast/references/blog/app/components/blog/BlogFeedView.tsx +0 -136
  47. package/skills/wix-headless-fast/references/blog/app/components/blog/PostView.tsx +0 -112
  48. package/skills/wix-headless-fast/references/blog/app/components/blog/RichContent.tsx +0 -42
  49. package/skills/wix-headless-fast/references/blog/app/hooks/blog/useBlogFeed.ts +0 -31
  50. package/skills/wix-headless-fast/references/blog/app/hooks/blog/usePost.ts +0 -22
  51. package/skills/wix-headless-fast/references/blog/app/wix/blog/blog-feed-store.ts +0 -137
  52. package/skills/wix-headless-fast/references/blog/app/wix/blog/post-store.ts +0 -78
  53. package/skills/wix-headless-fast/references/blog/app/wix/blog/posts-core.ts +0 -117
  54. package/skills/wix-headless-fast/references/blog/app/wix/blog/posts.ts +0 -52
  55. package/skills/wix-headless-fast/references/blog/app/wix/blog/taxonomy-core.ts +0 -47
  56. package/skills/wix-headless-fast/references/blog/app/wix/blog/taxonomy.ts +0 -58
  57. package/skills/wix-headless-fast/references/blog/app/wix/blog/types.ts +0 -62
  58. package/skills/wix-headless-fast/references/blog/app-astro/layouts/SiteLayout.astro +0 -40
  59. package/skills/wix-headless-fast/references/blog/app-astro/pages/blog/[...slug].astro +0 -97
  60. package/skills/wix-headless-fast/references/blog/app-astro/pages/blog.astro +0 -24
  61. package/skills/wix-headless-fast/references/blog/lock/astro/package-lock.json +0 -16156
  62. package/skills/wix-headless-fast/references/blog/rest/posts.ts +0 -42
  63. package/skills/wix-headless-fast/references/blog/rest/taxonomy.ts +0 -62
  64. package/skills/wix-headless-fast/references/blog/seed/SEED.md +0 -81
  65. package/skills/wix-headless-fast/references/blog/seed/seed-blog.mjs +0 -287
  66. package/skills/wix-headless-fast/references/bookings/INSTRUCTIONS.md +0 -275
  67. package/skills/wix-headless-fast/references/bookings/app/components/bookings/ServiceBookingView.tsx +0 -144
  68. package/skills/wix-headless-fast/references/bookings/app/components/bookings/ServicesView.tsx +0 -119
  69. package/skills/wix-headless-fast/references/bookings/app/hooks/bookings/useBookingFlow.ts +0 -32
  70. package/skills/wix-headless-fast/references/bookings/app/hooks/bookings/useServices.ts +0 -23
  71. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/booking-core.ts +0 -218
  72. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/booking-flow-store.ts +0 -169
  73. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/booking.ts +0 -121
  74. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/services-core.ts +0 -92
  75. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/services-store.ts +0 -90
  76. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/services.ts +0 -57
  77. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/types.ts +0 -72
  78. package/skills/wix-headless-fast/references/bookings/app-astro/layouts/SiteLayout.astro +0 -40
  79. package/skills/wix-headless-fast/references/bookings/app-astro/pages/services/[slug].astro +0 -76
  80. package/skills/wix-headless-fast/references/bookings/app-astro/pages/services.astro +0 -22
  81. package/skills/wix-headless-fast/references/bookings/lock/astro/package-lock.json +0 -11962
  82. package/skills/wix-headless-fast/references/bookings/rest/booking.ts +0 -113
  83. package/skills/wix-headless-fast/references/bookings/rest/services.ts +0 -55
  84. package/skills/wix-headless-fast/references/bookings/seed/SEED.md +0 -71
  85. package/skills/wix-headless-fast/references/bookings/seed/seed-bookings.mjs +0 -302
  86. package/skills/wix-headless-fast/references/cms/INSTRUCTIONS.md +0 -353
  87. package/skills/wix-headless-fast/references/cms/app/hooks/cms/useCollection.ts +0 -50
  88. package/skills/wix-headless-fast/references/cms/app/hooks/cms/useItem.ts +0 -37
  89. package/skills/wix-headless-fast/references/cms/app/wix/cms/collection-store.ts +0 -158
  90. package/skills/wix-headless-fast/references/cms/app/wix/cms/item-store.ts +0 -93
  91. package/skills/wix-headless-fast/references/cms/app/wix/cms/items-core.ts +0 -177
  92. package/skills/wix-headless-fast/references/cms/app/wix/cms/items.ts +0 -123
  93. package/skills/wix-headless-fast/references/cms/app/wix/cms/types.ts +0 -75
  94. package/skills/wix-headless-fast/references/cms/app-astro/layouts/SiteLayout.astro +0 -41
  95. package/skills/wix-headless-fast/references/cms/lock/astro/package-lock.json +0 -11262
  96. package/skills/wix-headless-fast/references/cms/rest/items.ts +0 -125
  97. package/skills/wix-headless-fast/references/cms/seed/SEED.md +0 -112
  98. package/skills/wix-headless-fast/references/cms/seed/seed-cms.mjs +0 -324
  99. package/skills/wix-headless-fast/references/events/INSTRUCTIONS.md +0 -305
  100. package/skills/wix-headless-fast/references/events/app/components/events/EventConfirmationView.tsx +0 -66
  101. package/skills/wix-headless-fast/references/events/app/components/events/EventRegistrationView.tsx +0 -178
  102. package/skills/wix-headless-fast/references/events/app/components/events/EventsView.tsx +0 -118
  103. package/skills/wix-headless-fast/references/events/app/hooks/events/useEventRegistration.ts +0 -35
  104. package/skills/wix-headless-fast/references/events/app/hooks/events/useEvents.ts +0 -24
  105. package/skills/wix-headless-fast/references/events/app/wix/events/events-core.ts +0 -130
  106. package/skills/wix-headless-fast/references/events/app/wix/events/events-store.ts +0 -97
  107. package/skills/wix-headless-fast/references/events/app/wix/events/events.ts +0 -55
  108. package/skills/wix-headless-fast/references/events/app/wix/events/registration-core.ts +0 -113
  109. package/skills/wix-headless-fast/references/events/app/wix/events/registration-store.ts +0 -156
  110. package/skills/wix-headless-fast/references/events/app/wix/events/registration.ts +0 -97
  111. package/skills/wix-headless-fast/references/events/app/wix/events/types.ts +0 -61
  112. package/skills/wix-headless-fast/references/events/app-astro/layouts/SiteLayout.astro +0 -40
  113. package/skills/wix-headless-fast/references/events/app-astro/pages/event-confirmation.astro +0 -12
  114. package/skills/wix-headless-fast/references/events/app-astro/pages/events/[slug].astro +0 -80
  115. package/skills/wix-headless-fast/references/events/app-astro/pages/events.astro +0 -21
  116. package/skills/wix-headless-fast/references/events/lock/astro/package-lock.json +0 -11884
  117. package/skills/wix-headless-fast/references/events/rest/events.ts +0 -57
  118. package/skills/wix-headless-fast/references/events/rest/registration.ts +0 -83
  119. package/skills/wix-headless-fast/references/events/seed/SEED.md +0 -95
  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 -338
  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/seed-forms.mjs +0 -327
  134. package/skills/wix-headless-fast/references/members/INSTRUCTIONS.md +0 -314
  135. package/skills/wix-headless-fast/references/members/app/components/members/AccountView.tsx +0 -60
  136. package/skills/wix-headless-fast/references/members/app/components/members/LoginForm.tsx +0 -155
  137. package/skills/wix-headless-fast/references/members/app/components/members/MemberMenu.tsx +0 -78
  138. package/skills/wix-headless-fast/references/members/app/components/members/RequireAuth.tsx +0 -47
  139. package/skills/wix-headless-fast/references/members/app/hooks/members/useMember.ts +0 -66
  140. package/skills/wix-headless-fast/references/members/app/wix/members/auth-core.ts +0 -105
  141. package/skills/wix-headless-fast/references/members/app/wix/members/auth.ts +0 -59
  142. package/skills/wix-headless-fast/references/members/app/wix/members/client.ts +0 -53
  143. package/skills/wix-headless-fast/references/members/app/wix/members/member-store.ts +0 -122
  144. package/skills/wix-headless-fast/references/members/app/wix/members/members-core.ts +0 -43
  145. package/skills/wix-headless-fast/references/members/app/wix/members/members.ts +0 -29
  146. package/skills/wix-headless-fast/references/members/app/wix/members/types.ts +0 -21
  147. package/skills/wix-headless-fast/references/members/app-astro/layouts/SiteLayout.astro +0 -42
  148. package/skills/wix-headless-fast/references/members/app-astro/pages/account.astro +0 -10
  149. package/skills/wix-headless-fast/references/members/app-astro/pages/login.astro +0 -11
  150. package/skills/wix-headless-fast/references/members/lock/astro/package-lock.json +0 -10329
  151. package/skills/wix-headless-fast/references/members/rest/auth.ts +0 -215
  152. package/skills/wix-headless-fast/references/members/rest/members.ts +0 -26
  153. package/skills/wix-headless-fast/references/members/seed/SEED.md +0 -39
  154. package/skills/wix-headless-fast/references/members/seed/seed-members.mjs +0 -94
  155. package/skills/wix-headless-fast/references/portfolio/INSTRUCTIONS.md +0 -313
  156. package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/CollectionProjectsView.tsx +0 -110
  157. package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/CollectionsView.tsx +0 -90
  158. package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/GalleryMedia.tsx +0 -35
  159. package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/ProjectDetailView.tsx +0 -85
  160. package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useCollectionProjects.ts +0 -32
  161. package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useCollections.ts +0 -21
  162. package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useProjectDetail.ts +0 -31
  163. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/collection-projects-store.ts +0 -82
  164. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/collections-store.ts +0 -58
  165. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/portfolio-core.ts +0 -177
  166. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/portfolio.ts +0 -78
  167. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/project-detail-store.ts +0 -81
  168. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/types.ts +0 -55
  169. package/skills/wix-headless-fast/references/portfolio/app-astro/layouts/SiteLayout.astro +0 -40
  170. package/skills/wix-headless-fast/references/portfolio/app-astro/pages/portfolio/[slug].astro +0 -30
  171. package/skills/wix-headless-fast/references/portfolio/app-astro/pages/portfolio.astro +0 -21
  172. package/skills/wix-headless-fast/references/portfolio/app-astro/pages/projects/[slug].astro +0 -29
  173. package/skills/wix-headless-fast/references/portfolio/lock/astro/package-lock.json +0 -10197
  174. package/skills/wix-headless-fast/references/portfolio/rest/portfolio.ts +0 -75
  175. package/skills/wix-headless-fast/references/portfolio/seed/SEED.md +0 -86
  176. package/skills/wix-headless-fast/references/portfolio/seed/seed-portfolio.mjs +0 -258
  177. package/skills/wix-headless-fast/references/pricing-plans/INSTRUCTIONS.md +0 -294
  178. package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/PlanDetailView.tsx +0 -47
  179. package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/PlansView.tsx +0 -101
  180. package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/SubscribeButton.tsx +0 -41
  181. package/skills/wix-headless-fast/references/pricing-plans/app/hooks/pricing-plans/usePlanPurchase.ts +0 -16
  182. package/skills/wix-headless-fast/references/pricing-plans/app/hooks/pricing-plans/usePlans.ts +0 -22
  183. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plan-purchase-store.ts +0 -54
  184. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plans-core.ts +0 -106
  185. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plans-store.ts +0 -64
  186. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plans.ts +0 -27
  187. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/purchase-core.ts +0 -43
  188. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/purchase.ts +0 -22
  189. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/types.ts +0 -30
  190. package/skills/wix-headless-fast/references/pricing-plans/app-astro/layouts/SiteLayout.astro +0 -41
  191. package/skills/wix-headless-fast/references/pricing-plans/app-astro/pages/plans/[slug].astro +0 -40
  192. package/skills/wix-headless-fast/references/pricing-plans/app-astro/pages/plans.astro +0 -21
  193. package/skills/wix-headless-fast/references/pricing-plans/lock/astro/package-lock.json +0 -11226
  194. package/skills/wix-headless-fast/references/pricing-plans/rest/plans.ts +0 -31
  195. package/skills/wix-headless-fast/references/pricing-plans/rest/purchase.ts +0 -20
  196. package/skills/wix-headless-fast/references/pricing-plans/seed/SEED.md +0 -79
  197. package/skills/wix-headless-fast/references/pricing-plans/seed/seed-pricing-plans.mjs +0 -279
  198. package/skills/wix-headless-fast/references/restaurants/INSTRUCTIONS.md +0 -358
  199. package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/MenuView.tsx +0 -142
  200. package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/OrderCartButton.tsx +0 -26
  201. package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/OrderCartDrawer.tsx +0 -121
  202. package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/ReservationView.tsx +0 -155
  203. package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useMenus.ts +0 -34
  204. package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useOrderCart.ts +0 -43
  205. package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useReservation.ts +0 -34
  206. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/menu-core.ts +0 -155
  207. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/menu-store.ts +0 -89
  208. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/menu.ts +0 -71
  209. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/order-store.ts +0 -103
  210. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/ordering-core.ts +0 -124
  211. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/ordering.ts +0 -185
  212. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/reservation-store.ts +0 -193
  213. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/reservations-core.ts +0 -94
  214. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/reservations.ts +0 -74
  215. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/types.ts +0 -168
  216. package/skills/wix-headless-fast/references/restaurants/app-astro/layouts/SiteLayout.astro +0 -47
  217. package/skills/wix-headless-fast/references/restaurants/app-astro/pages/menu.astro +0 -22
  218. package/skills/wix-headless-fast/references/restaurants/app-astro/pages/reservations.astro +0 -12
  219. package/skills/wix-headless-fast/references/restaurants/lock/astro/package-lock.json +0 -12560
  220. package/skills/wix-headless-fast/references/restaurants/rest/menu.ts +0 -60
  221. package/skills/wix-headless-fast/references/restaurants/rest/ordering.ts +0 -169
  222. package/skills/wix-headless-fast/references/restaurants/rest/reservations.ts +0 -68
  223. package/skills/wix-headless-fast/references/restaurants/seed/SEED.md +0 -89
  224. package/skills/wix-headless-fast/references/restaurants/seed/seed-restaurants.mjs +0 -479
  225. package/skills/wix-headless-fast/references/shared/CONTENT.md +0 -22
  226. package/skills/wix-headless-fast/references/shared/CUSTOM_OPERATIONS.md +0 -73
  227. package/skills/wix-headless-fast/references/shared/DESIGN.md +0 -26
  228. package/skills/wix-headless-fast/references/shared/SUPPLIED-CONTENT.md +0 -23
  229. package/skills/wix-headless-fast/references/shared/app/styles/global.css +0 -52
  230. package/skills/wix-headless-fast/references/shared/app/wix/config.ts +0 -15
  231. package/skills/wix-headless-fast/references/shared/app/wix/media.ts +0 -81
  232. package/skills/wix-headless-fast/references/shared/app/wix/money.ts +0 -24
  233. package/skills/wix-headless-fast/references/shared/app/wix/sdk.ts +0 -89
  234. package/skills/wix-headless-fast/references/shared/capabilities/media-upload/app/wix/media-upload/client.ts +0 -46
  235. package/skills/wix-headless-fast/references/shared/capabilities/media-upload/app-astro/pages/api/wix/media-upload.ts +0 -46
  236. package/skills/wix-headless-fast/references/shared/rest/client.ts +0 -155
  237. package/skills/wix-headless-fast/references/shared/rest/config.ts +0 -3
  238. package/skills/wix-headless-fast/references/shared/rest/media.ts +0 -65
  239. package/skills/wix-headless-fast/references/shared/seed/images.mjs +0 -145
  240. package/skills/wix-headless-fast/references/storefront/INSTRUCTIONS.md +0 -608
  241. package/skills/wix-headless-fast/references/storefront/app/components/storefront/CartButton.tsx +0 -26
  242. package/skills/wix-headless-fast/references/storefront/app/components/storefront/CartDrawer.tsx +0 -155
  243. package/skills/wix-headless-fast/references/storefront/app/components/storefront/FilterPanel.tsx +0 -266
  244. package/skills/wix-headless-fast/references/storefront/app/components/storefront/OptionPicker.tsx +0 -95
  245. package/skills/wix-headless-fast/references/storefront/app/components/storefront/QuickAdd.tsx +0 -136
  246. package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useCart.ts +0 -48
  247. package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useProductDetail.ts +0 -39
  248. package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useShop.ts +0 -34
  249. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart-core.ts +0 -121
  250. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart-store.ts +0 -107
  251. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart.ts +0 -138
  252. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/catalog-core.ts +0 -309
  253. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/catalog.ts +0 -133
  254. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/product-detail-store.ts +0 -147
  255. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/shop-store.ts +0 -289
  256. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/types.ts +0 -167
  257. package/skills/wix-headless-fast/references/storefront/app-astro/layouts/SiteLayout.astro +0 -65
  258. package/skills/wix-headless-fast/references/storefront/lock/astro/package-lock.json +0 -12247
  259. package/skills/wix-headless-fast/references/storefront/rest/cart.ts +0 -132
  260. package/skills/wix-headless-fast/references/storefront/rest/catalog.ts +0 -123
  261. package/skills/wix-headless-fast/references/storefront/seed/SEED.md +0 -124
  262. package/skills/wix-headless-fast/references/storefront/seed/seed-store.mjs +0 -525
@@ -1,36 +1,59 @@
1
- // Attach a NEW headless frontend to an EXISTING Wix site — the fast path for a site that already
1
+ // Attach a NEW headless frontend to an EXISTING Wix site — setup's sibling for a site that already
2
2
  // exists (named in the prompt by its id). `init`/`wix create` cannot do this: they always create
3
3
  // a site. This script does what they do AFTER creating one — OAuth app, managed hosting, env
4
4
  // vars, `wix.config.json` — against the site id given, then scaffolds and deploys like
5
- // fast-path.mjs. Nothing on the site is created, changed or deleted; there is no seed step.
5
+ // setup.mjs. Nothing on the site is created, changed or deleted; there is no seed step.
6
6
  //
7
- // node <SKILL_ROOT>/install/attach.mjs --site <metaSiteId> --business-name "<Brand>" \
8
- // --vertical <a>[,<b>…] [--stack astro|react|static] [--subfolder [--folder-name <name>]]
7
+ // node <SKILL_ROOT>/install/attach.mjs [--site <metaSiteId>] --business-name "<Brand>" \
8
+ // --vertical <a>[,<b>…] [--stack astro|react|lib|static] [--hosting wix|self [--origin <url>[,<url>]]] \
9
+ // [--subfolder [--folder-name <name>]]
9
10
  //
11
+ // --hosting wix (default): the frontend releases to Wix hosting — the site's app project is
12
+ // created or reused and `wix release` uploads to its *.wix-site-host.com address.
13
+ // self: the frontend is hosted elsewhere (Vercel, a Flask server, …): no app
14
+ // project, no Wix address, no Astro template; the OAuth app, wix.config.json and
15
+ // .env.local are still set up, the code deploys for --stack, and the origins given
16
+ // in --origin go on the OAuth app's redirect allow-list, which is what a Wix-hosted
17
+ // flow (checkout) needs to return to a frontend on another host.
18
+ //
19
+ // --site the site. May be omitted when the folder holds a wix.config.json: then it is
20
+ // the site in that config (what `init` left behind in an empty folder).
10
21
  // --business-name the site's name (names the folder, the hosting slug and the app project).
11
22
  // --vertical which shipped code deploys (no seed runs — the site owns its content). Both are
12
23
  // the caller's decision, read off the site before calling this (SKILL.md step 3).
13
- // --stack astro (default): scaffolds the CLI's blank Astro template with the hosting adapter,
14
- // ready for `wix build` / `wix release`. react|static: writes wix.config.json into the
15
- // folder and stops — the caller scaffolds (Vite / plain HTML) per SKILL.md.
16
- // The project is created in the CURRENT DIRECTORY — the folder that already holds the installed
17
- // skills — so it is self-contained. `--subfolder` (opt-in) creates it in a new folder named after
18
- // the business instead.
24
+ // --stack astro (default) in a folder without a project: copies the first vertical's
25
+ // composed template (templates/<vertical>/project). react|static there: writes wix.config.json
26
+ // and stops — the caller scaffolds (Vite / plain HTML) per SKILL.md. In a folder
27
+ // that holds a project, --stack is required and nothing is scaffolded.
28
+ //
29
+ // The FOLDER decides, on file markers only:
30
+ // - a project (package.json or index.html) AND wix.config.json → refuses: a Wix project with a
31
+ // frontend already; deploy.mjs adds a solution to it.
32
+ // - a project, no config → LINK: the hosting calls, then wix.config.json and .env.local are
33
+ // written into the project as it is, the shipped code deploys for --stack, the install starts.
34
+ // - no project (empty, or only a config for this same site) → the scaffold path above.
35
+ // - a config naming a different site → refuses: never re-point a folder; use --subfolder.
36
+ // The project lives in the CURRENT DIRECTORY — the folder that already holds the installed skills —
37
+ // so it is self-contained. `--subfolder` (opt-in) creates it in a new folder named after the
38
+ // business instead.
19
39
  //
20
40
  // Emits ONE JSON event per line (attached, scaffolded, deployed, install_started,
21
41
  // ready_for_brand_layer, or error). Requires a logged-in Wix CLI (`npx @wix/cli@latest whoami`)
22
42
  // whose account owns or co-manages the site.
23
43
  import { spawn, spawnSync, execFileSync } from "node:child_process";
24
- import { cpSync, existsSync, mkdirSync, mkdtempSync, openSync, readFileSync, readdirSync, renameSync, rmSync, writeFileSync } from "node:fs";
25
- import { tmpdir } from "node:os";
26
- import { dirname, join, resolve } from "node:path";
44
+ import { cpSync, existsSync, mkdirSync, openSync, readFileSync, writeFileSync } from "node:fs";
45
+ import { basename, dirname, join, resolve } from "node:path";
27
46
  import { fileURLToPath } from "node:url";
47
+ import { writeAgentsMd } from "./agents-md.mjs";
48
+ import { listVerticals, templatesDir } from "./templates.mjs";
28
49
 
29
50
  const SKILL_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..");
30
51
  const MANAGE = "https://manage.wix.com";
52
+ const API = "https://www.wixapis.com";
31
53
  const HEADLESS_PROJECT_TYPE_ID = "eb363dea-85a0-4159-9b05-949542be5079";
32
- const TEMPLATES_REPO = "https://github.com/wix/headless-templates.git";
33
- const TEMPLATE_PATH = "astro/blank";
54
+ // The shipped code: the repository's templates/ (a checkout, the cache, or fetched now, in a second).
55
+ let TEMPLATES;
56
+ try { TEMPLATES = templatesDir(); } catch (e) { fail("templates", e.message); }
34
57
 
35
58
  const emit = (event, extra = {}) => console.log(JSON.stringify({ event, ...extra }));
36
59
  const fail = (step, detail) => {
@@ -44,25 +67,46 @@ const flag = (name) => {
44
67
  const i = argv.indexOf(`--${name}`);
45
68
  return i !== -1 && argv[i + 1] && !argv[i + 1].startsWith("--") ? argv[i + 1] : null;
46
69
  };
47
- const siteId = flag("site");
48
- const stack = flag("stack") ?? "astro";
70
+ const stackFlag = flag("stack");
71
+ const hosting0 = flag("hosting") ?? "wix";
72
+ const origins = (flag("origin") ?? "").split(",").map((o) => o.trim().replace(/\/$/, "")).filter(Boolean);
49
73
  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);
74
+ // ---- the folder ---------------------------------------------------------------------------------
75
+ const cwd = process.cwd();
76
+ const has = (p) => existsSync(join(cwd, p));
77
+ const cwdConfig = has("wix.config.json") ? JSON.parse(readFileSync(join(cwd, "wix.config.json"), "utf8")) : null;
78
+ const hasProject = has("package.json") || has("index.html");
79
+ const siteId = flag("site") ?? cwdConfig?.siteId ?? cwdConfig?.projectId ?? null;
80
+ const stack = stackFlag ?? "astro";
81
+ const knownVerticals = listVerticals(TEMPLATES);
53
82
  const verticals = argv
54
83
  .flatMap((a, i) => (a === "--vertical" && argv[i + 1] ? argv[i + 1].split(",") : []))
55
84
  .map((v) => v.trim())
56
85
  .filter(Boolean);
57
86
  const businessName = flag("business-name");
58
87
  if (!siteId || !/^[0-9a-f-]{36}$/i.test(siteId) || !businessName || !verticals.length) {
59
- fail("args", `usage: attach.mjs --site <metaSiteId> --business-name "<Brand>" --vertical <${knownVerticals.join("|")}>[,…] [--stack astro|react|static]`);
88
+ fail("args", `usage: attach.mjs [--site <metaSiteId>] --business-name "<Brand>" --vertical <${knownVerticals.join("|")}>[,…] [--stack astro|react|lib|static] (--site may be omitted when wix.config.json is here)`);
60
89
  }
61
90
  for (const v of verticals) if (!knownVerticals.includes(v)) fail("args", `unknown vertical "${v}" — shipped verticals: ${knownVerticals.join(", ")}`);
62
- if (!["astro", "react", "static"].includes(stack)) fail("args", `unknown stack "${stack}" — astro, react or static`);
63
- if (existsSync(join(process.cwd(), "wix.config.json"))) {
64
- fail("args", "the current directory is already a Wix project (wix.config.json) — attach creates a new frontend; run deploy.mjs here instead");
91
+ if (!["astro", "react", "lib", "static"].includes(stack)) fail("args", `unknown stack "${stack}" — astro, react, lib or static`);
92
+ if (!["wix", "self"].includes(hosting0)) fail("args", `unknown --hosting "${hosting0}" — wix or self`);
93
+ for (const o of origins) if (!/^https?:\/\/[^/\s]+$/.test(o)) fail("args", `--origin must be a scheme and host such as https://shop.example.com or http://localhost:8000, got "${o}"`);
94
+ if (hosting0 === "self" && stack === "astro" && !hasProject && !stackFlag) {
95
+ fail("args", "--hosting self scaffolds nothing: pass --stack for the frontend you will host (react|lib|static), or attach from inside the project on disk");
65
96
  }
97
+ if (!subfolder) {
98
+ if (hasProject && cwdConfig) {
99
+ fail("place", "this folder is already a Wix project with a frontend (wix.config.json and a project): nothing to attach. deploy.mjs <vertical> adds this skill's code or a solution to it; then ONE npm install");
100
+ }
101
+ if (cwdConfig && (cwdConfig.siteId ?? cwdConfig.projectId) !== siteId) {
102
+ fail("place", `this folder is attached to site ${cwdConfig.siteId ?? cwdConfig.projectId}, not ${siteId} — a folder is never re-pointed; attach the other site with --subfolder`);
103
+ }
104
+ if (hasProject && !stackFlag) {
105
+ fail("args", "attaching a project on disk needs --stack astro|react|lib|static — the stack you resolved in SKILL.md step 1 for this project");
106
+ }
107
+ }
108
+ const mode = !subfolder && hasProject ? "link" : hosting0 === "self" ? "config-only" : "scaffold";
109
+ emit("folder", { mode, stack, hosting: hosting0, project: hasProject, config: cwdConfig ? "same site" : null });
66
110
 
67
111
  // ---- http ---------------------------------------------------------------------------------------
68
112
  const cliToken = (site) => {
@@ -92,25 +136,27 @@ async function call(base, path, { method = "POST", token, site, body, query } =
92
136
  }
93
137
 
94
138
  const folderName = flag("folder-name") ?? (businessName.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 40) || "site");
95
- const projectDir = subfolder ? resolve(process.cwd(), folderName) : process.cwd();
139
+ const projectDir = subfolder ? resolve(cwd, folderName) : cwd;
96
140
  if (subfolder && existsSync(join(projectDir, "wix.config.json"))) fail("args", `${folderName}/ is already a Wix project — pick --folder-name, or run deploy.mjs there`);
97
141
 
98
142
  // ---- 1 · attach: OAuth app + hosting + env, on the manage host with a site token -----------------
99
143
  // The same calls `init` makes after it has created a site, in the same order.
100
144
  const siteToken = cliToken(siteId);
101
145
  const opts = { token: siteToken, site: siteId };
102
- let appId, appProject, instanceId, secrets, hosting = "created";
146
+ let appId, appProject = null, instanceId, secrets, hosting = hosting0 === "self" ? "self" : "created";
103
147
  try {
104
148
  const comp = await call(MANAGE, "/_api/companion-apps/v1/companion-apps/get-or-create", { ...opts, body: {} });
105
149
  appId = comp.companionApp?.id;
106
150
  if (!appId) throw new Error("get-or-create returned no companion app id");
107
151
  const slug = folderName;
108
- try { appProject = (await call(MANAGE, `/_api/wix-code-app-projects/v1/app-projects/${appId}`, { ...opts, method: "GET" })).appProject; } catch { appProject = null; }
109
- if (appProject) {
110
- hosting = "reused";
111
- } else {
112
- try { await call(MANAGE, `/apps-service/v1/apps/${appId}/set-namespace`, { ...opts, method: "PATCH", body: { appId, appName: businessName, namespace: slug } }); }
113
- catch (e) { emit("note", { step: "set-namespace", detail: String(e.message).slice(0, 200) }); }
152
+ if (hosting0 === "wix") {
153
+ try { appProject = (await call(MANAGE, `/_api/wix-code-app-projects/v1/app-projects/${appId}`, { ...opts, method: "GET" })).appProject; } catch { appProject = null; }
154
+ if (appProject) {
155
+ hosting = "reused";
156
+ } else {
157
+ try { await call(MANAGE, `/apps-service/v1/apps/${appId}/set-namespace`, { ...opts, method: "PATCH", body: { appId, appName: businessName, namespace: slug } }); }
158
+ catch (e) { emit("note", { step: "set-namespace", detail: String(e.message).slice(0, 200) }); }
159
+ }
114
160
  }
115
161
  try {
116
162
  const inst = await call(MANAGE, "/apps-installer-service/v1/app-instance/install", { ...opts, body: { tenant: { id: siteId, tenantType: "SITE" }, appInstance: { appDefId: appId, version: "latest" } } });
@@ -118,9 +164,23 @@ try {
118
164
  } catch (e) { emit("note", { step: "install", detail: String(e.message).slice(0, 200) }); }
119
165
  secrets = (await call(MANAGE, `/apps-service/v1/apps/${appId}`, { ...opts, method: "GET", query: { withSecrets: true } })).app?.appSecrets;
120
166
  if (!secrets?.appSecret) throw new Error("app secrets unavailable for this app");
121
- if (!appProject) {
167
+ if (hosting0 === "self") {
168
+ // No Wix hosting. The one thing a frontend on another host needs from the site: its origins on
169
+ // the OAuth app's redirect allow-list, so checkout and the other Wix-hosted flows can return.
170
+ // The public OAuth Apps API (wix-manage: Manage OAuth Apps), merged with what is already there.
171
+ if (origins.length) {
172
+ const current = (await call(API, `/oauth-app/v1/oauth-apps/${appId}`, { ...opts, method: "GET" })).oAuthApp ?? {};
173
+ const merged = [...new Set([...(current.allowedRedirectDomains ?? []), ...origins])];
174
+ await call(API, `/oauth-app/v1/oauth-apps/${appId}`, { ...opts, method: "PATCH", body: { oAuthApp: { allowedRedirectDomains: merged }, mask: { paths: ["allowedRedirectDomains"] } } });
175
+ emit("origins_allowed", { appId, allowedRedirectDomains: merged });
176
+ } else {
177
+ emit("note", { step: "origins", detail: "no --origin given: add the frontend's origins to the OAuth app's allowedRedirectDomains (wix-manage: Manage OAuth Apps) before the first checkout test" });
178
+ }
179
+ }
180
+ if (hosting0 === "wix" && !appProject) {
122
181
  appProject = (await call(MANAGE, "/_api/wix-code-app-projects/v1/app-projects", { ...opts, body: { appProject: { id: appId, displayName: businessName.slice(0, 50), slug, appProjectTypeId: HEADLESS_PROJECT_TYPE_ID } } })).appProject;
123
182
  }
183
+ if (hosting0 === "wix") {
124
184
  if (!appProject?.baseUrl) throw new Error("app project has no baseUrl");
125
185
  const prod = String(appProject.baseUrl).replace(/\/$/, "");
126
186
  const host = new URL(appProject.baseUrl).hostname;
@@ -146,55 +206,54 @@ try {
146
206
  await call(MANAGE, `/_api/wix-code-app-environments/v2/bulk/app-projects/${appProject.id}/app-environment-variables/upsert`, { ...opts, body: {
147
207
  appProjectId: appProject.id, environment: "system_global", mutability: "STATIC", returnEntity: true, returnAllEnvironment: true, variables,
148
208
  } });
209
+ }
149
210
  } catch (e) {
150
211
  fail("attach", e?.message || e);
151
212
  }
152
- const baseUrl = String(appProject.baseUrl).replace(/\/$/, "");
153
- emit("attached", { siteId, appId, baseUrl, hosting, note: hosting === "reused" ? "this site already has a headless frontend at baseUrl; `wix release` from this project replaces it" : undefined });
213
+ const baseUrl = appProject ? String(appProject.baseUrl).replace(/\/$/, "") : null;
214
+ // Is a frontend serving at that address? The hosting project says nothing about it (init and the
215
+ // provisioning call create one with nothing behind it). The site's release slots do: the release
216
+ // with slug `prod` is production traffic and names the deployment it serves — the same read the
217
+ // headless back office makes for its frontend status. Absent means nothing was ever released.
218
+ // Deployments keep their own addresses, so a replaced one is not lost; prod can be pointed back.
219
+ // A folder that reaches this point is not the one that released (a linked project never runs
220
+ // attach), so a `prod` release here means a NEW project is about to take over a live frontend.
221
+ let frontend = null;
222
+ if (appProject) {
223
+ try {
224
+ const r = await call(MANAGE, `/_api/wix-code-app-releases/v1/app-projects/${appProject.id}/app-releases/query`, { ...opts, body: { query: { cursorPaging: { limit: 20 } } } });
225
+ const prod = (r.appReleases ?? []).find((x) => x.releaseSlug === "prod");
226
+ frontend = prod
227
+ ? { serving: true, releasedAt: prod.updatedDate ?? prod.createdDate ?? null, deploymentId: prod.appDeploymentId ?? null }
228
+ : { serving: false };
229
+ } catch (e) {
230
+ emit("note", { step: "releases", detail: String(e.message).slice(0, 200) });
231
+ frontend = { serving: null };
232
+ }
233
+ }
234
+ const note =
235
+ hosting === "self" ? "no Wix hosting: the frontend is yours to host; its origins must be on the OAuth app's allow-list"
236
+ : frontend?.serving === true
237
+ ? `a frontend is SERVING at ${baseUrl}, released ${frontend.releasedAt}. This is a new project: a \`wix release\` from here replaces it (the current deployment keeps its own address and prod can be pointed back). Tell the user before releasing; unless the brief asked for a new frontend, ask.`
238
+ : frontend?.serving === false
239
+ ? `${hosting === "created" ? "hosting created" : "hosting exists"} at ${baseUrl}; nothing served yet — the first release from this project fills it`
240
+ : frontend
241
+ ? `could not read whether a frontend is serving at ${baseUrl}; check the address before releasing`
242
+ : undefined;
243
+ emit("attached", { siteId, appId, baseUrl, hosting, frontend, origins: hosting0 === "self" ? origins : undefined, note });
154
244
 
155
- // ---- 2 · scaffold -------------------------------------------------------------------------------
245
+ // ---- 2 · scaffold (only where there is no project) -------------------------------------------------
156
246
  mkdirSync(projectDir, { recursive: true });
157
- if (stack === "astro") {
158
- // The CLI's own blank template (what `wix create` copies), then what its extender adds: the
159
- // hosting adapter, React islands, the `wix` scripts. Pinned like a freshly created project.
160
- const tmp = mkdtempSync(join(tmpdir(), "wix-template-"));
161
- const clone = spawnSync("git", ["clone", "--quiet", "--depth", "1", "--filter=blob:none", "--sparse", TEMPLATES_REPO, tmp], { encoding: "utf8", timeout: 120_000 });
162
- if (clone.status !== 0) fail("scaffold", clone.stderr || "git clone of the template repo failed");
163
- const sparse = spawnSync("git", ["-C", tmp, "sparse-checkout", "set", TEMPLATE_PATH], { encoding: "utf8", timeout: 60_000 });
164
- if (sparse.status !== 0 || !existsSync(join(tmp, TEMPLATE_PATH, "package.json"))) fail("scaffold", sparse.stderr || `template ${TEMPLATE_PATH} not found in ${TEMPLATES_REPO}`);
165
- cpSync(join(tmp, TEMPLATE_PATH), projectDir, { recursive: true, force: false, errorOnExist: false });
166
- rmSync(tmp, { recursive: true, force: true });
247
+ if (stack === "astro" && mode === "scaffold") {
248
+ // The first vertical's composed template: the CLI's blank scaffold with the vertical deployed
249
+ // and its lockfile, the same folder `wix create --template-path` copies for a new site. Copied
250
+ // here because the CLI's create makes a new site and this folder gets an existing one. Further
251
+ // verticals are deployed below.
252
+ cpSync(join(templatesDir({ need: `${verticals[0]}/project` }), verticals[0], "project"), projectDir, { recursive: true, force: false, errorOnExist: false });
167
253
  const pkgPath = join(projectDir, "package.json");
168
254
  const pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
169
255
  pkg.name = folderName;
170
- pkg.scripts = { astro: "astro", dev: "wix dev", build: "wix build", wix: "wix", preview: "wix preview", release: "wix release", generate: "wix generate", env: "wix env", skills: "wix skills" };
171
- pkg.devDependencies = {
172
- ...(pkg.devDependencies ?? {}),
173
- "@astrojs/react": "^4.3.0",
174
- "@types/react": "^18.3.1",
175
- "@types/react-dom": "^18.3.1",
176
- "@wix/cli": "^1.1.92",
177
- "@wix/astro-wix-hosting-adapter": "^2.0.0",
178
- react: "18.3.1",
179
- "react-dom": "18.3.1",
180
- };
181
256
  writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
182
- writeFileSync(join(projectDir, "astro.config.mjs"), `// @ts-check
183
- import { defineConfig } from "astro/config";
184
- import wix from "@wix/astro";
185
- import wixPages from "@wix/astro-pages";
186
- import react from "@astrojs/react";
187
- import wixHostingAdapter from "@wix/astro-wix-hosting-adapter";
188
-
189
- // https://astro.build/config
190
- export default defineConfig({
191
- integrations: [wix(), wixPages(), react()],
192
- security: { checkOrigin: false },
193
- adapter: wixHostingAdapter(),
194
- image: { domains: ["static.wixstatic.com"] },
195
- output: "server",
196
- });
197
- `);
198
257
  const gi = join(projectDir, ".gitignore");
199
258
  const cur = existsSync(gi) ? readFileSync(gi, "utf8") : "";
200
259
  if (!/\.env/.test(cur)) writeFileSync(gi, cur + "\n# local env (pulled from Wix)\n.env.local\n.env\n");
@@ -211,15 +270,18 @@ writeFileSync(join(projectDir, ".env.local"), [
211
270
  `WIX_CLIENT_SECRET=${quote(secrets.appSecret)}`,
212
271
  "",
213
272
  ].join("\n"));
214
- emit("scaffolded", { folder: folderName, stack, template: stack === "astro" ? `${TEMPLATES_REPO}#${TEMPLATE_PATH}` : null });
273
+ emit(mode === "link" ? "linked" : mode === "config-only" ? "configured" : "scaffolded", { folder: folderName, stack, template: mode === "scaffold" && stack === "astro" ? join(TEMPLATES, verticals[0], "project") : null });
274
+ // the agent config files `wix create` writes (attach never runs the CLI's scaffold at all); fill-only
275
+ emit("agent_configs", writeAgentsMd(projectDir, { skill: basename(SKILL_ROOT), stack }));
215
276
 
216
- if (stack !== "astro") {
217
- emit("ready", { projectDir, siteId, appId, baseUrl, hosting, stack, dashboardUrl: `https://manage.wix.com/dashboard/${siteId}`,
218
- next: `scaffold the ${stack} project in this folder per SKILL.md, then deploy.mjs <vertical…> --stack ${stack} (the client id is read from wix.config.json); no seed — the site owns its content` });
277
+ if (mode !== "link" && (stack !== "astro" || mode === "config-only")) {
278
+ emit("ready", { projectDir, siteId, appId, baseUrl, hosting, frontend, stack, dashboardUrl: `https://manage.wix.com/dashboard/${siteId}`,
279
+ next: `scaffold the ${stack} project in this folder per SKILL.md, then deploy.mjs <vertical…> --stack ${stack} (the client id is read from wix.config.json); no seed — the site owns its content` +
280
+ (hosting === "self" ? `; you host it: origins on the OAuth app allow-list now: ${origins.join(", ") || "none — add them before the first checkout test"}` : "") });
219
281
  process.exit(0);
220
282
  }
221
283
 
222
- // ---- 3 · deploy shipped code + deps + lockfile ---------------------------------------------------
284
+ // ---- 3 · deploy shipped code + deps (adds nothing to a scaffold from the template) --------------
223
285
  let deployResult = {};
224
286
  {
225
287
  const deploy = spawnSync("node", [join(SKILL_ROOT, "install", "deploy.mjs"), ...verticals, "--stack", stack], { cwd: projectDir, encoding: "utf8", timeout: 60_000 });
@@ -229,12 +291,16 @@ let deployResult = {};
229
291
  emit("deployed", deployResult);
230
292
  }
231
293
 
232
- // ---- 4 · dependency install, detached -----------------------------------------------------------
233
- const installLog = join(projectDir, "npm-install.log");
234
- const logFd = openSync(installLog, "a");
235
- const install = spawn("sh", ["-c", "npm ci --ignore-scripts || npm install --ignore-scripts"], { cwd: projectDir, detached: true, stdio: ["ignore", logFd, logFd] });
236
- install.unref();
237
- emit("install_started", { log: installLog, doneMarker: "node_modules/.package-lock.json" });
294
+ // ---- 4 · dependency install, detached (any project with a package.json) --------------------------
295
+ let install = null;
296
+ if (existsSync(join(projectDir, "package.json"))) {
297
+ const installLog = join(projectDir, "npm-install.log");
298
+ const logFd = openSync(installLog, "a");
299
+ const child = spawn("sh", ["-c", existsSync(join(projectDir, "package-lock.json")) ? "npm ci --ignore-scripts || npm install --ignore-scripts" : "npm install --ignore-scripts"], { cwd: projectDir, detached: true, stdio: ["ignore", logFd, logFd] });
300
+ child.unref();
301
+ install = { log: installLog, doneMarker: "node_modules/.package-lock.json" };
302
+ emit("install_started", install);
303
+ }
238
304
 
239
305
  // ---- done ----------------------------------------------------------------------------------------
240
306
  emit("ready_for_brand_layer", {
@@ -243,11 +309,20 @@ emit("ready_for_brand_layer", {
243
309
  appId,
244
310
  baseUrl,
245
311
  hosting,
312
+ frontend,
246
313
  verticals,
247
314
  dashboardUrl: `https://manage.wix.com/dashboard/${siteId}`,
248
315
  productsUrl: deployResult.productsUrl,
249
316
  categoriesUrl: deployResult.categoriesUrl,
250
- install: { log: installLog, doneMarker: "node_modules/.package-lock.json" },
317
+ mode,
318
+ stack,
319
+ install,
251
320
  seed: null,
252
- next: "the site's content is live already — nothing to seed; read what it holds through the deployed data layer, theme SiteLayout + write the pages; wait for the install marker, build, release",
321
+ next:
322
+ "the site's content is live already — nothing to seed; get the measure of the site (SKILL.md step 3), theme + write the pages" +
323
+ (mode === "link" && hosting !== "self" ? "; make the project what its stack needs on Wix hosting (SKILL.md step 1)" : "") +
324
+ (install ? "; wait for the install marker" : "") +
325
+ (hosting === "self"
326
+ ? `; you host it — no wix release; origins on the OAuth app allow-list now: ${origins.join(", ") || "none — add them before the first checkout test"}; add the public one when it goes live`
327
+ : "; then release as step 5 says for the stack"),
253
328
  });
@@ -43,21 +43,25 @@ import {
43
43
  } from "node:fs";
44
44
  import { dirname, join, resolve } from "node:path";
45
45
  import { fileURLToPath } from "node:url";
46
+ import { templatesDir } from "./templates.mjs";
47
+ import { syncLockRoot } from "./lock.mjs";
46
48
 
47
49
  const SKILL_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..");
48
- const REF = join(SKILL_ROOT, "references");
50
+ // The shipped code: the repository's templates/ (a checkout, the cache, or fetched now).
51
+ const REF = templatesDir();
49
52
  const PROJECT = process.cwd();
50
53
  const SRC = join(PROJECT, "src");
51
54
  const CONFIG_TS = join(SRC, "wix", "config.ts");
52
55
  const PKG_JSON = join(PROJECT, "package.json");
53
56
 
54
- // The vertical registry: every directory under references/ that ships an app/ is a vertical.
57
+ // The vertical registry: every directory under templates/ that ships an app/ is a vertical.
55
58
  const VERTICALS = readdirSync(REF, { withFileTypes: true })
56
59
  .filter(
57
60
  (d) =>
58
61
  d.isDirectory() &&
59
62
  existsSync(join(REF, d.name, "app")) &&
60
- d.name !== "shared",
63
+ d.name !== "shared" &&
64
+ d.name !== "blank",
61
65
  )
62
66
  .map((d) => d.name);
63
67
 
@@ -73,8 +77,6 @@ const SHARED_DEPS = {
73
77
  };
74
78
  const CAPABILITY_DEPS = {
75
79
  "media-upload": {
76
- // All shipped Astro locks already carry @wix/media >= 1.0.271 transitively. Keep this
77
- // range compatible with them, then promote it to a root lock dependency below.
78
80
  "@wix/media": "^1.0.271",
79
81
  "@wix/essentials": "^1.0.10",
80
82
  },
@@ -179,7 +181,7 @@ const flagArgs = new Set(
179
181
  );
180
182
  const requested = [...new Set(argv.filter((a) => !flagArgs.has(a)))];
181
183
 
182
- const result = { stack, verticals: [], skillRoot: SKILL_ROOT };
184
+ const result = { stack, verticals: [], skillRoot: SKILL_ROOT, templates: REF };
183
185
 
184
186
  if (!["astro", "react", "lib", "static"].includes(stack)) {
185
187
  console.log(
@@ -362,13 +364,6 @@ if (result.verticals.length && existsSync(PKG_JSON)) {
362
364
  if (added.length)
363
365
  writeFileSync(PKG_JSON, JSON.stringify(pkg, null, 2) + "\n");
364
366
  result.depsAdded = added.map(([name]) => name);
365
- if (added.length)
366
- result.note = [
367
- result.note,
368
- "run `npm install --ignore-scripts` to pick up depsAdded",
369
- ]
370
- .filter(Boolean)
371
- .join("; ");
372
367
  } else if (result.verticals.length) {
373
368
  result.depsAdded = [];
374
369
  result.note = [
@@ -379,54 +374,20 @@ if (result.verticals.length && existsSync(PKG_JSON)) {
379
374
  .join("; ");
380
375
  }
381
376
 
382
- // ---- shipped lockfile (single vertical only) ------------------------------------------------------
383
- // A pre-resolved package-lock.json covering the scaffold + this vertical's deps ships at
384
- // references/<vertical>/lock/<stack>/package-lock.json. Placing it lets `npm ci` skip the whole
385
- // resolution phase (seconds instead of minutes). URLs are canonical registry.npmjs.org form —
386
- // npm substitutes the locally configured registry (mirrors/proxies) at fetch time. Placed only
387
- // when the project has no lock of its own; if it ever drifts out of sync, `npm ci` fails fast
388
- // and the `|| npm install` fallback self-heals.
377
+ // ---- the project's lockfile ---------------------------------------------------------------------
378
+ // A project created from a composed template (templates/<vertical>/project) carries that
379
+ // template's package-lock.json, so `npm ci` installs it without resolving. When this run added
380
+ // dependencies to package.json, the lock's root entry is brought in line where the tree already
381
+ // holds the package (install/lock.mjs); anything the tree lacks makes `npm ci` fail fast and the
382
+ // `|| npm install` fallback resolve it. A project without a lock installs with `npm install`.
389
383
  const PROJECT_LOCK = join(PROJECT, "package-lock.json");
390
- if (
391
- result.verticals.length === 1 &&
392
- existsSync(PKG_JSON) &&
393
- !existsSync(PROJECT_LOCK)
394
- ) {
395
- const shippedLock = join(
396
- REF,
397
- result.verticals[0],
398
- "lock",
399
- stack,
400
- "package-lock.json",
401
- );
402
- if (existsSync(shippedLock)) {
403
- cpSync(shippedLock, PROJECT_LOCK);
404
- if (uploadPolicies.length) {
405
- // The supplied per-vertical lock already resolves Media + Essentials transitively. Add
406
- // them to its root package entry too, so npm ci accepts package.json's new direct
407
- // dependency without falling back to a slow dependency-resolution install.
408
- const lock = JSON.parse(readFileSync(PROJECT_LOCK, "utf8"));
409
- lock.packages ??= {};
410
- lock.packages[""] ??= {};
411
- lock.packages[""].dependencies ??= {};
412
- const rootDeps = lock.packages[""].dependencies;
413
- for (const [name, range] of Object.entries(CAPABILITY_DEPS["media-upload"])) {
414
- if (!lock.packages?.[`node_modules/${name}`]) {
415
- result.lockCapability = `UNPATCHED — supplied lock lacks ${name}; npm install will resolve it`;
416
- break;
417
- }
418
- rootDeps[name] = range;
419
- }
420
- writeFileSync(PROJECT_LOCK, JSON.stringify(lock, null, 2) + "\n");
421
- if (!result.lockCapability) result.lockCapability = "media_upload_promoted";
422
- }
423
- result.lockDeployed = true;
424
- result.note = [
425
- result.note,
426
- "install with `npm ci --ignore-scripts || npm install --ignore-scripts`",
427
- ]
428
- .filter(Boolean)
429
- .join("; ");
384
+ if (result.verticals.length && existsSync(PKG_JSON)) {
385
+ if (existsSync(PROJECT_LOCK)) {
386
+ const sync = syncLockRoot(PROJECT);
387
+ if (sync && (sync.promoted.length || sync.missing.length)) result.lock = sync;
388
+ result.note = [result.note, "install with `npm ci --ignore-scripts || npm install --ignore-scripts`"].filter(Boolean).join("; ");
389
+ } else if (result.depsAdded?.length) {
390
+ result.note = [result.note, "run `npm install --ignore-scripts` to pick up depsAdded"].filter(Boolean).join("; ");
430
391
  }
431
392
  }
432
393
 
@@ -0,0 +1,55 @@
1
+ // Keep a project's package-lock.json valid for `npm ci` after package.json gained dependencies.
2
+ // `npm ci` refuses a lock whose root entry disagrees with package.json. When the dependency deploy
3
+ // added is already in the lock's tree (pulled in by something else), declaring it in the root entry
4
+ // too is all `npm ci` needs; a dependency the tree lacks is left for `npm install` to resolve.
5
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
6
+ import { join } from "node:path";
7
+
8
+ const parse = (v) => {
9
+ const m = String(v).match(/^(\d+)\.(\d+)\.(\d+)/);
10
+ return m ? m.slice(1).map(Number) : null;
11
+ };
12
+ const cmp = (a, b) => a[0] - b[0] || a[1] - b[1] || a[2] - b[2];
13
+
14
+ // The ranges deploy writes: exact, ^x.y.z, ~x.y.z, >=x.y.z. Anything else is "not known to fit".
15
+ export function satisfies(version, range) {
16
+ const v = parse(version);
17
+ const m = String(range).trim().match(/^(\^|~|>=)?\s*v?(\d+\.\d+\.\d+)/);
18
+ if (!v || !m) return false;
19
+ const r = parse(m[2]);
20
+ const op = m[1] ?? "";
21
+ if (op === "") return cmp(v, r) === 0;
22
+ if (cmp(v, r) < 0) return false;
23
+ if (op === ">=") return true;
24
+ if (op === "~") return v[0] === r[0] && v[1] === r[1];
25
+ // caret: same major; for 0.x, same minor
26
+ return r[0] > 0 ? v[0] === r[0] : v[0] === 0 && v[1] === r[1];
27
+ }
28
+
29
+ // Returns null when there is no lock; else {promoted, missing}. Writes the lock only when it changed.
30
+ export function syncLockRoot(projectDir) {
31
+ const lockPath = join(projectDir, "package-lock.json");
32
+ const pkgPath = join(projectDir, "package.json");
33
+ if (!existsSync(lockPath) || !existsSync(pkgPath)) return null;
34
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
35
+ const lock = JSON.parse(readFileSync(lockPath, "utf8"));
36
+ lock.packages ??= {};
37
+ const root = (lock.packages[""] ??= {});
38
+ const promoted = [], missing = [];
39
+ let changed = false;
40
+ for (const field of ["dependencies", "devDependencies"]) {
41
+ for (const [name, range] of Object.entries(pkg[field] ?? {})) {
42
+ if (root[field]?.[name] === range) continue;
43
+ const inTree = lock.packages[`node_modules/${name}`];
44
+ if (inTree && satisfies(inTree.version, range)) {
45
+ (root[field] ??= {})[name] = range;
46
+ promoted.push(name);
47
+ changed = true;
48
+ } else {
49
+ missing.push(name);
50
+ }
51
+ }
52
+ }
53
+ if (changed) writeFileSync(lockPath, JSON.stringify(lock, null, 2) + "\n");
54
+ return { promoted, missing };
55
+ }