@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.
- package/package.json +1 -1
- package/skills/wix-app/SKILL.md +71 -113
- package/skills/wix-app/references/APP_TOOLS.md +2 -1
- package/skills/wix-app/references/BACKEND_EVENT.md +3 -3
- package/skills/wix-app/references/CUSTOM_ELEMENT_WIDGET.md +41 -152
- package/skills/wix-app/references/DASHBOARD_MODAL.md +4 -4
- package/skills/wix-app/references/DASHBOARD_PAGE.md +11 -25
- package/skills/wix-app/references/DATA_COLLECTION.md +16 -219
- package/skills/wix-app/references/SDK_MODULE_MAP.md +44 -0
- package/skills/wix-app/references/SITE_PLUGIN.md +36 -190
- package/skills/wix-app/references/app-tools/TOOLS.md +3 -1
- package/skills/wix-app/references/custom-element-widget/SETTINGS_PANEL.md +21 -0
- package/skills/wix-app/references/dashboard-page/DATA_SOURCES.md +182 -0
- package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE.md +97 -0
- package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_COLLECTION.md +184 -0
- package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_ROUTER.md +203 -0
- package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_SETTINGS.md +44 -0
- package/skills/wix-app/references/dashboard-page/ECOM_NAVIGATION.md +17 -0
- package/skills/wix-app/references/dashboard-page/QUERY_AND_PAGING.md +182 -0
- package/skills/wix-app/references/dashboard-page/TABLE_STATE.md +133 -0
- package/skills/wix-app/references/dashboard-page/UX_SUCCESS_MODEL.md +10 -5
- package/skills/wix-app/references/dashboard-plugin/SLOTS.md +4 -18
- package/skills/wix-app/references/data-collection/LIFECYCLE.md +68 -0
- package/skills/wix-app/references/data-collection/PERMISSIONS.md +47 -0
- package/skills/wix-app/references/data-collection/SCHEMA.md +181 -0
- package/skills/wix-app/references/data-collection/WIX_DATA.md +38 -66
- package/skills/wix-app/references/site-plugin/EXAMPLES.md +1 -1
- package/skills/wix-headless-fast/SKILL.md +144 -221
- package/skills/wix-headless-fast/cold-start/bootstrap.mjs +156 -0
- package/skills/wix-headless-fast/{entry/skill.md → cold-start/cold-start.md} +15 -15
- package/skills/wix-headless-fast/guides/existing-site.md +76 -0
- package/skills/wix-headless-fast/guides/reference-mode.md +97 -0
- package/skills/wix-headless-fast/install/AGENTS.md +35 -0
- package/skills/wix-headless-fast/install/agents-md.mjs +39 -0
- package/skills/wix-headless-fast/install/attach.mjs +161 -86
- package/skills/wix-headless-fast/install/deploy.mjs +21 -60
- package/skills/wix-headless-fast/install/lock.mjs +55 -0
- package/skills/wix-headless-fast/install/setup.mjs +259 -0
- package/skills/wix-headless-fast/install/templates.mjs +168 -0
- package/skills/wix-manage/references/ecommerce/pricing-promotions/ecom-pricing-create-coupon.md +10 -19
- package/skills/wix-manage/references/events/create-wix-event.md +5 -1
- package/skills/wix-manage/references/google-ads/google-ads-dashboard-navigation.md +27 -0
- package/skills/wix-manage/references/google-ads/manage-campaign-success-guide.md +83 -37
- package/skills/wix-headless-fast/install/fast-path.mjs +0 -181
- package/skills/wix-headless-fast/references/blog/INSTRUCTIONS.md +0 -301
- package/skills/wix-headless-fast/references/blog/app/components/blog/BlogFeedView.tsx +0 -136
- package/skills/wix-headless-fast/references/blog/app/components/blog/PostView.tsx +0 -112
- package/skills/wix-headless-fast/references/blog/app/components/blog/RichContent.tsx +0 -42
- package/skills/wix-headless-fast/references/blog/app/hooks/blog/useBlogFeed.ts +0 -31
- package/skills/wix-headless-fast/references/blog/app/hooks/blog/usePost.ts +0 -22
- package/skills/wix-headless-fast/references/blog/app/wix/blog/blog-feed-store.ts +0 -137
- package/skills/wix-headless-fast/references/blog/app/wix/blog/post-store.ts +0 -78
- package/skills/wix-headless-fast/references/blog/app/wix/blog/posts-core.ts +0 -117
- package/skills/wix-headless-fast/references/blog/app/wix/blog/posts.ts +0 -52
- package/skills/wix-headless-fast/references/blog/app/wix/blog/taxonomy-core.ts +0 -47
- package/skills/wix-headless-fast/references/blog/app/wix/blog/taxonomy.ts +0 -58
- package/skills/wix-headless-fast/references/blog/app/wix/blog/types.ts +0 -62
- package/skills/wix-headless-fast/references/blog/app-astro/layouts/SiteLayout.astro +0 -40
- package/skills/wix-headless-fast/references/blog/app-astro/pages/blog/[...slug].astro +0 -97
- package/skills/wix-headless-fast/references/blog/app-astro/pages/blog.astro +0 -24
- package/skills/wix-headless-fast/references/blog/lock/astro/package-lock.json +0 -16156
- package/skills/wix-headless-fast/references/blog/rest/posts.ts +0 -42
- package/skills/wix-headless-fast/references/blog/rest/taxonomy.ts +0 -62
- package/skills/wix-headless-fast/references/blog/seed/SEED.md +0 -81
- package/skills/wix-headless-fast/references/blog/seed/seed-blog.mjs +0 -287
- package/skills/wix-headless-fast/references/bookings/INSTRUCTIONS.md +0 -275
- package/skills/wix-headless-fast/references/bookings/app/components/bookings/ServiceBookingView.tsx +0 -144
- package/skills/wix-headless-fast/references/bookings/app/components/bookings/ServicesView.tsx +0 -119
- package/skills/wix-headless-fast/references/bookings/app/hooks/bookings/useBookingFlow.ts +0 -32
- package/skills/wix-headless-fast/references/bookings/app/hooks/bookings/useServices.ts +0 -23
- package/skills/wix-headless-fast/references/bookings/app/wix/bookings/booking-core.ts +0 -218
- package/skills/wix-headless-fast/references/bookings/app/wix/bookings/booking-flow-store.ts +0 -169
- package/skills/wix-headless-fast/references/bookings/app/wix/bookings/booking.ts +0 -121
- package/skills/wix-headless-fast/references/bookings/app/wix/bookings/services-core.ts +0 -92
- package/skills/wix-headless-fast/references/bookings/app/wix/bookings/services-store.ts +0 -90
- package/skills/wix-headless-fast/references/bookings/app/wix/bookings/services.ts +0 -57
- package/skills/wix-headless-fast/references/bookings/app/wix/bookings/types.ts +0 -72
- package/skills/wix-headless-fast/references/bookings/app-astro/layouts/SiteLayout.astro +0 -40
- package/skills/wix-headless-fast/references/bookings/app-astro/pages/services/[slug].astro +0 -76
- package/skills/wix-headless-fast/references/bookings/app-astro/pages/services.astro +0 -22
- package/skills/wix-headless-fast/references/bookings/lock/astro/package-lock.json +0 -11962
- package/skills/wix-headless-fast/references/bookings/rest/booking.ts +0 -113
- package/skills/wix-headless-fast/references/bookings/rest/services.ts +0 -55
- package/skills/wix-headless-fast/references/bookings/seed/SEED.md +0 -71
- package/skills/wix-headless-fast/references/bookings/seed/seed-bookings.mjs +0 -302
- package/skills/wix-headless-fast/references/cms/INSTRUCTIONS.md +0 -353
- package/skills/wix-headless-fast/references/cms/app/hooks/cms/useCollection.ts +0 -50
- package/skills/wix-headless-fast/references/cms/app/hooks/cms/useItem.ts +0 -37
- package/skills/wix-headless-fast/references/cms/app/wix/cms/collection-store.ts +0 -158
- package/skills/wix-headless-fast/references/cms/app/wix/cms/item-store.ts +0 -93
- package/skills/wix-headless-fast/references/cms/app/wix/cms/items-core.ts +0 -177
- package/skills/wix-headless-fast/references/cms/app/wix/cms/items.ts +0 -123
- package/skills/wix-headless-fast/references/cms/app/wix/cms/types.ts +0 -75
- package/skills/wix-headless-fast/references/cms/app-astro/layouts/SiteLayout.astro +0 -41
- package/skills/wix-headless-fast/references/cms/lock/astro/package-lock.json +0 -11262
- package/skills/wix-headless-fast/references/cms/rest/items.ts +0 -125
- package/skills/wix-headless-fast/references/cms/seed/SEED.md +0 -112
- package/skills/wix-headless-fast/references/cms/seed/seed-cms.mjs +0 -324
- package/skills/wix-headless-fast/references/events/INSTRUCTIONS.md +0 -305
- package/skills/wix-headless-fast/references/events/app/components/events/EventConfirmationView.tsx +0 -66
- package/skills/wix-headless-fast/references/events/app/components/events/EventRegistrationView.tsx +0 -178
- package/skills/wix-headless-fast/references/events/app/components/events/EventsView.tsx +0 -118
- package/skills/wix-headless-fast/references/events/app/hooks/events/useEventRegistration.ts +0 -35
- package/skills/wix-headless-fast/references/events/app/hooks/events/useEvents.ts +0 -24
- package/skills/wix-headless-fast/references/events/app/wix/events/events-core.ts +0 -130
- package/skills/wix-headless-fast/references/events/app/wix/events/events-store.ts +0 -97
- package/skills/wix-headless-fast/references/events/app/wix/events/events.ts +0 -55
- package/skills/wix-headless-fast/references/events/app/wix/events/registration-core.ts +0 -113
- package/skills/wix-headless-fast/references/events/app/wix/events/registration-store.ts +0 -156
- package/skills/wix-headless-fast/references/events/app/wix/events/registration.ts +0 -97
- package/skills/wix-headless-fast/references/events/app/wix/events/types.ts +0 -61
- package/skills/wix-headless-fast/references/events/app-astro/layouts/SiteLayout.astro +0 -40
- package/skills/wix-headless-fast/references/events/app-astro/pages/event-confirmation.astro +0 -12
- package/skills/wix-headless-fast/references/events/app-astro/pages/events/[slug].astro +0 -80
- package/skills/wix-headless-fast/references/events/app-astro/pages/events.astro +0 -21
- package/skills/wix-headless-fast/references/events/lock/astro/package-lock.json +0 -11884
- package/skills/wix-headless-fast/references/events/rest/events.ts +0 -57
- package/skills/wix-headless-fast/references/events/rest/registration.ts +0 -83
- package/skills/wix-headless-fast/references/events/seed/SEED.md +0 -95
- package/skills/wix-headless-fast/references/events/seed/seed-events.mjs +0 -276
- package/skills/wix-headless-fast/references/forms/INSTRUCTIONS.md +0 -338
- package/skills/wix-headless-fast/references/forms/app/hooks/forms/useWixForm.ts +0 -85
- package/skills/wix-headless-fast/references/forms/app/wix/forms/form-store.ts +0 -332
- package/skills/wix-headless-fast/references/forms/app/wix/forms/forms-core.ts +0 -238
- package/skills/wix-headless-fast/references/forms/app/wix/forms/forms.ts +0 -54
- package/skills/wix-headless-fast/references/forms/app/wix/forms/submissions-core.ts +0 -216
- package/skills/wix-headless-fast/references/forms/app/wix/forms/submissions.ts +0 -59
- package/skills/wix-headless-fast/references/forms/app/wix/forms/types.ts +0 -135
- package/skills/wix-headless-fast/references/forms/lock/astro/package-lock.json +0 -10593
- package/skills/wix-headless-fast/references/forms/rest/forms.ts +0 -34
- package/skills/wix-headless-fast/references/forms/rest/submissions.ts +0 -56
- package/skills/wix-headless-fast/references/forms/seed/SEED.md +0 -116
- package/skills/wix-headless-fast/references/forms/seed/seed-forms.mjs +0 -327
- package/skills/wix-headless-fast/references/members/INSTRUCTIONS.md +0 -314
- package/skills/wix-headless-fast/references/members/app/components/members/AccountView.tsx +0 -60
- package/skills/wix-headless-fast/references/members/app/components/members/LoginForm.tsx +0 -155
- package/skills/wix-headless-fast/references/members/app/components/members/MemberMenu.tsx +0 -78
- package/skills/wix-headless-fast/references/members/app/components/members/RequireAuth.tsx +0 -47
- package/skills/wix-headless-fast/references/members/app/hooks/members/useMember.ts +0 -66
- package/skills/wix-headless-fast/references/members/app/wix/members/auth-core.ts +0 -105
- package/skills/wix-headless-fast/references/members/app/wix/members/auth.ts +0 -59
- package/skills/wix-headless-fast/references/members/app/wix/members/client.ts +0 -53
- package/skills/wix-headless-fast/references/members/app/wix/members/member-store.ts +0 -122
- package/skills/wix-headless-fast/references/members/app/wix/members/members-core.ts +0 -43
- package/skills/wix-headless-fast/references/members/app/wix/members/members.ts +0 -29
- package/skills/wix-headless-fast/references/members/app/wix/members/types.ts +0 -21
- package/skills/wix-headless-fast/references/members/app-astro/layouts/SiteLayout.astro +0 -42
- package/skills/wix-headless-fast/references/members/app-astro/pages/account.astro +0 -10
- package/skills/wix-headless-fast/references/members/app-astro/pages/login.astro +0 -11
- package/skills/wix-headless-fast/references/members/lock/astro/package-lock.json +0 -10329
- package/skills/wix-headless-fast/references/members/rest/auth.ts +0 -215
- package/skills/wix-headless-fast/references/members/rest/members.ts +0 -26
- package/skills/wix-headless-fast/references/members/seed/SEED.md +0 -39
- package/skills/wix-headless-fast/references/members/seed/seed-members.mjs +0 -94
- package/skills/wix-headless-fast/references/portfolio/INSTRUCTIONS.md +0 -313
- package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/CollectionProjectsView.tsx +0 -110
- package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/CollectionsView.tsx +0 -90
- package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/GalleryMedia.tsx +0 -35
- package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/ProjectDetailView.tsx +0 -85
- package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useCollectionProjects.ts +0 -32
- package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useCollections.ts +0 -21
- package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useProjectDetail.ts +0 -31
- package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/collection-projects-store.ts +0 -82
- package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/collections-store.ts +0 -58
- package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/portfolio-core.ts +0 -177
- package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/portfolio.ts +0 -78
- package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/project-detail-store.ts +0 -81
- package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/types.ts +0 -55
- package/skills/wix-headless-fast/references/portfolio/app-astro/layouts/SiteLayout.astro +0 -40
- package/skills/wix-headless-fast/references/portfolio/app-astro/pages/portfolio/[slug].astro +0 -30
- package/skills/wix-headless-fast/references/portfolio/app-astro/pages/portfolio.astro +0 -21
- package/skills/wix-headless-fast/references/portfolio/app-astro/pages/projects/[slug].astro +0 -29
- package/skills/wix-headless-fast/references/portfolio/lock/astro/package-lock.json +0 -10197
- package/skills/wix-headless-fast/references/portfolio/rest/portfolio.ts +0 -75
- package/skills/wix-headless-fast/references/portfolio/seed/SEED.md +0 -86
- package/skills/wix-headless-fast/references/portfolio/seed/seed-portfolio.mjs +0 -258
- package/skills/wix-headless-fast/references/pricing-plans/INSTRUCTIONS.md +0 -294
- package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/PlanDetailView.tsx +0 -47
- package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/PlansView.tsx +0 -101
- package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/SubscribeButton.tsx +0 -41
- package/skills/wix-headless-fast/references/pricing-plans/app/hooks/pricing-plans/usePlanPurchase.ts +0 -16
- package/skills/wix-headless-fast/references/pricing-plans/app/hooks/pricing-plans/usePlans.ts +0 -22
- package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plan-purchase-store.ts +0 -54
- package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plans-core.ts +0 -106
- package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plans-store.ts +0 -64
- package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plans.ts +0 -27
- package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/purchase-core.ts +0 -43
- package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/purchase.ts +0 -22
- package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/types.ts +0 -30
- package/skills/wix-headless-fast/references/pricing-plans/app-astro/layouts/SiteLayout.astro +0 -41
- package/skills/wix-headless-fast/references/pricing-plans/app-astro/pages/plans/[slug].astro +0 -40
- package/skills/wix-headless-fast/references/pricing-plans/app-astro/pages/plans.astro +0 -21
- package/skills/wix-headless-fast/references/pricing-plans/lock/astro/package-lock.json +0 -11226
- package/skills/wix-headless-fast/references/pricing-plans/rest/plans.ts +0 -31
- package/skills/wix-headless-fast/references/pricing-plans/rest/purchase.ts +0 -20
- package/skills/wix-headless-fast/references/pricing-plans/seed/SEED.md +0 -79
- package/skills/wix-headless-fast/references/pricing-plans/seed/seed-pricing-plans.mjs +0 -279
- package/skills/wix-headless-fast/references/restaurants/INSTRUCTIONS.md +0 -358
- package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/MenuView.tsx +0 -142
- package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/OrderCartButton.tsx +0 -26
- package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/OrderCartDrawer.tsx +0 -121
- package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/ReservationView.tsx +0 -155
- package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useMenus.ts +0 -34
- package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useOrderCart.ts +0 -43
- package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useReservation.ts +0 -34
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/menu-core.ts +0 -155
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/menu-store.ts +0 -89
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/menu.ts +0 -71
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/order-store.ts +0 -103
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/ordering-core.ts +0 -124
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/ordering.ts +0 -185
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/reservation-store.ts +0 -193
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/reservations-core.ts +0 -94
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/reservations.ts +0 -74
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/types.ts +0 -168
- package/skills/wix-headless-fast/references/restaurants/app-astro/layouts/SiteLayout.astro +0 -47
- package/skills/wix-headless-fast/references/restaurants/app-astro/pages/menu.astro +0 -22
- package/skills/wix-headless-fast/references/restaurants/app-astro/pages/reservations.astro +0 -12
- package/skills/wix-headless-fast/references/restaurants/lock/astro/package-lock.json +0 -12560
- package/skills/wix-headless-fast/references/restaurants/rest/menu.ts +0 -60
- package/skills/wix-headless-fast/references/restaurants/rest/ordering.ts +0 -169
- package/skills/wix-headless-fast/references/restaurants/rest/reservations.ts +0 -68
- package/skills/wix-headless-fast/references/restaurants/seed/SEED.md +0 -89
- package/skills/wix-headless-fast/references/restaurants/seed/seed-restaurants.mjs +0 -479
- package/skills/wix-headless-fast/references/shared/CONTENT.md +0 -22
- package/skills/wix-headless-fast/references/shared/CUSTOM_OPERATIONS.md +0 -73
- package/skills/wix-headless-fast/references/shared/DESIGN.md +0 -26
- package/skills/wix-headless-fast/references/shared/SUPPLIED-CONTENT.md +0 -23
- package/skills/wix-headless-fast/references/shared/app/styles/global.css +0 -52
- package/skills/wix-headless-fast/references/shared/app/wix/config.ts +0 -15
- package/skills/wix-headless-fast/references/shared/app/wix/media.ts +0 -81
- package/skills/wix-headless-fast/references/shared/app/wix/money.ts +0 -24
- package/skills/wix-headless-fast/references/shared/app/wix/sdk.ts +0 -89
- package/skills/wix-headless-fast/references/shared/capabilities/media-upload/app/wix/media-upload/client.ts +0 -46
- package/skills/wix-headless-fast/references/shared/capabilities/media-upload/app-astro/pages/api/wix/media-upload.ts +0 -46
- package/skills/wix-headless-fast/references/shared/rest/client.ts +0 -155
- package/skills/wix-headless-fast/references/shared/rest/config.ts +0 -3
- package/skills/wix-headless-fast/references/shared/rest/media.ts +0 -65
- package/skills/wix-headless-fast/references/shared/seed/images.mjs +0 -145
- package/skills/wix-headless-fast/references/storefront/INSTRUCTIONS.md +0 -608
- package/skills/wix-headless-fast/references/storefront/app/components/storefront/CartButton.tsx +0 -26
- package/skills/wix-headless-fast/references/storefront/app/components/storefront/CartDrawer.tsx +0 -155
- package/skills/wix-headless-fast/references/storefront/app/components/storefront/FilterPanel.tsx +0 -266
- package/skills/wix-headless-fast/references/storefront/app/components/storefront/OptionPicker.tsx +0 -95
- package/skills/wix-headless-fast/references/storefront/app/components/storefront/QuickAdd.tsx +0 -136
- package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useCart.ts +0 -48
- package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useProductDetail.ts +0 -39
- package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useShop.ts +0 -34
- package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart-core.ts +0 -121
- package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart-store.ts +0 -107
- package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart.ts +0 -138
- package/skills/wix-headless-fast/references/storefront/app/wix/storefront/catalog-core.ts +0 -309
- package/skills/wix-headless-fast/references/storefront/app/wix/storefront/catalog.ts +0 -133
- package/skills/wix-headless-fast/references/storefront/app/wix/storefront/product-detail-store.ts +0 -147
- package/skills/wix-headless-fast/references/storefront/app/wix/storefront/shop-store.ts +0 -289
- package/skills/wix-headless-fast/references/storefront/app/wix/storefront/types.ts +0 -167
- package/skills/wix-headless-fast/references/storefront/app-astro/layouts/SiteLayout.astro +0 -65
- package/skills/wix-headless-fast/references/storefront/lock/astro/package-lock.json +0 -12247
- package/skills/wix-headless-fast/references/storefront/rest/cart.ts +0 -132
- package/skills/wix-headless-fast/references/storefront/rest/catalog.ts +0 -123
- package/skills/wix-headless-fast/references/storefront/seed/SEED.md +0 -124
- package/skills/wix-headless-fast/references/storefront/seed/seed-store.mjs +0 -525
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
// Set up the project in the current folder — one deterministic call from "the folder and the
|
|
2
|
+
// brief" to "brand layer can start", for a folder that is NOT yet a Wix project:
|
|
3
|
+
//
|
|
4
|
+
// node <SKILL_ROOT>/install/setup.mjs --vertical <storefront|bookings|…> \
|
|
5
|
+
// [--plan plan.json] [--business-name "<Brand>"] [--stack astro|react|lib|static] \
|
|
6
|
+
// [--subfolder [--folder-name <npm-safe-name>]]
|
|
7
|
+
//
|
|
8
|
+
// - `wix.config.json` present → refuses. The folder is already a Wix project; deploy.mjs adds
|
|
9
|
+
// this skill's code or a solution to it, then one install, then the seed if there is content.
|
|
10
|
+
// - a project but no `wix.config.json` (a package.json, or an index.html at the root) → CONNECT:
|
|
11
|
+
// `npm create @wix/new@latest init` in place creates the site and the config, then deploy.
|
|
12
|
+
// - otherwise (empty, or loose files such as a CSV or a brief) → CREATE: `wix create` with the
|
|
13
|
+
// vertical's composed template (templates/<vertical>/project: the CLI's blank scaffold with the
|
|
14
|
+
// vertical deployed and a lockfile), placed in the current directory (`--business-name` required).
|
|
15
|
+
//
|
|
16
|
+
// The script reads file markers only (wix.config.json, a package.json or index.html); everything
|
|
17
|
+
// else is the agent's call: when connecting, `--stack` is required and comes from SKILL.md step 1,
|
|
18
|
+
// and what the project needs for that stack on Wix hosting is prose there, not detection here. The
|
|
19
|
+
// seed runs only when `--plan` is given: a brief that has not supplied any content gets no seed.
|
|
20
|
+
//
|
|
21
|
+
// Composes pieces that also remain individually runnable (deploy.mjs, the vertical's seed module)
|
|
22
|
+
// to recover one failed step. Emits ONE JSON event per line and exits in ~35s with the two long
|
|
23
|
+
// steps — the dependency install and the seed — running detached in the background (logs and
|
|
24
|
+
// completion markers in the final event), so the caller can build the brand layer while they finish.
|
|
25
|
+
import { spawn, spawnSync } from "node:child_process";
|
|
26
|
+
import { existsSync, openSync, readFileSync, readdirSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
27
|
+
import { basename, dirname, join, resolve } from "node:path";
|
|
28
|
+
import { fileURLToPath } from "node:url";
|
|
29
|
+
import { AGENT_CONFIG_FILES, writeAgentsMd } from "./agents-md.mjs";
|
|
30
|
+
import { listVerticals, templatesDir } from "./templates.mjs";
|
|
31
|
+
|
|
32
|
+
const SKILL_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
33
|
+
|
|
34
|
+
const emit = (event, extra = {}) => console.log(JSON.stringify({ event, ...extra }));
|
|
35
|
+
const fail = (step, detail) => {
|
|
36
|
+
emit("error", { step, detail: String(detail).slice(0, 600) });
|
|
37
|
+
process.exit(1);
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
// ---- args ---------------------------------------------------------------------------------------
|
|
41
|
+
const argv = process.argv.slice(2);
|
|
42
|
+
const flag = (name) => {
|
|
43
|
+
const i = argv.indexOf(`--${name}`);
|
|
44
|
+
return i !== -1 && argv[i + 1] && !argv[i + 1].startsWith("--") ? argv[i + 1] : null;
|
|
45
|
+
};
|
|
46
|
+
const businessName = flag("business-name");
|
|
47
|
+
const planPath = flag("plan");
|
|
48
|
+
const vertical = flag("vertical");
|
|
49
|
+
const stackFlag = flag("stack");
|
|
50
|
+
// Opt-in: keep a CREATE's project in a subfolder instead of the current directory.
|
|
51
|
+
const subfolder = argv.includes("--subfolder");
|
|
52
|
+
// The shipped code: the repository's templates/ (a checkout, the cache, or fetched now, in a second).
|
|
53
|
+
let TEMPLATES;
|
|
54
|
+
try { TEMPLATES = templatesDir(); } catch (e) { fail("templates", e.message); }
|
|
55
|
+
const knownVerticals = listVerticals(TEMPLATES);
|
|
56
|
+
const usage = `usage: setup.mjs --vertical <${knownVerticals.join("|")}> [--plan plan.json] [--business-name "<Brand>"] [--stack astro|react|lib|static] [--subfolder]`;
|
|
57
|
+
// --vertical is REQUIRED: a defaulted vertical deploys the wrong code and runs the wrong seed.
|
|
58
|
+
if (!vertical) fail("args", usage);
|
|
59
|
+
if (!knownVerticals.includes(vertical)) {
|
|
60
|
+
fail("args", `unknown vertical "${vertical}" — shipped verticals: ${knownVerticals.join(", ")}`);
|
|
61
|
+
}
|
|
62
|
+
if (stackFlag && !["astro", "react", "lib", "static"].includes(stackFlag)) {
|
|
63
|
+
fail("args", `unknown --stack "${stackFlag}" — astro, react, lib or static`);
|
|
64
|
+
}
|
|
65
|
+
if (planPath && !existsSync(planPath)) fail("args", `plan file not found: ${planPath}`);
|
|
66
|
+
|
|
67
|
+
// ---- 0 · read the folder --------------------------------------------------------------------------
|
|
68
|
+
const cwd = process.cwd();
|
|
69
|
+
const has = (p) => existsSync(join(cwd, p));
|
|
70
|
+
if (has("wix.config.json")) {
|
|
71
|
+
fail("place", "this folder is already a Wix project (wix.config.json): nothing to set up. deploy.mjs <vertical> adds this skill's code or a solution to it; then ONE npm install; then the vertical's seed module if there is content to create");
|
|
72
|
+
}
|
|
73
|
+
const pkg = has("package.json") ? JSON.parse(readFileSync(join(cwd, "package.json"), "utf8")) : null;
|
|
74
|
+
const hasProject = !!pkg || has("index.html");
|
|
75
|
+
const mode = hasProject ? "connect" : "create";
|
|
76
|
+
if (mode === "connect" && !stackFlag) {
|
|
77
|
+
fail("args", "connecting a project on disk needs --stack astro|react|lib|static — the stack you resolved in SKILL.md step 1 for this project");
|
|
78
|
+
}
|
|
79
|
+
const stack = stackFlag ?? "astro";
|
|
80
|
+
emit("folder", { mode, stack, project: hasProject ? (pkg?.name ?? basename(cwd)) : null });
|
|
81
|
+
|
|
82
|
+
let projectDir = cwd;
|
|
83
|
+
let folderName = null;
|
|
84
|
+
|
|
85
|
+
if (mode === "create") {
|
|
86
|
+
// ---- 1 · scaffold -----------------------------------------------------------------------------
|
|
87
|
+
if (!businessName) fail("args", `an empty folder is a CREATE run and needs --business-name. ${usage}`);
|
|
88
|
+
folderName =
|
|
89
|
+
flag("folder-name") ??
|
|
90
|
+
businessName.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 40);
|
|
91
|
+
// `let`: the Wix CLI can only scaffold into a subfolder; by default we then move the scaffold up
|
|
92
|
+
// into the current directory and repoint projectDir there, so the detached install/seed and every
|
|
93
|
+
// reported path use the final location.
|
|
94
|
+
projectDir = resolve(cwd, folderName);
|
|
95
|
+
if (existsSync(join(projectDir, "wix.config.json"))) {
|
|
96
|
+
emit("scaffold_skipped", { reason: "project already exists", folder: folderName });
|
|
97
|
+
} else {
|
|
98
|
+
// The composed template: the CLI copies it in place of its blank one, creates the site and
|
|
99
|
+
// writes wix.config.json; the vertical's code and its lockfile arrive with it. Any other
|
|
100
|
+
// stack takes the CLI's blank Astro scaffold, as before, and deploy below adds the code.
|
|
101
|
+
// The composed project is the one part of the templates a project's repository does not keep;
|
|
102
|
+
// a committed copy fetches it here, at the commit the rest came from.
|
|
103
|
+
const template = stack === "astro" ? join(templatesDir({ need: `${vertical}/project` }), vertical, "project") : null;
|
|
104
|
+
emit("scaffolding", { folder: folderName, template });
|
|
105
|
+
const scaffold = spawnSync(
|
|
106
|
+
"npm",
|
|
107
|
+
// --skip-git: this wrapper composes its own steps and leaves version control to
|
|
108
|
+
// the caller / the enclosing repo; the scaffold's own `git init` + "Initial
|
|
109
|
+
// commit" is noise here, and becomes a nested-repo (submodule gitlink) hazard
|
|
110
|
+
// if the project is later placed inside an existing repo. --skip-install for the
|
|
111
|
+
// same reason: deps install in a detached step below.
|
|
112
|
+
["create", "@wix/new@latest", "--", "headless",
|
|
113
|
+
"--folder-name", folderName, "--business-name", businessName,
|
|
114
|
+
"--site-template", "blank", ...(template ? ["--template-path", template] : []),
|
|
115
|
+
"--skip-install", "--skip-git", "--no-publish"],
|
|
116
|
+
{ env: { ...process.env, CI: "1" }, encoding: "utf8", timeout: 300_000 },
|
|
117
|
+
);
|
|
118
|
+
if (scaffold.status !== 0 || !existsSync(join(projectDir, "wix.config.json"))) {
|
|
119
|
+
fail("scaffold", (scaffold.stderr || scaffold.stdout || "scaffold produced no wix.config.json — is the Wix CLI logged in? (npx @wix/cli@latest whoami)").slice(-600));
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
} else {
|
|
123
|
+
// ---- 1 · init in place --------------------------------------------------------------------------
|
|
124
|
+
// The CLI's `init` links the folder to a NEW site: creates the site and its OAuth app, writes
|
|
125
|
+
// wix.config.json and .env.local, touches nothing else. Non-interactive under CI=1; the site is
|
|
126
|
+
// named after the folder (rename it in the dashboard).
|
|
127
|
+
emit("initializing", { folder: cwd });
|
|
128
|
+
const init = spawnSync("npm", ["create", "@wix/new@latest", "--", "init"],
|
|
129
|
+
{ cwd, env: { ...process.env, CI: "1" }, encoding: "utf8", timeout: 300_000 });
|
|
130
|
+
if (init.status !== 0 || !has("wix.config.json")) {
|
|
131
|
+
fail("init", (init.stderr || init.stdout || "init produced no wix.config.json — is the Wix CLI logged in? (npx @wix/cli@latest whoami)").slice(-600));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
const wixConfig = JSON.parse(readFileSync(join(projectDir, "wix.config.json"), "utf8"));
|
|
135
|
+
const siteId = wixConfig.siteId ?? wixConfig.projectId;
|
|
136
|
+
// Static: `wix release` uploads the output folder whole, so the project root (config, plan, seed
|
|
137
|
+
// output, the skills) must not be it. The site lives in site/: the config points there and the REST
|
|
138
|
+
// layer deploys into it; the pages, styles and assets are the agent's to move (the `next` says so).
|
|
139
|
+
const STATIC_OUT = "site";
|
|
140
|
+
if (stack === "static") {
|
|
141
|
+
wixConfig.site = { ...(wixConfig.site ?? {}), outputDirectory: `./${STATIC_OUT}` };
|
|
142
|
+
writeFileSync(join(projectDir, "wix.config.json"), JSON.stringify(wixConfig, null, 2) + "\n");
|
|
143
|
+
}
|
|
144
|
+
emit(mode === "create" ? "scaffolded" : "connected", { folder: folderName ?? cwd, siteId, stack });
|
|
145
|
+
|
|
146
|
+
// ---- 2 · deploy shipped code + deps ---------------------------------------------------------------
|
|
147
|
+
// A CREATE from the composed template already holds the code and the lock: deploy adds nothing and
|
|
148
|
+
// reports the project; a CONNECT gets the code and its dependencies here.
|
|
149
|
+
const deploy = spawnSync(
|
|
150
|
+
"node",
|
|
151
|
+
[join(SKILL_ROOT, "install", "deploy.mjs"), vertical, "--stack", stack, ...(stack === "static" ? ["--out", STATIC_OUT] : []), ...(planPath ? ["--plan", resolve(planPath)] : [])],
|
|
152
|
+
{ cwd: projectDir, encoding: "utf8", timeout: 60_000 },
|
|
153
|
+
);
|
|
154
|
+
if (deploy.status !== 0) fail("deploy", deploy.stderr || deploy.stdout);
|
|
155
|
+
let deployResult = {};
|
|
156
|
+
try { deployResult = JSON.parse(deploy.stdout); } catch { /* keep going with raw output below */ }
|
|
157
|
+
if (deployResult.error) fail("deploy", deployResult.error);
|
|
158
|
+
emit("deployed", deployResult);
|
|
159
|
+
|
|
160
|
+
// ---- 2c · place a CREATE's project in the current directory -------------------------------------
|
|
161
|
+
// The Wix CLI scaffolds into a subfolder, so the scaffold is moved up into the current directory —
|
|
162
|
+
// the folder that already holds the installed skills — and the subfolder removed. Done HERE, before
|
|
163
|
+
// the detached install below, on purpose: no node_modules exists yet, so the move is instant and
|
|
164
|
+
// cannot collide with a running install. A pure move: the scaffold was created with --skip-git, so
|
|
165
|
+
// there is no nested repo to reconcile — git is whatever the folder already is. Refuses rather than
|
|
166
|
+
// overwrite: an entry that already exists in the current directory stops the move before anything
|
|
167
|
+
// is touched. `--subfolder` skips this step.
|
|
168
|
+
if (mode === "create" && !subfolder && projectDir !== cwd) {
|
|
169
|
+
// The CLI's own agent config files, when its generator managed to write them, are dropped from
|
|
170
|
+
// the scaffold: ours (written below, after the move) carries the same CLI section plus this
|
|
171
|
+
// project's skills. A file the user's folder already has is never overwritten or merged into —
|
|
172
|
+
// it is kept as is, and the agent_configs event says so.
|
|
173
|
+
for (const f of AGENT_CONFIG_FILES) rmSync(join(projectDir, f), { recursive: true, force: true });
|
|
174
|
+
const entries = readdirSync(projectDir);
|
|
175
|
+
const clashes = entries.filter((e) => existsSync(join(cwd, e)));
|
|
176
|
+
if (clashes.length) {
|
|
177
|
+
fail("place", `the current directory already has: ${clashes.join(", ")} — run with --subfolder to keep the project in ${folderName}/, or start in an empty folder`);
|
|
178
|
+
}
|
|
179
|
+
try {
|
|
180
|
+
for (const entry of entries) renameSync(join(projectDir, entry), join(cwd, entry));
|
|
181
|
+
rmSync(projectDir, { recursive: true, force: true });
|
|
182
|
+
projectDir = cwd;
|
|
183
|
+
emit("project_placed", { into: cwd });
|
|
184
|
+
} catch (e) {
|
|
185
|
+
fail("place", e?.stack || e);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// ---- 2d · the agent config files `wix create` would have written --------------------------------
|
|
190
|
+
// Skipped by the CLI because of --skip-install. Fill-only: a project that has its own AGENTS.md
|
|
191
|
+
// keeps it (the event says `kept`).
|
|
192
|
+
emit("agent_configs", writeAgentsMd(projectDir, { skill: basename(SKILL_ROOT), stack }));
|
|
193
|
+
|
|
194
|
+
// ---- 3 · start the dependency install, detached --------------------------------------------------
|
|
195
|
+
// ONE install, here, for any project with a package.json (deploy patched it). The static stack has
|
|
196
|
+
// no package.json and nothing to install. `npm ci` only where a lockfile exists: without one it fails
|
|
197
|
+
// with a usage error that sits at the top of the log and reads as a failed install (run 109).
|
|
198
|
+
let install = null;
|
|
199
|
+
if (stack !== "static" && existsSync(join(projectDir, "package.json"))) {
|
|
200
|
+
const installLog = join(projectDir, "npm-install.log");
|
|
201
|
+
const logFd = openSync(installLog, "a");
|
|
202
|
+
const child = spawn("sh", ["-c", existsSync(join(projectDir, "package-lock.json")) ? "npm ci --ignore-scripts || npm install --ignore-scripts" : "npm install --ignore-scripts"], {
|
|
203
|
+
cwd: projectDir,
|
|
204
|
+
detached: true,
|
|
205
|
+
stdio: ["ignore", logFd, logFd],
|
|
206
|
+
});
|
|
207
|
+
child.unref();
|
|
208
|
+
install = { log: installLog, doneMarker: "node_modules/.package-lock.json" };
|
|
209
|
+
emit("install_started", install);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// ---- 4 · start the seed, detached (only with a plan) ---------------------------------------------
|
|
213
|
+
// The seed includes a Wix-side provisioning wait of unpredictable length (10-80s); running it in
|
|
214
|
+
// the caller's foreground would idle the agent for exactly that long. Detach it like the install:
|
|
215
|
+
// result JSON + exit-code marker land as files the caller syncs on before release. Seeding is
|
|
216
|
+
// additive: it never deletes or overwrites what the site holds.
|
|
217
|
+
let seed = null;
|
|
218
|
+
if (planPath) {
|
|
219
|
+
const seedDir = join(TEMPLATES, vertical, "seed");
|
|
220
|
+
const seedName = existsSync(seedDir)
|
|
221
|
+
? readdirSync(seedDir).find((f) => f.startsWith("seed-") && f.endsWith(".mjs"))
|
|
222
|
+
: undefined;
|
|
223
|
+
if (!seedName) fail("seed", `no seed module found under ${seedDir}`);
|
|
224
|
+
const seedFile = join(seedDir, seedName);
|
|
225
|
+
const planAbs = resolve(planPath);
|
|
226
|
+
const seedChild = spawn(
|
|
227
|
+
"sh",
|
|
228
|
+
["-c", `node "${seedFile}" "${planAbs}" > seed-result.json 2> seed.log; echo $? > .seed-exit`],
|
|
229
|
+
{ cwd: projectDir, detached: true, stdio: "ignore" },
|
|
230
|
+
);
|
|
231
|
+
seedChild.unref();
|
|
232
|
+
seed = { resultFile: "seed-result.json", log: "seed.log", doneMarker: ".seed-exit", success: "file contains 0" };
|
|
233
|
+
emit("seeding_started", { vertical, ...seed });
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// ---- done ----------------------------------------------------------------------------------------
|
|
237
|
+
const release = {
|
|
238
|
+
astro: "npx @wix/cli@latest build, then npx @wix/cli@latest release",
|
|
239
|
+
react: "the project's own build, then npx @wix/cli@latest release of the build folder named in wix.config.json (what Wix hosting serves and how routes must be shaped: SKILL.md step 1)",
|
|
240
|
+
lib: "the project's own build, then npx @wix/cli@latest release of the build folder named in wix.config.json (SKILL.md step 1)",
|
|
241
|
+
static: `npx @wix/cli@latest release — no build; it uploads ${STATIC_OUT}/ whole (wix.config.json site.outputDirectory), so the pages, styles and assets move into ${STATIC_OUT}/ first and import the modules from ./js/wix/ there; the root keeps the config, the plan, the seed output and the skills`,
|
|
242
|
+
}[stack];
|
|
243
|
+
emit("ready_for_brand_layer", {
|
|
244
|
+
mode,
|
|
245
|
+
stack,
|
|
246
|
+
projectDir,
|
|
247
|
+
siteId,
|
|
248
|
+
dashboardUrl: deployResult.dashboardUrl,
|
|
249
|
+
productsUrl: deployResult.productsUrl,
|
|
250
|
+
categoriesUrl: deployResult.categoriesUrl,
|
|
251
|
+
install,
|
|
252
|
+
seed,
|
|
253
|
+
next:
|
|
254
|
+
(planPath
|
|
255
|
+
? "theme + write the home page; "
|
|
256
|
+
: "the site is new and empty — seed it (a plan per step 2, the vertical's seed module) or say so; theme + write the home page; ") +
|
|
257
|
+
(install || seed ? "then wait for the done markers" + (seed ? ", verify .seed-exit is 0 (else read seed.log and re-run the seed module)" : "") + "; " : "") +
|
|
258
|
+
`then ${release}`,
|
|
259
|
+
});
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
// Where the shipped code is. The verticals live in the skill's repository under `templates/`
|
|
2
|
+
// (each with its code layers, its tools and a composed project with a lockfile), not in the skill
|
|
3
|
+
// folder: the skill stays small and the code is fetched once, when first needed.
|
|
4
|
+
//
|
|
5
|
+
// node <SKILL_ROOT>/install/templates.mjs [--refresh] # prints {templates, source, verticals}
|
|
6
|
+
//
|
|
7
|
+
// Resolution, in order:
|
|
8
|
+
// 1. a checkout of the repository itself (the skill folder sits in it): `<repo>/templates/`.
|
|
9
|
+
// 2. the cache `<SKILL_ROOT>/templates/`, filled by an earlier call (`--refresh` refetches).
|
|
10
|
+
// 3. a fetch: a sparse, shallow clone of `templates/` from the repository the skill was installed
|
|
11
|
+
// from (skills-lock.json's `source`, default wix/skills), at the branch or tag the install
|
|
12
|
+
// named (its `ref`, falling back to the default branch when that ref no longer exists) or the
|
|
13
|
+
// repository's default branch. The lock records no commit, so there is nothing more exact to
|
|
14
|
+
// pin to; `WIX_HEADLESS_FAST_TEMPLATES_REF=<branch|tag|sha>` overrides the ref.
|
|
15
|
+
// The cache stays with the project: its `.gitignore` leaves out only the composed `project/`
|
|
16
|
+
// folders (the scaffolds with their lockfiles, read once, at create or attach) and the repository
|
|
17
|
+
// tooling, so the code layers, playbooks, seeds and readers are committed at the commit the project
|
|
18
|
+
// was built from, recorded in `.source`. A caller that needs a `project/` folder passes it as
|
|
19
|
+
// `need`; when a committed copy lacks it, that part is fetched at the same commit.
|
|
20
|
+
import { cpSync, existsSync, mkdtempSync, mkdirSync, readdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
21
|
+
import { tmpdir } from "node:os";
|
|
22
|
+
import { dirname, join, resolve } from "node:path";
|
|
23
|
+
import { spawnSync } from "node:child_process";
|
|
24
|
+
import { fileURLToPath } from "node:url";
|
|
25
|
+
|
|
26
|
+
export const SKILL_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
27
|
+
export const DEFAULT_REPO = "https://github.com/wix/skills.git";
|
|
28
|
+
|
|
29
|
+
const git = (args, opts = {}) => spawnSync("git", args, { encoding: "utf8", timeout: 180_000, ...opts });
|
|
30
|
+
|
|
31
|
+
// The repository and ref the skill was installed from: the nearest skills-lock.json above the
|
|
32
|
+
// skill folder, its entry for this skill. "wix/skills" → the default branch of that repository;
|
|
33
|
+
// "https://github.com/owner/repo/tree/<ref>" → that ref.
|
|
34
|
+
export function installSource() {
|
|
35
|
+
const skill = SKILL_ROOT.split("/").pop();
|
|
36
|
+
let dir = SKILL_ROOT;
|
|
37
|
+
for (let i = 0; i < 6; i++) {
|
|
38
|
+
const p = join(dir, "skills-lock.json");
|
|
39
|
+
if (existsSync(p)) {
|
|
40
|
+
try {
|
|
41
|
+
const entry = JSON.parse(readFileSync(p, "utf8")).skills?.[skill];
|
|
42
|
+
if (typeof entry?.source === "string" && entry.source) {
|
|
43
|
+
const parsed = parseSource(entry.source);
|
|
44
|
+
// `ref` is the branch or tag the install named (skills-lock.json v1 keeps it beside `source`)
|
|
45
|
+
return { ...parsed, ref: parsed.ref ?? (typeof entry.ref === "string" && entry.ref ? entry.ref : null) };
|
|
46
|
+
}
|
|
47
|
+
} catch { /* fall through to the default */ }
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
const up = dirname(dir);
|
|
51
|
+
if (up === dir) break;
|
|
52
|
+
dir = up;
|
|
53
|
+
}
|
|
54
|
+
return { repo: DEFAULT_REPO, ref: null };
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function parseSource(src) {
|
|
58
|
+
const m = src.match(/^(?:https?:\/\/github\.com\/)?([^/\s]+)\/([^/\s#@]+?)(?:\.git)?(?:\/tree\/([^\s]+))?$/);
|
|
59
|
+
if (!m) return { repo: DEFAULT_REPO, ref: null };
|
|
60
|
+
return { repo: `https://github.com/${m[1]}/${m[2]}.git`, ref: m[3] ?? null };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function listVerticals(dir) {
|
|
64
|
+
return readdirSync(dir, { withFileTypes: true })
|
|
65
|
+
.filter((d) => d.isDirectory() && d.name !== "shared" && d.name !== "blank" && existsSync(join(dir, d.name, "app")))
|
|
66
|
+
.map((d) => d.name)
|
|
67
|
+
.sort();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function templatesDir({ refresh = false, need = null } = {}) {
|
|
71
|
+
const checkout = resolve(SKILL_ROOT, "..", "..", "templates");
|
|
72
|
+
if (existsSync(join(checkout, "shared", "app"))) return checkout;
|
|
73
|
+
const cache = join(SKILL_ROOT, "templates");
|
|
74
|
+
if (!refresh && existsSync(join(cache, "shared", "app"))) {
|
|
75
|
+
if (need && !existsSync(join(cache, need))) fetchIgnoredPart(cache, need);
|
|
76
|
+
return cache;
|
|
77
|
+
}
|
|
78
|
+
fetchTemplates(cache);
|
|
79
|
+
return cache;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// What a project's repository does not carry: the composed scaffolds (heavy, read once) and the
|
|
83
|
+
// repository's own tooling. Everything else in the cache is committed with the project.
|
|
84
|
+
const IGNORED = ["*/project/", "blank/", "compose.mjs"];
|
|
85
|
+
|
|
86
|
+
// A committed copy lacks the ignored parts. Fetch them at the commit the copy came from, so the
|
|
87
|
+
// scaffold a create copies matches the code committed beside it; the committed files are untouched.
|
|
88
|
+
function fetchIgnoredPart(cache, need) {
|
|
89
|
+
const src = templatesSource(cache);
|
|
90
|
+
const { repo } = installSource();
|
|
91
|
+
const r = cloneSparse(src.repo ?? repo, src.commit ?? process.env.WIX_HEADLESS_FAST_TEMPLATES_REF ?? null);
|
|
92
|
+
const tmp = r.tmp;
|
|
93
|
+
if (r.status !== 0 || !existsSync(join(tmp, "templates", need))) {
|
|
94
|
+
rmSync(tmp, { recursive: true, force: true });
|
|
95
|
+
throw new Error(`could not fetch templates/${need} from ${src.repo ?? repo}${src.commit ? ` @ ${src.commit.slice(0, 7)}` : ""}: ${(r.stderr || r.stdout || "not in the clone").trim().slice(-300)}`);
|
|
96
|
+
}
|
|
97
|
+
for (const part of ["blank", ...readdirSync(join(tmp, "templates"), { withFileTypes: true }).filter((d) => d.isDirectory() && existsSync(join(tmp, "templates", d.name, "project"))).map((d) => `${d.name}/project`)]) {
|
|
98
|
+
const from = join(tmp, "templates", part);
|
|
99
|
+
if (existsSync(from) && !existsSync(join(cache, part))) cpSync(from, join(cache, part), { recursive: true });
|
|
100
|
+
}
|
|
101
|
+
rmSync(tmp, { recursive: true, force: true });
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export function templatesSource(dir) {
|
|
105
|
+
const p = join(dir, ".source");
|
|
106
|
+
if (existsSync(p)) { try { return JSON.parse(readFileSync(p, "utf8")); } catch { /* below */ } }
|
|
107
|
+
return { checkout: dir };
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function fetchTemplates(cache) {
|
|
111
|
+
const { repo, ref: lockRef } = installSource();
|
|
112
|
+
const envRef = process.env.WIX_HEADLESS_FAST_TEMPLATES_REF || null;
|
|
113
|
+
let ref = envRef || lockRef || null;
|
|
114
|
+
let r = cloneSparse(repo, ref);
|
|
115
|
+
// The branch the skill was installed from can be gone by the time the code is first needed
|
|
116
|
+
// (merged and deleted). The lock's ref then falls back to the default branch; an explicit env
|
|
117
|
+
// ref does not.
|
|
118
|
+
let fellBack = false;
|
|
119
|
+
if (r.status !== 0 && ref && !envRef && /not found|couldn't find remote ref|unknown revision/i.test(r.stderr || "")) {
|
|
120
|
+
rmSync(r.tmp, { recursive: true, force: true });
|
|
121
|
+
fellBack = true; ref = null;
|
|
122
|
+
r = cloneSparse(repo, null);
|
|
123
|
+
}
|
|
124
|
+
const tmp = r.tmp;
|
|
125
|
+
if (r.error?.code === "ENOENT") {
|
|
126
|
+
rmSync(tmp, { recursive: true, force: true });
|
|
127
|
+
throw new Error("git is not installed or not on PATH; the shipped code is fetched with a git clone of the skill's repository");
|
|
128
|
+
}
|
|
129
|
+
if (r.status !== 0 || !existsSync(join(tmp, "templates", "shared", "app"))) {
|
|
130
|
+
rmSync(tmp, { recursive: true, force: true });
|
|
131
|
+
throw new Error(`could not fetch templates/ from ${repo}${ref ? ` @ ${ref}` : ""}: ${(r.stderr || r.stdout || "no templates/shared/app in the clone").trim().slice(-400)}`);
|
|
132
|
+
}
|
|
133
|
+
const commit = git(["-C", tmp, "rev-parse", "HEAD"]).stdout.trim();
|
|
134
|
+
rmSync(cache, { recursive: true, force: true });
|
|
135
|
+
mkdirSync(dirname(cache), { recursive: true });
|
|
136
|
+
try { renameSync(join(tmp, "templates"), cache); }
|
|
137
|
+
catch { cpSync(join(tmp, "templates"), cache, { recursive: true }); }
|
|
138
|
+
rmSync(tmp, { recursive: true, force: true });
|
|
139
|
+
writeFileSync(join(cache, ".gitignore"), IGNORED.join("\n") + "\n");
|
|
140
|
+
writeFileSync(join(cache, ".source"), JSON.stringify({ repo, ref: ref ?? (fellBack ? `default branch (${lockRef} not found)` : "default branch"), commit, fetchedAt: new Date().toISOString() }, null, 2) + "\n");
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// A sparse, shallow clone of templates/ at a ref (branch, tag, or commit id) into a temp dir.
|
|
144
|
+
function cloneSparse(repo, ref) {
|
|
145
|
+
const tmp = mkdtempSync(join(tmpdir(), "wix-headless-fast-templates-"));
|
|
146
|
+
let r;
|
|
147
|
+
if (ref && /^[0-9a-f]{40}$/i.test(ref)) {
|
|
148
|
+
// a commit: shallow-fetch just it (GitHub serves any reachable commit by id)
|
|
149
|
+
for (const args of [["init", "-q", tmp], ["-C", tmp, "remote", "add", "origin", repo], ["-C", tmp, "fetch", "-q", "--depth", "1", "--filter=blob:none", "origin", ref], ["-C", tmp, "sparse-checkout", "set", "templates"], ["-C", tmp, "checkout", "-q", "FETCH_HEAD"]]) {
|
|
150
|
+
r = git(args);
|
|
151
|
+
if (r.status !== 0) break;
|
|
152
|
+
}
|
|
153
|
+
} else {
|
|
154
|
+
r = git(["clone", "--quiet", "--depth", "1", "--filter=blob:none", "--sparse", ...(ref ? ["-b", ref] : []), repo, tmp]);
|
|
155
|
+
if (r.status === 0) r = git(["-C", tmp, "sparse-checkout", "set", "templates"]);
|
|
156
|
+
}
|
|
157
|
+
return { ...r, tmp };
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
|
161
|
+
try {
|
|
162
|
+
const dir = templatesDir({ refresh: process.argv.includes("--refresh") });
|
|
163
|
+
console.log(JSON.stringify({ templates: dir, source: templatesSource(dir), verticals: listVerticals(dir) }));
|
|
164
|
+
} catch (e) {
|
|
165
|
+
console.log(JSON.stringify({ error: e.message }));
|
|
166
|
+
process.exit(1);
|
|
167
|
+
}
|
|
168
|
+
}
|
package/skills/wix-manage/references/ecommerce/pricing-promotions/ecom-pricing-create-coupon.md
CHANGED
|
@@ -47,10 +47,7 @@ Before creating a coupon, check for code conflicts and existing promotions on th
|
|
|
47
47
|
"code": "SUMMER20",
|
|
48
48
|
"percentOffRate": 20,
|
|
49
49
|
"scope": {
|
|
50
|
-
"namespace": "stores"
|
|
51
|
-
"group": {
|
|
52
|
-
"name": "product"
|
|
53
|
-
}
|
|
50
|
+
"namespace": "stores"
|
|
54
51
|
},
|
|
55
52
|
"startTime": 1717200000000,
|
|
56
53
|
"expirationTime": 1719792000000,
|
|
@@ -91,10 +88,7 @@ Check for: duplicate codes, overlapping scopes with active coupons, and cross-me
|
|
|
91
88
|
"code": "SPRING15",
|
|
92
89
|
"percentOffRate": 15,
|
|
93
90
|
"scope": {
|
|
94
|
-
"namespace": "stores"
|
|
95
|
-
"group": {
|
|
96
|
-
"name": "product"
|
|
97
|
-
}
|
|
91
|
+
"namespace": "stores"
|
|
98
92
|
},
|
|
99
93
|
"startTime": 1714521600000,
|
|
100
94
|
"usageLimit": 200,
|
|
@@ -167,10 +161,7 @@ Check for: duplicate codes, overlapping scopes with active coupons, and cross-me
|
|
|
167
161
|
"code": "SAVE10",
|
|
168
162
|
"moneyOffAmount": 10,
|
|
169
163
|
"scope": {
|
|
170
|
-
"namespace": "stores"
|
|
171
|
-
"group": {
|
|
172
|
-
"name": "product"
|
|
173
|
-
}
|
|
164
|
+
"namespace": "stores"
|
|
174
165
|
},
|
|
175
166
|
"startTime": 1714521600000,
|
|
176
167
|
"active": true
|
|
@@ -230,11 +221,11 @@ Instead of targeting a scope, you can require a minimum cart subtotal. This is a
|
|
|
230
221
|
|
|
231
222
|
## Scope values for Wix Stores
|
|
232
223
|
|
|
233
|
-
| Scope target | `namespace` | `group
|
|
234
|
-
|
|
235
|
-
| All store products | `"stores"` | `
|
|
236
|
-
| Specific product | `"stores"` | `"product"
|
|
237
|
-
| Specific collection | `"stores"` | `"collection"
|
|
224
|
+
| Scope target | `namespace` | `group` |
|
|
225
|
+
|---|---|---|
|
|
226
|
+
| All store products | `"stores"` | Omit the `group` field entirely — a present-but-empty `group: {}` is rejected the same as a populated one missing `entityId` |
|
|
227
|
+
| Specific product | `"stores"` | `{ "name": "product", "entityId": "<product UUID>" }` |
|
|
228
|
+
| Specific collection | `"stores"` | `{ "name": "collection", "entityId": "<collection UUID>" }` |
|
|
238
229
|
|
|
239
230
|
---
|
|
240
231
|
|
|
@@ -246,7 +237,7 @@ When the recommendation output has `mechanism: "COUPON"`, use this mapping to co
|
|
|
246
237
|
|
|
247
238
|
| Recommendation `scope` | Coupon `scope` |
|
|
248
239
|
|---|---|
|
|
249
|
-
| `SITE` | `{ "namespace": "stores"
|
|
240
|
+
| `SITE` | `{ "namespace": "stores" }` (all products — omit `group` entirely) |
|
|
250
241
|
| `CATEGORY` | `{ "namespace": "stores", "group": { "name": "collection", "entityId": "<first categoryId>" } }` |
|
|
251
242
|
| `ITEMS` | `{ "namespace": "stores", "group": { "name": "product", "entityId": "<first productId>" } }` |
|
|
252
243
|
|
|
@@ -340,7 +331,7 @@ When the recommendation output has `mechanism: "COUPON"`, use this mapping to co
|
|
|
340
331
|
|
|
341
332
|
| Error | Cause | Fix |
|
|
342
333
|
|---|---|---|
|
|
343
|
-
| `"When scope or minimumSubtotal is not used - only FreeShipping coupon is allowed"` | Coupon sent without `scope` or `minimumSubtotal` | Add `scope: { "namespace": "stores"
|
|
334
|
+
| `"When scope or minimumSubtotal is not used - only FreeShipping coupon is allowed"` | Coupon sent without `scope` or `minimumSubtotal` | Add `scope: { "namespace": "stores" }` for site-wide (omit `group` — do not send `group: {}`, which is rejected identically), or set `minimumSubtotal` |
|
|
344
335
|
| Duplicate code | Another coupon uses the same code | Generate a different code |
|
|
345
336
|
| Invalid startTime | Value too low (must be epoch ms, not seconds) | Multiply by 1000 if in seconds |
|
|
346
337
|
| Both scope and minimumSubtotal set | These are oneOf — cannot use both | Choose scope OR minimumSubtotal |
|
|
@@ -200,7 +200,11 @@ The response is the definition under `ticketDefinition`:
|
|
|
200
200
|
Keep `revision` — `PATCH /events/v3/ticket-definitions/{id}` requires the current value, and it
|
|
201
201
|
increments on every update.
|
|
202
202
|
|
|
203
|
-
- **`feeType` is required
|
|
203
|
+
- **`feeType` is required.** A free ticket (`fixedPrice` of `"0"`) takes `NO_FEE`. A paid ticket
|
|
204
|
+
takes `FEE_ADDED_AT_CHECKOUT` (the guest pays the service fee) unless the user asked to absorb it,
|
|
205
|
+
then `FEE_INCLUDED`. `NO_FEE` on a paid ticket is accepted only on sites that do not collect ticket
|
|
206
|
+
fees. If a paid ticket fails with `400 INVALID_FEE_TYPE`, the site is one that does not collect
|
|
207
|
+
ticket fees: retry that ticket once with `NO_FEE`.
|
|
204
208
|
- **`value` is a string.** `"value": 10` fails `400 Unexpected value for field value`.
|
|
205
209
|
- **No writable `free` flag** — `pricingMethod.free` is read-only; a free ticket is a `fixedPrice`
|
|
206
210
|
of `"0"`.
|
|
@@ -12,6 +12,22 @@ Build direct links into the Google Ads page of a site's dashboard. For the gener
|
|
|
12
12
|
| Page | URL after `/dashboard/{metaSiteId}/` | What it manages |
|
|
13
13
|
|---|---|---|
|
|
14
14
|
| Google Ads | `google-ads` | The Google Ads account, campaigns, and their performance |
|
|
15
|
+
| Keywords manager (campaign-scoped) | `google-ads/keywords-manager?campaignId={campaignId}` | Search themes and campaign exclusions: `excludedSearchTerms` for Smart campaigns and `excludedKeywords` for Performance Max Leads campaigns |
|
|
16
|
+
|
|
17
|
+
## Resolve a Campaign-Scoped Destination
|
|
18
|
+
|
|
19
|
+
A campaign-scoped URL requires the campaign's Wix `campaignId`. Never substitute a campaign name in the URL or omit the query parameter.
|
|
20
|
+
|
|
21
|
+
1. Reuse a `campaignId` already established in the conversation or returned by the preceding campaign operation. A Campaign Success Guide flow has already resolved its campaign, so use that ID without listing campaigns again.
|
|
22
|
+
2. If only the campaign name is known, list campaigns once in the selected site's context:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
curl -X GET 'https://www.wixapis.com/_serverless/pa-google/v1/campaigns' \
|
|
26
|
+
-H 'Authorization: <AUTH>'
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Read `campaigns[].id` and `campaigns[].name`, and use the ID only when one campaign clearly matches the user's name.
|
|
30
|
+
3. If neither the campaign ID nor name is known, or the list does not yield exactly one clear match, ask the user for the campaign ID or a more specific name. Do not guess or build the link until the campaign is unambiguous.
|
|
15
31
|
|
|
16
32
|
## Pairing Entities with Their Read APIs
|
|
17
33
|
|
|
@@ -23,3 +39,14 @@ Example — after creating a campaign:
|
|
|
23
39
|
Your Performance Max campaign is live.
|
|
24
40
|
Manage it here: https://manage.wix.com/dashboard/{metaSiteId}/google-ads
|
|
25
41
|
```
|
|
42
|
+
|
|
43
|
+
When a user explicitly prefers to add a campaign's search themes manually, link directly to that campaign's keywords manager. Do not substitute this manual route for an agent-supported update the user wants the agent to perform.
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
Add Search Themes: https://manage.wix.com/dashboard/{metaSiteId}/google-ads/keywords-manager?campaignId={campaignId}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
The same campaign-scoped route manages exclusions. Name the destination after the campaign field the user is managing:
|
|
50
|
+
|
|
51
|
+
- **Smart campaigns:** `excludedSearchTerms` → **Manage Excluded Search Terms**
|
|
52
|
+
- **Performance Max Leads campaigns:** `excludedKeywords` → **Manage Excluded Keywords**
|