@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
@@ -0,0 +1,126 @@
1
+ // The site context of a project folder — the one place that says which site a call targets.
2
+ //
3
+ // node <SKILL_ROOT>/install/context.mjs [--refresh] [--no-pull] (prints one JSON object)
4
+ //
5
+ // Two identities live in a Wix project and are the same site almost always:
6
+ // deploy — `wix.config.json` (`siteId`, `appId`): where `wix release` uploads. The CLI's business.
7
+ // content — `.env.local` (`WIX_CLIENT_ID`, what `wix env pull` writes): the app the SDK client
8
+ // runs as, on every stack (the Astro integration reads WIX_CLIENT_ID from the env and
9
+ // never the config; the other stacks get it copied into src/wix/config.ts by deploy.mjs).
10
+ // They differ on a MIGRATION PREVIEW: a project whose config points at a fresh site created only to
11
+ // host the deployment, while `.env.local` carries the credentials of the site being migrated (the
12
+ // parent) and says so. Then every admin, discovery and seed call targets the parent, the SDK client
13
+ // is the parent's, and only the release goes to the child. Completing the migration is a CLI step
14
+ // that does not exist yet; this module only reads the state.
15
+ //
16
+ // `env pull` runs here when `.env.local` is missing (or --refresh): it is the source of the content
17
+ // identity, and the Astro build refuses to run without it. Non-interactive (CI=1); a failure is
18
+ // reported in `pullError` and the config's ids stand in, so a caller can still work offline.
19
+ import { spawnSync } from "node:child_process";
20
+ import { copyFileSync, existsSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
21
+ import { tmpdir } from "node:os";
22
+ import { join } from "node:path";
23
+
24
+ // The variables `wix env pull` writes for a migration preview. The names are the platform's and are
25
+ // spelled once, here.
26
+ export const ENV = {
27
+ clientId: "WIX_CLIENT_ID",
28
+ parentSiteId: "WIX_MIGRATION_PARENT_SITE_ID",
29
+ migration: "WIX_MIGRATION",
30
+ };
31
+
32
+ /** KEY=value lines of a dotenv file, quotes stripped; null when the file is absent. */
33
+ export function readEnvFile(file) {
34
+ if (!existsSync(file)) return null;
35
+ const out = {};
36
+ for (const raw of readFileSync(file, "utf8").split(/\r?\n/)) {
37
+ const line = raw.trim();
38
+ if (!line || line.startsWith("#")) continue;
39
+ const eq = line.indexOf("=");
40
+ if (eq === -1) continue;
41
+ const key = line.slice(0, eq).trim().replace(/^export\s+/, "");
42
+ let value = line.slice(eq + 1).trim();
43
+ if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) {
44
+ value = value.slice(1, -1).replace(/\\"/g, '"');
45
+ }
46
+ out[key] = value;
47
+ }
48
+ return out;
49
+ }
50
+
51
+ export function readWixConfig(cwd) {
52
+ const file = join(cwd, "wix.config.json");
53
+ if (!existsSync(file)) return null;
54
+ try { return JSON.parse(readFileSync(file, "utf8")); } catch { return null; }
55
+ }
56
+
57
+ const truthy = (v) => typeof v === "string" && /^(1|true|yes|on)$/i.test(v.trim());
58
+
59
+ const ENV_PULL = ["-y", "@wix/cli@latest", "env", "pull"];
60
+ const runPull = (dir) => spawnSync("npx", ENV_PULL, { cwd: dir, env: { ...process.env, CI: "1" }, encoding: "utf8", timeout: 180_000 });
61
+
62
+ /**
63
+ * `wix env pull` into `cwd/.env.local`. The CLI mounts `env` only once the folder reads as an Astro
64
+ * project (an astro.config.* file, or `site.outputDirectory` in the config); a folder that holds just
65
+ * the downloaded `wix.config.json` gets "unknown command 'env'". Then the pull runs in a temp folder
66
+ * holding a copy of the config and an empty astro.config.mjs, and the `.env.local` comes back here.
67
+ */
68
+ export function pullEnv(cwd) {
69
+ const envFile = join(cwd, ".env.local");
70
+ let r = runPull(cwd);
71
+ if (r.status === 0 && existsSync(envFile)) return { ok: true, via: "in place" };
72
+ const notAProjectYet = /unknown command 'env'/.test(`${r.stderr}${r.stdout}`);
73
+ if (notAProjectYet) {
74
+ const tmp = mkdtempSync(join(tmpdir(), "wix-env-pull-"));
75
+ try {
76
+ copyFileSync(join(cwd, "wix.config.json"), join(tmp, "wix.config.json"));
77
+ writeFileSync(join(tmp, "astro.config.mjs"), "");
78
+ r = runPull(tmp);
79
+ if (r.status === 0 && existsSync(join(tmp, ".env.local"))) {
80
+ copyFileSync(join(tmp, ".env.local"), envFile);
81
+ return { ok: true, via: "stub project" };
82
+ }
83
+ } finally {
84
+ rmSync(tmp, { recursive: true, force: true });
85
+ }
86
+ }
87
+ return { ok: false, error: (r.stderr || r.stdout || "env pull produced no .env.local — is the Wix CLI logged in? (npx @wix/cli@latest whoami)").trim().slice(-400) };
88
+ }
89
+
90
+ /**
91
+ * `{ deploy: { siteId, appId }, content: { siteId, clientId }, migration: { active, parentSiteId },
92
+ * env: { file, present, pulled }, pullError?, warnings: [] }`.
93
+ * `pull`: "auto" (default) pulls when `.env.local` is missing; true always; false never.
94
+ */
95
+ export function siteContext({ cwd = process.cwd(), pull = "auto" } = {}) {
96
+ const config = readWixConfig(cwd) ?? {};
97
+ const deploy = { siteId: config.siteId ?? config.projectId ?? null, appId: config.appId ?? null };
98
+ const envFile = join(cwd, ".env.local");
99
+ let pulled = false, pullError;
100
+ if (deploy.siteId && (pull === true || (pull === "auto" && !existsSync(envFile)))) {
101
+ const r = pullEnv(cwd);
102
+ if (r.ok) pulled = r.via;
103
+ else pullError = r.error;
104
+ }
105
+ const env = readEnvFile(envFile) ?? {};
106
+ const parentSiteId = env[ENV.parentSiteId] || null;
107
+ const active = !!parentSiteId && (truthy(env[ENV.migration]) || env[ENV.migration] === undefined);
108
+ const migration = { active, parentSiteId: active ? parentSiteId : null };
109
+ const clientId = env[ENV.clientId] || deploy.appId;
110
+ const content = { siteId: active ? parentSiteId : deploy.siteId, clientId };
111
+ const warnings = [];
112
+ if (env[ENV.clientId] && deploy.appId && env[ENV.clientId] !== deploy.appId && !active) {
113
+ warnings.push(`.env.local ${ENV.clientId} differs from wix.config.json appId and no migration is declared — the SDK client runs as the env's app, the release goes to the config's site`);
114
+ }
115
+ if (active && migration.parentSiteId === deploy.siteId) {
116
+ warnings.push("the migration's parent site is the deploy site itself — nothing is being migrated");
117
+ }
118
+ return { deploy, content, migration, env: { file: envFile, present: Object.keys(env).length > 0, pulled }, ...(pullError ? { pullError } : {}), warnings };
119
+ }
120
+
121
+ // ---- CLI ----------------------------------------------------------------------------------------
122
+ if (process.argv[1] && /context\.mjs$/.test(process.argv[1])) {
123
+ const argv = process.argv.slice(2);
124
+ const pull = argv.includes("--no-pull") ? false : argv.includes("--refresh") ? true : "auto";
125
+ console.log(JSON.stringify(siteContext({ pull }), null, 2));
126
+ }
@@ -43,21 +43,26 @@ 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";
48
+ import { siteContext } from "./context.mjs";
46
49
 
47
50
  const SKILL_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..");
48
- const REF = join(SKILL_ROOT, "references");
51
+ // The shipped code: the repository's templates/ (a checkout, the cache, or fetched now).
52
+ const REF = templatesDir();
49
53
  const PROJECT = process.cwd();
50
54
  const SRC = join(PROJECT, "src");
51
55
  const CONFIG_TS = join(SRC, "wix", "config.ts");
52
56
  const PKG_JSON = join(PROJECT, "package.json");
53
57
 
54
- // The vertical registry: every directory under references/ that ships an app/ is a vertical.
58
+ // The vertical registry: every directory under templates/ that ships an app/ is a vertical.
55
59
  const VERTICALS = readdirSync(REF, { withFileTypes: true })
56
60
  .filter(
57
61
  (d) =>
58
62
  d.isDirectory() &&
59
63
  existsSync(join(REF, d.name, "app")) &&
60
- d.name !== "shared",
64
+ d.name !== "shared" &&
65
+ d.name !== "blank",
61
66
  )
62
67
  .map((d) => d.name);
63
68
 
@@ -73,12 +78,14 @@ const SHARED_DEPS = {
73
78
  };
74
79
  const CAPABILITY_DEPS = {
75
80
  "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
81
  "@wix/media": "^1.0.271",
79
82
  "@wix/essentials": "^1.0.10",
80
83
  },
84
+ "site-search": {
85
+ "@wix/search": "^1.0.90",
86
+ },
81
87
  };
88
+ const SITE_SEARCH = join("shared", "capabilities", "site-search");
82
89
  const VERTICAL_DEPS = {
83
90
  storefront: {
84
91
  core: {
@@ -158,6 +165,19 @@ const VERTICAL_DEPS = {
158
165
  "@wix/redirects": "^1.0.125",
159
166
  },
160
167
  },
168
+ faq: {
169
+ core: {
170
+ "@wix/faq": "^1.0.76",
171
+ },
172
+ // no astro block: the FAQ page is a plain page (no wixMetadata item routing); its JSON-LD is inline
173
+ },
174
+ donations: {
175
+ core: {
176
+ "@wix/donations": "^1.0.64",
177
+ "@wix/ecom": "^1.0.2454",
178
+ "@wix/redirects": "^1.0.125",
179
+ },
180
+ },
161
181
  };
162
182
 
163
183
  const COPY = { recursive: true, force: false, errorOnExist: false };
@@ -179,7 +199,7 @@ const flagArgs = new Set(
179
199
  );
180
200
  const requested = [...new Set(argv.filter((a) => !flagArgs.has(a)))];
181
201
 
182
- const result = { stack, verticals: [], skillRoot: SKILL_ROOT };
202
+ const result = { stack, verticals: [], skillRoot: SKILL_ROOT, templates: REF };
183
203
 
184
204
  if (!["astro", "react", "lib", "static"].includes(stack)) {
185
205
  console.log(
@@ -209,6 +229,27 @@ if (!Array.isArray(uploadPolicies)) {
209
229
  console.log(JSON.stringify({ error: "plan.capabilities.mediaUpload.policies must be an array" }));
210
230
  process.exit(1);
211
231
  }
232
+ // Site search is on when the plan carries the entry (`{}` is enough; `true` too). Its fields are
233
+ // data for the generated config; the shipped core drops unknown type names, so only shapes are checked.
234
+ const siteSearchEntry = plan.capabilities?.siteSearch;
235
+ const siteSearch = siteSearchEntry === true ? {} : siteSearchEntry && typeof siteSearchEntry === "object" ? siteSearchEntry : null;
236
+ if (siteSearchEntry != null && siteSearchEntry !== false && !siteSearch) {
237
+ console.log(JSON.stringify({ error: "plan.capabilities.siteSearch must be an object (or true)" }));
238
+ process.exit(1);
239
+ }
240
+ if (siteSearch) {
241
+ const strings = (v) => Array.isArray(v) && v.every((x) => typeof x === "string");
242
+ const map = (v) => v === undefined || (v && typeof v === "object" && !Array.isArray(v) && Object.values(v).every((x) => typeof x === "string"));
243
+ if ((siteSearch.types !== undefined && !strings(siteSearch.types)) || !map(siteSearch.routes) || !map(siteSearch.labels)) {
244
+ console.log(JSON.stringify({ error: "plan.capabilities.siteSearch: types must be string[]; routes and labels must be objects of strings" }));
245
+ process.exit(1);
246
+ }
247
+ }
248
+ // The generated file is data only; the shipped core resolves defaults (types, routes, labels) from it.
249
+ const siteSearchConfigSource = () =>
250
+ `// Generated by wix-headless-fast install/deploy.mjs from plan.capabilities.siteSearch.\n` +
251
+ `// Edit the plan and redeploy. Defaults for anything omitted are in search-core.ts (resolveConfig).\n` +
252
+ `export const siteSearchPlan = ${JSON.stringify(siteSearch, null, 2)};\n`;
212
253
  // ---- static stack: the REST layer, composed flat and stripped ------------------------------------
213
254
  if (stack === "static") {
214
255
  const { spawnSync } = await import("node:child_process");
@@ -216,10 +257,9 @@ if (stack === "static") {
216
257
  const OUT = outDir ? resolve(PROJECT, outDir) : PROJECT;
217
258
  const JS = join(OUT, "js", "wix");
218
259
  result.out = outDir ?? ".";
219
- let clientId = clientIdFlag;
220
- if (!clientId && existsSync(join(PROJECT, "wix.config.json"))) {
221
- clientId = JSON.parse(readFileSync(join(PROJECT, "wix.config.json"), "utf8")).appId ?? null;
222
- }
260
+ // The client id the browser mints visitor tokens with: --client-id, else the CONTENT app from
261
+ // .env.local (`wix env pull`; on a migration preview the parent site's app), else the config's appId.
262
+ let clientId = clientIdFlag ?? (existsSync(join(PROJECT, "wix.config.json")) ? siteContext({ cwd: PROJECT }).content.clientId : null);
223
263
  if (!clientId) {
224
264
  console.log(JSON.stringify({ error: "static stack needs the public OAuth client id — run `npm create @wix/new@latest init` here first, or pass --client-id" }));
225
265
  process.exit(1);
@@ -231,19 +271,23 @@ if (stack === "static") {
231
271
  }
232
272
  // Only files that aren't there yet — a re-run restores, never clobbers (same as the copy below).
233
273
  cpSync(join(REF, "shared", "rest"), JS, COPY);
234
- for (const vertical of requested) {
235
- cpSync(join(REF, vertical, "rest"), JS, COPY);
274
+ // Every layer with a rest/ twin: the requested verticals, plus the site-search capability when the
275
+ // plan turns it on (same shape — rest/ beside app/wix/<name>/ — at templates/shared/capabilities).
276
+ const layers = requested.map((vertical) => [vertical, join(REF, vertical)]);
277
+ if (siteSearch) layers.push(["site-search", join(REF, SITE_SEARCH)]);
278
+ for (const [vertical, root] of layers) {
279
+ cpSync(join(root, "rest"), JS, COPY);
236
280
  // The vertical's transport-agnostic core: types, every *-core.ts, and every *-store.ts under its
237
281
  // app/wix/<vertical>/ — the stores are the hooks' logic without React, over the same function
238
282
  // names the REST twin exports, so they run against it unchanged.
239
- const appWix = join(REF, vertical, "app", "wix", vertical);
283
+ const appWix = join(root, "app", "wix", vertical);
240
284
  for (const f of readdirSync(appWix)) {
241
285
  // Every vertical has a types.ts; flat in one folder they would collide, so each lands as
242
286
  // <vertical>-types.ts and the vertical's own files are pointed at it below.
243
287
  if (f === "types.ts") cpSync(join(appWix, f), join(JS, `${vertical}-types.ts`), COPY);
244
288
  else if (f.endsWith("-core.ts") || f.endsWith("-store.ts")) cpSync(join(appWix, f), join(JS, f), COPY);
245
289
  }
246
- const own = new Set([...readdirSync(join(REF, vertical, "rest")), ...readdirSync(appWix)].filter((f) => f.endsWith(".ts") && f !== "types.ts"));
290
+ const own = new Set([...readdirSync(join(root, "rest")), ...readdirSync(appWix)].filter((f) => f.endsWith(".ts") && f !== "types.ts"));
247
291
  for (const f of own) {
248
292
  const fp = join(JS, f);
249
293
  if (!existsSync(fp)) continue;
@@ -251,7 +295,12 @@ if (stack === "static") {
251
295
  const fixed = src.replace(/from\s+"\.\/types(?:\.js)?"/g, `from "./${vertical}-types.js"`);
252
296
  if (fixed !== src) writeFileSync(fp, fixed);
253
297
  }
254
- result.verticals.push(vertical);
298
+ if (VERTICALS.includes(vertical)) result.verticals.push(vertical);
299
+ }
300
+ if (siteSearch) {
301
+ // The REST twin imports the plan as data from beside it (shared/rest already owns config.ts).
302
+ writeFileSync(join(JS, "site-search-config.generated.ts"), siteSearchConfigSource());
303
+ result.capabilities = { ...result.capabilities, siteSearch: true };
255
304
  }
256
305
  // Browser ESM resolves nothing: every relative import needs its .js. The rest/ files are written
257
306
  // that way; the files borrowed from app/wix/ are bundler-style and get the suffix here.
@@ -284,7 +333,7 @@ if (stack === "static") {
284
333
  result.js = `${outDir ? outDir.replace(/\/$/, "") + "/" : ""}js/wix/*.js`;
285
334
  // The note lists what actually landed, so it holds for every vertical (and several at once).
286
335
  const stores = readdirSync(JS).filter((f) => f.endsWith("-store.js")).map((f) => `./js/wix/${f}`);
287
- const dataFiles = readdirSync(JS).filter((f) => f.endsWith(".js") && !f.endsWith("-store.js") && !f.endsWith("-core.js") && !f.endsWith("-types.js") && !["client.js", "config.js", "media.js"].includes(f)).map((f) => `./js/wix/${f}`);
336
+ const dataFiles = readdirSync(JS).filter((f) => f.endsWith(".js") && !f.endsWith("-store.js") && !f.endsWith("-core.js") && !f.endsWith("-types.js") && !f.endsWith(".generated.js") && !["client.js", "config.js", "media.js"].includes(f)).map((f) => `./js/wix/${f}`);
288
337
  result.note = `import the data layer (${dataFiles.join(", ")})${stores.length ? ` and the stores (${stores.join(", ")})` : ""} relative to ${outDir ?? "the project root"} in a <script type="module">; the .ts beside them are the same files with types, for reading; point wix.config.json site.outputDirectory at "./${outDir ?? "."}"`;
289
338
  console.log(JSON.stringify(result));
290
339
  process.exit(0);
@@ -317,11 +366,20 @@ if (uploadPolicies.length) {
317
366
  cpSync(join(REF, "shared", "capabilities", "media-upload", "app"), SRC, COPY);
318
367
  cpSync(join(REF, "shared", "capabilities", "media-upload", "app-astro"), SRC, COPY);
319
368
  }
369
+ // Site search ships like a vertical (data layer, stores, hooks, components, a search page) at a
370
+ // disjoint path (src/wix/site-search/, src/components/site-search/, …), so the same per-stack rule
371
+ // applies: lib takes only app/wix/, astro adds app-astro/.
372
+ if (siteSearch) {
373
+ if (stack === "lib") cpSync(join(REF, SITE_SEARCH, "app", "wix"), join(SRC, "wix"), COPY);
374
+ else cpSync(join(REF, SITE_SEARCH, "app"), SRC, COPY);
375
+ if (stack === "astro") cpSync(join(REF, SITE_SEARCH, "app-astro"), SRC, COPY);
376
+ }
320
377
 
321
378
  const unknown = requested.filter((v) => !VERTICALS.includes(v));
322
379
  // lib: only @wix/sdk from the shared deps — the Tailwind pair serves the components, which don't ship there.
323
380
  const wantedDeps = stack === "lib" ? { "@wix/sdk": SHARED_DEPS["@wix/sdk"] } : { ...SHARED_DEPS };
324
381
  if (uploadPolicies.length) Object.assign(wantedDeps, CAPABILITY_DEPS["media-upload"]);
382
+ if (siteSearch) Object.assign(wantedDeps, CAPABILITY_DEPS["site-search"]);
325
383
  for (const vertical of requested.filter((v) => VERTICALS.includes(v))) {
326
384
  if (stack === "lib") cpSync(join(REF, vertical, "app", "wix"), join(SRC, "wix"), COPY);
327
385
  else cpSync(join(REF, vertical, "app"), SRC, COPY);
@@ -349,6 +407,15 @@ if (uploadPolicies.length) {
349
407
  );
350
408
  result.capabilities = { mediaUpload: uploadPolicies.map((policy) => policy.id) };
351
409
  }
410
+ if (siteSearch) {
411
+ // The SDK transport imports the plan as data from beside it; defaults resolve in the shipped core.
412
+ writeFileSync(join(SRC, "wix", "site-search", "config.generated.ts"), siteSearchConfigSource());
413
+ result.capabilities = { ...result.capabilities, siteSearch: true };
414
+ if (siteSearch.install) {
415
+ // Indexing needs the Wix Site Search app on the site — a site mutation the deploy never makes.
416
+ result.note = [result.note, "siteSearch.install: run `node <SKILL_ROOT>/templates/shared/capabilities/site-search/seed/install.mjs` from the project root after the seed (results appear about half a minute later)"].filter(Boolean).join("; ");
417
+ }
418
+ }
352
419
 
353
420
  // ---- dependency patch (fill-only) ----------------------------------------------------------------
354
421
  if (result.verticals.length && existsSync(PKG_JSON)) {
@@ -362,13 +429,6 @@ if (result.verticals.length && existsSync(PKG_JSON)) {
362
429
  if (added.length)
363
430
  writeFileSync(PKG_JSON, JSON.stringify(pkg, null, 2) + "\n");
364
431
  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
432
  } else if (result.verticals.length) {
373
433
  result.depsAdded = [];
374
434
  result.note = [
@@ -379,54 +439,20 @@ if (result.verticals.length && existsSync(PKG_JSON)) {
379
439
  .join("; ");
380
440
  }
381
441
 
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.
442
+ // ---- the project's lockfile ---------------------------------------------------------------------
443
+ // A project created from a composed template (templates/<vertical>/project) carries that
444
+ // template's package-lock.json, so `npm ci` installs it without resolving. When this run added
445
+ // dependencies to package.json, the lock's root entry is brought in line where the tree already
446
+ // holds the package (install/lock.mjs); anything the tree lacks makes `npm ci` fail fast and the
447
+ // `|| npm install` fallback resolve it. A project without a lock installs with `npm install`.
389
448
  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("; ");
449
+ if (result.verticals.length && existsSync(PKG_JSON)) {
450
+ if (existsSync(PROJECT_LOCK)) {
451
+ const sync = syncLockRoot(PROJECT);
452
+ if (sync && (sync.promoted.length || sync.missing.length)) result.lock = sync;
453
+ result.note = [result.note, "install with `npm ci --ignore-scripts || npm install --ignore-scripts`"].filter(Boolean).join("; ");
454
+ } else if (result.depsAdded?.length) {
455
+ result.note = [result.note, "run `npm install --ignore-scripts` to pick up depsAdded"].filter(Boolean).join("; ");
430
456
  }
431
457
  }
432
458
 
@@ -455,12 +481,15 @@ if (stack === "astro" && result.verticals.length && existsSync(ASTRO_CONFIG)) {
455
481
 
456
482
  // ---- ready-made links -----------------------------------------------------------------------------
457
483
  // Emit the siteId and the dashboard deep links so nothing downstream re-derives or retypes them.
484
+ // The site the links point at is the CONTENT site — the parent on a migration preview, where the
485
+ // config's site only hosts the deployment (install/context.mjs).
458
486
  const WIX_CONFIG = join(PROJECT, "wix.config.json");
459
- if (existsSync(WIX_CONFIG)) {
460
- const config = JSON.parse(readFileSync(WIX_CONFIG, "utf8"));
461
- const siteId = config.siteId ?? config.projectId;
487
+ const ctx = existsSync(WIX_CONFIG) ? siteContext({ cwd: PROJECT }) : null;
488
+ if (ctx) {
489
+ const siteId = ctx.content.siteId;
462
490
  if (siteId) {
463
491
  result.siteId = siteId;
492
+ if (ctx.migration.active) result.migration = { parentSiteId: ctx.migration.parentSiteId, deploySiteId: ctx.deploy.siteId };
464
493
  result.dashboardUrl = `https://manage.wix.com/dashboard/${siteId}`;
465
494
  if (result.verticals.includes("storefront")) {
466
495
  result.productsUrl = `https://manage.wix.com/dashboard/${siteId}/wix-stores/products`;
@@ -479,13 +508,10 @@ if (!requested.length) {
479
508
  // ---- client ids ---------------------------------------------------------------------------------
480
509
  // The shared data client is ambient on managed Astro. Members are different: their shipped
481
510
  // custom credential flow always needs an explicit public OAuth client, including on Astro.
482
- let clientId = clientIdFlag;
483
- if (!clientId && existsSync(join(PROJECT, "wix.config.json"))) {
484
- // On a Wix-managed project the public OAuth client id IS the appId.
485
- clientId =
486
- JSON.parse(readFileSync(join(PROJECT, "wix.config.json"), "utf8")).appId ??
487
- null;
488
- }
511
+ // --client-id, else the CONTENT app: .env.local's WIX_CLIENT_ID (what `wix env pull` writes — on a
512
+ // migration preview the parent site's app, the one the Astro integration itself runs as), else the
513
+ // config's appId. Never the config first: on a preview that is the deploy-only child app.
514
+ const clientId = clientIdFlag ?? ctx?.content.clientId ?? null;
489
515
  if (stack === "react" || stack === "lib") {
490
516
  if (clientId) {
491
517
  const current = readFileSync(CONFIG_TS, "utf8");
@@ -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
+ }