@wix/agent-skills 1.6.0 → 1.8.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 (195) hide show
  1. package/README.md +5 -9
  2. package/package.json +1 -1
  3. package/skills/wix-app/SKILL.md +51 -42
  4. package/skills/wix-app/references/BACKEND_EVENT.md +10 -65
  5. package/skills/wix-app/references/CUSTOM_ELEMENT_WIDGET.md +101 -406
  6. package/skills/wix-app/references/DASHBOARD_MENU_PLUGIN.md +14 -111
  7. package/skills/wix-app/references/DASHBOARD_MODAL.md +56 -205
  8. package/skills/wix-app/references/DASHBOARD_PAGE.md +19 -98
  9. package/skills/wix-app/references/DASHBOARD_PLUGIN.md +6 -108
  10. package/skills/wix-app/references/DATA_COLLECTION.md +113 -198
  11. package/skills/wix-app/references/EMBEDDED_SCRIPT.md +41 -268
  12. package/skills/wix-app/references/EXTENSION_REGISTRATION.md +27 -76
  13. package/skills/wix-app/references/SERVICE_PLUGIN.md +35 -188
  14. package/skills/wix-app/references/SITE_PLUGIN.md +8 -92
  15. package/skills/wix-app/references/STORES_VERSIONING.md +1 -0
  16. package/skills/wix-app/references/backend-event/COMMON-EVENTS.md +0 -44
  17. package/skills/wix-app/references/custom-element-widget/SETTINGS_PANEL.md +19 -330
  18. package/skills/wix-app/references/dashboard-menu-plugin/bookings-slots.md +0 -12
  19. package/skills/wix-app/references/dashboard-menu-plugin/ecommerce-slots.md +7 -0
  20. package/skills/wix-app/references/dashboard-menu-plugin/restaurants-slots.md +0 -12
  21. package/skills/wix-app/references/dashboard-plugin/SLOTS.md +3 -15
  22. package/skills/wix-app/references/service-plugin/ADDITIONAL-FEES.md +2 -18
  23. package/skills/wix-app/references/service-plugin/BOOKINGS-STAFF-SORTING.md +2 -42
  24. package/skills/wix-app/references/service-plugin/DISCOUNT-TRIGGERS.md +1 -11
  25. package/skills/wix-app/references/service-plugin/GIFT-CARDS.md +1 -11
  26. package/skills/wix-app/references/service-plugin/PAYMENT-SETTINGS.md +2 -40
  27. package/skills/wix-app/references/service-plugin/SHIPPING-RATES.md +2 -19
  28. package/skills/wix-app/references/service-plugin/VALIDATIONS.md +2 -18
  29. package/skills/wix-app/references/site-plugin/SLOTS.md +17 -68
  30. package/skills/wix-design-system/SKILL.md +4 -0
  31. package/skills/wix-headless/SKILL.md +131 -386
  32. package/skills/wix-headless/references/BUILD-astro.md +246 -0
  33. package/skills/wix-headless/references/BUILD-own-build.md +167 -0
  34. package/skills/wix-headless/references/BUILD.md +105 -0
  35. package/skills/wix-headless/references/DESIGN_SYSTEM.md +175 -0
  36. package/skills/wix-headless/references/DISCOVERY-connect.md +55 -0
  37. package/skills/wix-headless/references/DISCOVERY-create.md +238 -0
  38. package/skills/wix-headless/references/DISCOVERY.md +50 -306
  39. package/skills/wix-headless/references/PLAN-connect.md +19 -0
  40. package/skills/wix-headless/references/PLAN-create.md +17 -0
  41. package/skills/wix-headless/references/PLAN.md +92 -0
  42. package/skills/wix-headless/references/SEED.md +214 -0
  43. package/skills/wix-headless/references/SETUP.md +73 -248
  44. package/skills/wix-headless/references/{blog → astro/blog}/BLOG_PAGES.md +6 -5
  45. package/skills/wix-headless/references/{blog → astro/blog}/BLOG_SETUP.md +2 -2
  46. package/skills/wix-headless/references/astro/bookings/COMPONENTS.md +337 -0
  47. package/skills/wix-headless/references/astro/bookings/SERVICES_PAGES.md +428 -0
  48. package/skills/wix-headless/references/astro/cms/CMS_FOUNDATIONS.md +214 -0
  49. package/skills/wix-headless/references/{cms → astro/cms}/FAQ_KNOWLEDGE_BASE.md +14 -12
  50. package/skills/wix-headless/references/{cms → astro/cms}/PORTFOLIO.md +15 -16
  51. package/skills/wix-headless/references/{cms → astro/cms}/RESOURCE_LIBRARY.md +13 -15
  52. package/skills/wix-headless/references/{cms → astro/cms}/TEAM_DIRECTORY.md +11 -11
  53. package/skills/wix-headless/references/astro/designer/INSTRUCTIONS.md +354 -0
  54. package/skills/wix-headless/references/{ecom → astro/ecom}/CART_PAGES.md +8 -9
  55. package/skills/wix-headless/references/{ecom → astro/ecom}/CART_WIRING.md +6 -6
  56. package/skills/wix-headless/references/{ecom → astro/ecom}/COMPONENTS_CSS.md +6 -6
  57. package/skills/wix-headless/references/{forms → astro/forms}/CONTACT_FORM.md +18 -32
  58. package/skills/wix-headless/references/{gift-cards → astro/gift-cards}/COMPONENTS.md +3 -3
  59. package/skills/wix-headless/references/{gift-cards → astro/gift-cards}/PAGES.md +2 -2
  60. package/skills/wix-headless/references/{stores → astro/stores}/BACK_IN_STOCK.md +7 -7
  61. package/skills/wix-headless/references/{stores → astro/stores}/CATEGORY_PAGES.md +12 -13
  62. package/skills/wix-headless/references/{stores → astro/stores}/COMPONENTS_CSS.md +7 -7
  63. package/skills/wix-headless/references/{stores → astro/stores}/HOME_AND_NAV.md +11 -9
  64. package/skills/wix-headless/references/{stores → astro/stores}/PRODUCT_PAGES.md +11 -9
  65. package/skills/wix-headless/references/{stores → astro/stores}/SHARED_WIRING.md +8 -7
  66. package/skills/wix-headless/references/astro/templates/Footer.astro +27 -0
  67. package/skills/wix-headless/references/astro/templates/Layout.astro +132 -0
  68. package/skills/wix-headless/references/astro/templates/Navigation.astro +38 -0
  69. package/skills/wix-headless/references/astro/templates/astro.config.mjs +41 -0
  70. package/skills/wix-headless/references/astro/templates/bookings/AvailabilityCalendar.tsx +218 -0
  71. package/skills/wix-headless/references/astro/templates/bookings/BookingForm.tsx +194 -0
  72. package/skills/wix-headless/references/astro/templates/bookings/ManageBooking.tsx +84 -0
  73. package/skills/wix-headless/references/astro/templates/bookings/SeoTags.astro +25 -0
  74. package/skills/wix-headless/references/astro/templates/bookings/ServiceBookingFlow.tsx +50 -0
  75. package/skills/wix-headless/references/astro/templates/bookings/ServiceCard.astro +45 -0
  76. package/skills/wix-headless/references/astro/templates/bookings/api/confirm-booking.ts +34 -0
  77. package/skills/wix-headless/references/astro/templates/bookings/api/waitlist.ts +74 -0
  78. package/skills/wix-headless/references/astro/templates/bookings/booking-confirmation.astro +111 -0
  79. package/skills/wix-headless/references/astro/templates/bookings/components-bookings.css +413 -0
  80. package/skills/wix-headless/references/astro/templates/bookings/manage-booking.astro +76 -0
  81. package/skills/wix-headless/references/astro/templates/bookings/services/[slug].astro +81 -0
  82. package/skills/wix-headless/references/astro/templates/bookings/services/index.astro +65 -0
  83. package/skills/wix-headless/references/astro/templates/ecom/components-ecom.css +302 -0
  84. package/skills/wix-headless/references/astro/templates/global.css +286 -0
  85. package/skills/wix-headless/references/astro/templates/index.astro +56 -0
  86. package/skills/wix-headless/{templates → references/astro/templates}/stores/back-in-stock.ts +1 -1
  87. package/skills/wix-headless/{templates → references/astro/templates}/stores/components-stores.css +138 -33
  88. package/skills/wix-headless/references/blog/BLOG_CONTENT.md +28 -19
  89. package/skills/wix-headless/references/blog/INSTRUCTIONS.md +6 -6
  90. package/skills/wix-headless/references/bookings/INSTRUCTIONS.md +106 -0
  91. package/skills/wix-headless/references/bookings/SERVICES_DATA.md +295 -0
  92. package/skills/wix-headless/references/cms/CMS_FOUNDATIONS.md +35 -232
  93. package/skills/wix-headless/references/cms/INSTRUCTIONS.md +39 -8
  94. package/skills/wix-headless/references/commands/known-apps.json +2 -1
  95. package/skills/wix-headless/references/custom/CONNECTION_PLAN.md +142 -0
  96. package/skills/wix-headless/references/custom/INSTRUCTIONS.md +88 -0
  97. package/skills/wix-headless/references/custom/blog/WIRING.md +52 -0
  98. package/skills/wix-headless/references/custom/bookings/WIRING.md +88 -0
  99. package/skills/wix-headless/references/custom/cms/WIRING.md +97 -0
  100. package/skills/wix-headless/references/custom/ecom/WIRING.md +67 -0
  101. package/skills/wix-headless/references/custom/forms/WIRING.md +101 -0
  102. package/skills/wix-headless/references/custom/stores/WIRING.md +80 -0
  103. package/skills/wix-headless/references/ecom/INSTRUCTIONS.md +12 -12
  104. package/skills/wix-headless/references/forms/INSTRUCTIONS.md +6 -6
  105. package/skills/wix-headless/references/gift-cards/INSTRUCTIONS.md +13 -13
  106. package/skills/wix-headless/references/images/INSTRUCTIONS.md +58 -60
  107. package/skills/wix-headless/references/seed-recipes.md +49 -0
  108. package/skills/wix-headless/references/shared/AGENTS_MD.md +47 -0
  109. package/skills/wix-headless/references/shared/AUTHENTICATION.md +108 -0
  110. package/skills/wix-headless/references/shared/BUILD_NOISE.md +2 -2
  111. package/skills/wix-headless/references/shared/DESIGN_MD.md +85 -0
  112. package/skills/wix-headless/references/shared/DOCS_SEARCH.md +41 -0
  113. package/skills/wix-headless/references/shared/IMAGE_GENERATION.md +40 -39
  114. package/skills/wix-headless/references/shared/IMPLEMENTER.md +92 -41
  115. package/skills/wix-headless/references/shared/PRODUCTION_SHARP_EDGES.md +3 -3
  116. package/skills/wix-headless/references/shared/RETURN_CONTRACT.md +32 -312
  117. package/skills/wix-headless/references/shared/STYLING.md +48 -21
  118. package/skills/wix-headless/references/stores/INSTRUCTIONS.md +59 -29
  119. package/skills/wix-headless/references/stores/PRODUCT_CATALOG_DATA.md +31 -28
  120. package/skills/wix-headless/references/verticals/_schema.json +31 -117
  121. package/skills/wix-headless/references/verticals/_schema.md +60 -150
  122. package/skills/wix-headless/references/verticals/blog.md +5 -99
  123. package/skills/wix-headless/references/verticals/bookings.md +41 -0
  124. package/skills/wix-headless/references/verticals/cms.md +9 -100
  125. package/skills/wix-headless/references/verticals/ecom.md +6 -77
  126. package/skills/wix-headless/references/verticals/forms.md +5 -85
  127. package/skills/wix-headless/references/verticals/gift-cards.md +6 -103
  128. package/skills/wix-headless/references/verticals/stores.md +10 -144
  129. package/skills/wix-headless/scripts/check-manifest.mjs +148 -11
  130. package/skills/wix-headless/scripts/compose.mjs +540 -0
  131. package/skills/wix-headless/scripts/emit-design-tokens.mjs +136 -53
  132. package/skills/wix-headless/scripts/flatten.sh +61 -0
  133. package/skills/wix-headless/scripts/generate-images.mjs +242 -0
  134. package/skills/wix-headless/scripts/patch-decorative-slots.mjs +67 -43
  135. package/skills/wix-headless/scripts/plan-entity-image-waves.mjs +3 -3
  136. package/skills/wix-headless/scripts/scaffold.sh +113 -27
  137. package/skills/wix-headless/scripts/seed-utilities.sh +50 -12
  138. package/skills/wix-headless/scripts/write-decorative-json.mjs +62 -0
  139. package/skills/wix-manage/SKILL.md +4 -8
  140. package/skills/wix-manage/references/blog/how-to-create-blog-posts.md +2 -0
  141. package/skills/wix-manage/references/cms/cms-data-items-crud.md +4 -0
  142. package/skills/wix-manage/references/cms/cms-references-and-relationships.md +2 -0
  143. package/skills/wix-manage/references/cms/cms-schema-management.md +4 -0
  144. package/skills/wix-manage/references/domains/domain-search-and-purchase.md +10 -7
  145. package/skills/wix-manage/references/ecommerce/api-shipping.md +443 -0
  146. package/skills/wix-manage/references/ecommerce/flow-add-free-shipping.md +5 -6
  147. package/skills/wix-manage/references/ecommerce/flow-fix-coverage-gaps.md +4 -5
  148. package/skills/wix-manage/references/ecommerce/flow-optimize-shipping-rates.md +4 -5
  149. package/skills/wix-manage/references/ecommerce/goal-increase-aov.md +1 -1
  150. package/skills/wix-manage/references/ecommerce/goal-reduce-cart-abandonment.md +1 -2
  151. package/skills/wix-manage/references/ecommerce/guardrail-shipping-health.md +2 -2
  152. package/skills/wix-manage/references/ecommerce/recipe-apply-shipping-recommendations.md +4 -5
  153. package/skills/wix-manage/references/ecommerce/recommend-ecommerce-strategy.md +7 -7
  154. package/skills/wix-manage/references/ecommerce/setup-discount-rules.md +209 -72
  155. package/skills/wix-manage/references/ecommerce/setup-store-pickup-location.md +9 -10
  156. package/skills/wix-manage/references/ecommerce/skill-graph.md +4 -4
  157. package/skills/wix-manage/references/forms/create-form.md +50 -0
  158. package/skills/wix-manage/references/stores/bulk-create-products-with-options.md +2 -0
  159. package/skills/wix-manage/references/stores/create-product-from-image.md +91 -38
  160. package/skills/wix-manage/references/stores/setup-online-store-catalog-v3.md +2 -0
  161. package/skills/wix-app/references/custom-element-widget/default-thumbnail.png +0 -0
  162. package/skills/wix-app/references/data-collection/extension-template.ts +0 -107
  163. package/skills/wix-headless/references/ORCHESTRATION.md +0 -269
  164. package/skills/wix-headless/references/commands/install-app.md +0 -42
  165. package/skills/wix-headless/references/commands/mcp-bootstrap.md +0 -28
  166. package/skills/wix-headless/references/designer/INSTRUCTIONS.md +0 -828
  167. package/skills/wix-headless/references/shared/MCP_PREFIX.md +0 -105
  168. package/skills/wix-headless/scripts/copy-utility-templates.mjs +0 -153
  169. package/skills/wix-headless/scripts/finalize-run-json.mjs +0 -141
  170. package/skills/wix-headless/scripts/init-site-json.mjs +0 -63
  171. package/skills/wix-headless/scripts/preview.sh +0 -45
  172. package/skills/wix-headless/scripts/release.sh +0 -73
  173. package/skills/wix-headless/templates/ecom/components-ecom.css +0 -215
  174. package/skills/wix-manage/references/events/list-events.md +0 -203
  175. /package/skills/wix-headless/{templates → references/astro/templates}/ecom/CartBadge.tsx +0 -0
  176. /package/skills/wix-headless/{templates → references/astro/templates}/ecom/CartView.tsx +0 -0
  177. /package/skills/wix-headless/{templates → references/astro/templates}/ecom/cart.astro +0 -0
  178. /package/skills/wix-headless/{templates → references/astro/templates}/ecom/discounts.ts +0 -0
  179. /package/skills/wix-headless/{templates → references/astro/templates}/ecom/thank-you.astro +0 -0
  180. /package/skills/wix-headless/{templates → references/astro/templates}/gift-cards/GiftCardPurchase.tsx +0 -0
  181. /package/skills/wix-headless/{templates → references/astro/templates}/gift-cards/_home-teaser-snippet.astro +0 -0
  182. /package/skills/wix-headless/{templates → references/astro/templates}/gift-cards/_nav-snippet.astro +0 -0
  183. /package/skills/wix-headless/{templates → references/astro/templates}/gift-cards/components-gift-cards.css +0 -0
  184. /package/skills/wix-headless/{templates → references/astro/templates}/gift-cards/gift-cards.astro +0 -0
  185. /package/skills/wix-headless/{templates → references/astro/templates}/gift-cards/gift-cards.ts +0 -0
  186. /package/skills/wix-headless/{templates → references/astro/templates}/stores/AddToCartButton.tsx +0 -0
  187. /package/skills/wix-headless/{templates → references/astro/templates}/stores/BackInStockForm.tsx +0 -0
  188. /package/skills/wix-headless/{templates → references/astro/templates}/stores/CategoryRail.astro +0 -0
  189. /package/skills/wix-headless/{templates → references/astro/templates}/stores/ProductCard.astro +0 -0
  190. /package/skills/wix-headless/{templates → references/astro/templates}/stores/ProductPurchase.tsx +0 -0
  191. /package/skills/wix-headless/{templates → references/astro/templates}/stores/SeoTags.astro +0 -0
  192. /package/skills/wix-headless/{templates → references/astro/templates}/stores/categories.ts +0 -0
  193. /package/skills/wix-headless/{templates → references/astro/templates}/stores/category/[slug].astro +0 -0
  194. /package/skills/wix-headless/{templates → references/astro/templates}/stores/products/[slug].astro +0 -0
  195. /package/skills/wix-headless/{templates → references/astro/templates}/stores/products/index.astro +0 -0
@@ -1,225 +1,25 @@
1
- # CMS Foundations — Shared Patterns for `@wix/data`
1
+ # CMS Foundations — Seeding via `@wix/data` REST (business track)
2
2
 
3
- Core patterns used by all CMS use cases: service module template, `@wix/data` queries, image resolution, elevated access, MCP seeding, and rich-text (Ricos) rendering.
3
+ The **seeding** half of CMS foundations: create collections and insert + verify sample items via the Wix Data REST API. This is frontend-blind business-track work — a collection and its items are the same regardless of what renders them.
4
4
 
5
- > **Import note (read first).** Page code in this plugin uses `import * as items from "@wix/wix-data-items-sdk"` rather than the documented `import { items } from "@wix/data"`. The Wix-headless docs still show the `@wix/data` form, but `@wix/data` 1.0.448 dropped the `items` re-export — only sub-namespaces (`backups`, `collections`, `permissions`, …) remain, and the documented form fails the build with `'items' is not exported by '@wix/data'`. The actual `items` API (with `query`, `insert`, `update`, `remove`, `bulkInsert`, etc.) lives in `@wix/wix-data-items-sdk`, which `@wix/data` depends on transitively. Importing from there directly works on every current `@wix/data` version. The cms vertical pack adds `@wix/wix-data-items-sdk` to the install list so it's always present (`references/verticals/cms.md`). Use the wix-data-items-sdk import everywhere.
5
+ > **Rendering / page code lives in the astro frontend track.** The service-module template, `@wix/data` SDK query patterns, image resolution, Ricos rendering, and category filtering are **not** here — they are in `<SKILL_ROOT>/references/astro/cms/CMS_FOUNDATIONS.md` (the `pages` scope's doc). This file is consumed by the `seed` scope. The `cms/INSTRUCTIONS.md` router points each scope at the right half.
6
6
 
7
- ## Rendering Ricos rich-text fields
7
+ ## Collection ID Format (seeding-relevant)
8
8
 
9
- Wix CMS stores `RICH_TEXT` / `RICH_CONTENT` fields as **Ricos JSON** — a structured node tree (PARAGRAPH, HEADING, BULLETED_LIST, etc.), not HTML. The dashboard's rich-text editor reads and writes this format.
9
+ Native (user-created) CMS collections use **just the collection name** — no namespace prefix (e.g. `"about-content"`, `"faq"`, `"Projects"`). Only Wix App collections use a `<namespace>/<name>` format. Use the exact `id` you create here; verify with `GET /wix-data/v2/collections?fields=id` (standard REST headers from `../shared/AUTHENTICATION.md`). Never guess — the dashboard display name may differ from the ID.
10
10
 
11
- For SSR Astro pages (about, faq, portfolio, team, resource), import the seeded `renderRicos` util from `src/utils/ricos.ts`. The util is shipped by `seed-utilities.sh` (copied from `<SKILL_ROOT>/shared-utilities/ricos.ts` during Setup), so it's already on disk — do NOT inline a Ricos walker in your page.
11
+ ## Seeding via REST (Conditional)
12
12
 
13
- ```astro
14
- ---
15
- import * as items from "@wix/wix-data-items-sdk";
16
- import { auth } from "@wix/essentials";
17
- import { renderRicos } from "../utils/ricos";
18
-
19
- const elevatedQuery = auth.elevate(items.query);
20
- const { items: results } = await elevatedQuery("about-content")
21
- .limit(1)
22
- .find();
23
- const about = results[0];
24
- const bodyHtml = renderRicos(about?.body);
25
- ---
26
-
27
- <article class="prose">
28
- <h1>{about?.heading}</h1>
29
- <div set:html={bodyHtml} />
30
- </article>
31
- ```
32
-
33
- The util covers the common subset (PARAGRAPH, HEADING 1-6, BULLETED_LIST / ORDERED_LIST / LIST_ITEM, BLOCKQUOTE, DIVIDER + BOLD / ITALIC / UNDERLINE / LINK decorations). Anything outside that set renders defensively as a `<p>` with the raw text — never throws.
34
-
35
- > **Why not @wix/ricos?** The blog vertical uses `@wix/ricos`'s React `RicosViewer` as a client island because blog posts can carry the full Ricos feature set (galleries, polls, embedded media). For static CMS pages, that's ~80kb of React for paragraphs and lists — overkill. Use the seeded SSR walker instead.
36
-
37
- > **Do NOT `set:html={item.body}` directly.** That ships JSON-encoded text into the page (e.g. `[object Object]` or `{"nodes":...}`). Always go through `renderRicos`.
38
-
39
- > **Critical Rules — Read Before Starting**
40
- > 1. **Collection IDs have NO namespace** — user collections use just the name (e.g., `"Projects"`). Only Wix App collections use `<namespace>/<name>`. Verify via MCP: `GET /wix-data/v2/collections?fields=id`.
41
- > 2. **SDK query pattern** — `items.query("CollectionId").find()`. There is no `items.queryDataItems()` in the SDK.
42
- > 3. **`auth.elevate` on every query** — without it, restricted collections silently return no items.
43
- > 4. **CMS only for user collections** — use `@wix/blog` for blog posts, `@wix/stores` for products, `@wix/forms` for form submissions.
44
-
45
- ## Prerequisites
46
-
47
- - `@wix/data` package installed (collected by features orchestrator — do NOT install independently)
48
- - `@wix/essentials` package installed (for elevation)
49
- - A data collection created in the Wix dashboard → CMS section
50
- - No special Wix app installation needed — `@wix/data` works with any Wix Managed Headless project
51
-
52
- ## Collection ID Format
53
-
54
- Native (user-created) CMS collections use **just the collection name** — no namespace prefix.
55
-
56
- Example: if the collection is called `Projects`, the collection ID is simply `"Projects"`.
57
-
58
- Only Wix App collections (e.g., `Members/PublicData`, `Locations/Locations`) use a `<namespace>/<name>` format. User-created collections never use a namespace.
59
-
60
- > **How to verify**: Call `GET /wix-data/v2/collections?fields=id` via MCP and use the exact `id` value from the response. Never guess — the dashboard name may differ from the ID.
61
-
62
- ## Quick Reference — Inline Query (Simple Pages)
63
-
64
- For pages that just need to list items from a collection:
65
-
66
- ```astro
67
- ---
68
- import * as items from "@wix/wix-data-items-sdk";
69
- import { auth } from "@wix/essentials";
70
-
71
- // Always elevate queries for permission safety
72
- const elevatedQuery = auth.elevate(items.query);
73
- const { items: results } = await elevatedQuery("MyCollection")
74
- .ascending("sortField")
75
- .limit(50)
76
- .find();
77
-
78
- // Fields are directly on each item (NOT item.data.field)
79
- const myItems = results.map((item) => ({
80
- name: item.name, // correct
81
- // name: item.data.name // wrong — REST pattern, not SDK
82
- }));
83
- ---
84
- ```
85
-
86
- > **Common mistake:** `items.queryDataItems(...)` does NOT exist in the
87
- > `@wix/data` SDK. The REST API uses `/items/query` with a `dataCollectionId`
88
- > body field, but the SDK uses `items.query("collectionId")` — a chainable
89
- > QueryBuilder. Do not confuse REST and SDK patterns.
90
-
91
- ## Service Module Template
92
-
93
- Every CMS use case follows the same `src/lib/{usecase}.ts` pattern — a typed interface and query functions that pages import.
94
-
95
- ```typescript
96
- import * as items from "@wix/wix-data-items-sdk";
97
- import { auth } from "@wix/essentials";
98
- import { media } from "@wix/sdk";
99
-
100
- // -- Collection ID (use exact name from Wix dashboard — no namespace for native collections) --
101
- const COLLECTION_ID = "collection-name";
102
-
103
- // -- Typed interface matching collection fields --
104
- export interface CollectionItem {
105
- _id: string;
106
- title: string;
107
- slug: string;
108
- // ...add fields matching your collection schema
109
- coverImage?: string;
110
- }
111
-
112
- // -- Image resolution helper --
113
- function resolveImage(wixImageUrl: string | undefined, width = 800, height = 600): string | undefined {
114
- if (!wixImageUrl) return undefined;
115
- return media.getScaledToFillImageUrl(wixImageUrl, width, height, {});
116
- }
117
-
118
- // -- Query all items --
119
- // Wrap every Wix SDK await in try/catch. If the query throws at SSR, an empty
120
- // array keeps the page renderable instead of crashing it. (Unguarded SSR
121
- // awaits truncate Astro's response stream mid-body — nav renders, then blank.)
122
- export async function queryItems(): Promise<CollectionItem[]> {
123
- try {
124
- const elevatedQuery = auth.elevate(items.query);
125
- const { items: results } = await elevatedQuery(COLLECTION_ID)
126
- .ascending("orderIndex")
127
- .limit(50)
128
- .find();
129
-
130
- return results.map((item) => ({
131
- ...item,
132
- coverImage: resolveImage(item.coverImage),
133
- })) as CollectionItem[];
134
- } catch (err) {
135
- console.error(`[cms:${COLLECTION_ID}] query failed:`, err);
136
- return [];
137
- }
138
- }
139
-
140
- // -- Get single item by slug --
141
- export async function getItemBySlug(slug: string): Promise<CollectionItem | null> {
142
- try {
143
- const elevatedQuery = auth.elevate(items.query);
144
- const { items: results } = await elevatedQuery(COLLECTION_ID)
145
- .eq("slug", slug)
146
- .limit(1)
147
- .find();
148
-
149
- const item = results[0];
150
- if (!item) return null;
151
-
152
- return {
153
- ...item,
154
- coverImage: resolveImage(item.coverImage),
155
- } as CollectionItem;
156
- } catch (err) {
157
- console.error(`[cms:${COLLECTION_ID}] getItemBySlug failed:`, err);
158
- return null;
159
- }
160
- }
161
- ```
162
-
163
- Key details:
164
- - `auth.elevate(items.query)` wraps the query for restricted collections — always use this by default since collection permissions vary
165
- - `media.getScaledToFillImageUrl(url, w, h, {})` resolves `wix:image://` URLs to sized CDN URLs
166
- - Sort by `orderIndex` (ascending) for manually ordered content, or `_createdDate` (descending) for chronological
167
- - The interface must match the collection fields — check the dashboard, don't guess
168
-
169
- ## Multi-Image Resolution
170
-
171
- For collections with image arrays (e.g., gallery images):
172
-
173
- ```typescript
174
- function resolveImages(imageUrls: string[] | undefined, width = 800, height = 600): string[] {
175
- if (!imageUrls || imageUrls.length === 0) return [];
176
- return imageUrls
177
- .map((url) => media.getScaledToFillImageUrl(url, width, height, {}))
178
- .filter(Boolean);
179
- }
180
- ```
181
-
182
- ## Category Filtering Pattern
183
-
184
- Many use cases filter by category via URL search params (server-rendered, no client JS):
185
-
186
- ```astro
187
- ---
188
- const activeCategory = Astro.url.searchParams.get("category");
189
- const allItems = await queryItems();
190
- const filtered = activeCategory
191
- ? allItems.filter((item) => item.category === activeCategory)
192
- : allItems;
193
- const categories = [...new Set(allItems.map((item) => item.category).filter(Boolean))];
194
- ---
195
-
196
- <nav>
197
- <a href="?" class:list={[!activeCategory && "active"]}>All</a>
198
- {categories.map((cat) => (
199
- <a
200
- href={`?category=${encodeURIComponent(cat)}`}
201
- class:list={[activeCategory === cat && "active"]}
202
- >{cat}</a>
203
- ))}
204
- </nav>
205
- ```
206
-
207
- > **Styling note:** Category filter pill styling is created by the design skill. See `COMPONENT_PATTERNS.md` → Category Filter.
208
-
209
- ## MCP Seeding (Conditional)
210
-
211
- If Wix MCP tools are available, check if the collection has data and seed sample items if empty. This is **conditional** — only attempt if MCP is connected.
13
+ Check whether the collection already has data; seed sample items only if empty. Calls go through `curl` against `wixapis.com` with the site-scoped REST token (see `../shared/AUTHENTICATION.md`) — no SDK, no MCP.
212
14
 
213
15
  1. Query the collection — if items exist, skip seeding
214
- 2. If empty, create the collection and insert sample items via MCP (see templates below)
16
+ 2. If empty, create the collection and insert sample items via the REST calls below
215
17
  3. Design sample data that matches the business type from the functional plan
216
18
 
217
- > MCP seeding is optional. If MCP tools are not available, instruct the user to add content via the Wix dashboard → CMS section.
218
-
219
19
  ### Create collection (if it doesn't exist)
220
20
 
221
21
  ```
222
- <prefix>CallWixSiteAPI: POST https://www.wixapis.com/wix-data/v2/collections
22
+ REST: POST https://www.wixapis.com/wix-data/v2/collections
223
23
  body: {
224
24
  "collection": {
225
25
  "id": "about-content",
@@ -238,7 +38,7 @@ body: {
238
38
  **This is the critical step that must include actual field values.** Creating an item without populating the `data` object results in an empty record — the collection schema exists but the item has no content.
239
39
 
240
40
  ```
241
- <prefix>CallWixSiteAPI: POST https://www.wixapis.com/wix-data/v2/items
41
+ REST: POST https://www.wixapis.com/wix-data/v2/items
242
42
  body: {
243
43
  "dataCollectionId": "about-content",
244
44
  "dataItem": {
@@ -250,14 +50,14 @@ body: {
250
50
  }
251
51
  ```
252
52
 
253
- The response returns the created item's `_id` — collect these for the Phase 1 return contract.
53
+ The response returns the created item's `_id` — collect these for the seed return contract.
254
54
 
255
55
  **Every text field must be populated in the `data` object.** Do not create items with empty `data: {}` and expect Phase 2 or the image agent to fill in text fields — they only handle their own scope (pages and images respectively).
256
56
 
257
57
  For FAQ items, include both `question` and `answer` plus `sortOrder`:
258
58
 
259
59
  ```
260
- <prefix>CallWixSiteAPI: POST https://www.wixapis.com/wix-data/v2/items
60
+ REST: POST https://www.wixapis.com/wix-data/v2/items
261
61
  body: {
262
62
  "dataCollectionId": "faq",
263
63
  "dataItem": {
@@ -270,12 +70,14 @@ body: {
270
70
  }
271
71
  ```
272
72
 
73
+ > **Bulk insert (N ≥ 2 items):** use the `wix-manage` skill's recipe — `wix-manage/references/cms/cms-data-items-crud.md` § "Bulk Insert Items" (`POST /wix-data/v2/bulk/items/insert`, up to 1000/call, one `dataCollectionId` per call → fire one bulk call per collection as a parallel batch). It also documents bulk update/patch/delete. Do not hand-roll N single inserts for a multi-item seed.
74
+
273
75
  ### Verify inserts with a live query (mandatory)
274
76
 
275
77
  After inserting all items, **query each collection once** and confirm every field you sent is present in the stored `data`. A POST without errors does NOT prove the content persisted — the API has accepted insert bodies with missing fields before, and the failure is invisible until a human opens the page.
276
78
 
277
79
  ```
278
- <prefix>CallWixSiteAPI: POST https://www.wixapis.com/wix-data/v2/items/query
80
+ REST: POST https://www.wixapis.com/wix-data/v2/items/query
279
81
  body: { "dataCollectionId": "<collection>" }
280
82
  ```
281
83
 
@@ -287,12 +89,13 @@ For every returned item, confirm its `data` object contains every text field you
287
89
 
288
90
  A CMS seeder can return `complete` for an about-content item, then Image Phase 2 silently wipes its `heading` + `body` via a destructive full-record PUT. The verify-after-insert step here plus the read-merge-PUT rule in the images agent makes that class of data loss unreachable.
289
91
 
290
- ### MCP Seeding with Images
92
+ ### Seeding with Images
291
93
 
292
94
  For use cases with image fields (`photo`, `coverImage`, `galleryImages`),
293
- follow `../../shared/IMAGE_GENERATION.md` (Steps 1–2) for Wix AI image
294
- generation and Wix Media import. Image generation is MCP-authenticated
295
- and always available — do not ask the user for credentials.
95
+ follow `../shared/IMAGE_GENERATION.md` (Steps 1–2) for Wix AI image
96
+ generation and Wix Media import. Image generation goes through the same
97
+ CLI-minted REST token as the rest of this skill — do not ask the user for
98
+ credentials.
296
99
 
297
100
  **Workflow:**
298
101
 
@@ -303,14 +106,14 @@ and always available — do not ask the user for credentials.
303
106
 
304
107
  ```
305
108
  # Step a: read the existing item
306
- <prefix>CallWixSiteAPI: POST https://www.wixapis.com/wix-data/v2/items/query
109
+ REST: POST https://www.wixapis.com/wix-data/v2/items/query
307
110
  body: {
308
111
  "dataCollectionId": "CollectionName",
309
112
  "query": { "filter": { "_id": { "$in": ["{itemId}"] } } }
310
113
  }
311
114
 
312
115
  # Step b: merge image into existing data and PUT the full record
313
- <prefix>CallWixSiteAPI: PUT https://www.wixapis.com/wix-data/v2/items/{itemId}
116
+ REST: PUT https://www.wixapis.com/wix-data/v2/items/{itemId}
314
117
  body: {
315
118
  "dataCollectionId": "CollectionName",
316
119
  "dataItem": {
@@ -322,24 +125,24 @@ body: {
322
125
 
323
126
  `...existingData` must include every non-system field from step a (system fields `_id`, `_owner`, `_createdDate`, `_updatedDate` don't need to be echoed). Skipping the merge wipes seeded text fields and ships an empty About page.
324
127
 
325
- **Prompt templates** — each use-case reference defines its own prompt template (see the "Seed with Images" section in TEAM_DIRECTORY.md, PORTFOLIO.md, RESOURCE_LIBRARY.md). Always incorporate brand context from the discovery/design phases.
128
+ **Prompt templates** — each use-case reference defines its own prompt template (see the "Seed with Images" section in `../astro/cms/TEAM_DIRECTORY.md`, `../astro/cms/PORTFOLIO.md`, `../astro/cms/RESOURCE_LIBRARY.md`). Always incorporate brand context from the discovery/design phases.
326
129
 
327
130
  **Constraints:**
328
131
  - Never block the main flow on image failures — text data is already seeded
329
132
  - Runware image URLs are short-lived — import to Wix Media immediately after generation
330
133
  - If image generation or import fails for a single item, skip that item and continue with others
331
- - If all generation fails (credits exhausted, MCP errors), write the sidecar with `Status: partial` and proceed — but always attempt first
332
- - FAQ_KNOWLEDGE_BASE has no image fields — skip image generation for FAQ use cases
134
+ - If all generation fails (credits exhausted, upstream Runware errors), write the sidecar with `Status: partial` and proceed — but always attempt first
135
+ - `../astro/cms/FAQ_KNOWLEDGE_BASE.md` has no image fields — skip image generation for FAQ use cases
333
136
 
334
137
  ## Return Results
335
138
 
336
- Emit a structured JSON block at the end of your completion message per `../../shared/RETURN_CONTRACT.md`. Do NOT write sidecar files.
139
+ Emit a structured JSON block at the end of your completion message per `../shared/RETURN_CONTRACT.md`. Do NOT write sidecar files.
337
140
 
338
141
  ```json
339
142
  {
340
143
  "status": "complete",
341
144
  "phase": "cms-seed",
342
- "scope": "seed-seed",
145
+ "scope": "seed",
343
146
  "summary": "Created {N} collections; seeded {M} items; verified every field persisted",
344
147
  "data": {
345
148
  "collections": [
@@ -359,15 +162,15 @@ Emit a structured JSON block at the end of your completion message per `../../sh
359
162
  ```
360
163
 
361
164
  - `storedFields` MUST match the real keys seen in the verify-after-insert query response's `data` object (see § "Verify inserts with a live query"). Downstream pages agents compare against this — if you return `fields: ["heading", "body"]` but only `heading` was actually stored, pages render empty bodies.
362
- - `sampleValues` is a single example item's field-to-short-string map. Lets downstream agents spot-check that content is real without another MCP round-trip. Truncate rich-text bodies to the first ~80 characters.
165
+ - `sampleValues` is a single example item's field-to-short-string map. Lets downstream agents spot-check that content is real without another REST round-trip. Truncate rich-text bodies to the first ~80 characters.
363
166
  - For collections without image fields (e.g., FAQ), set `imageField: null`.
364
167
  - The JSON block MUST be the last content in your message.
365
168
 
366
- ## Testing
169
+ ## Testing (seed-side)
170
+
171
+ 1. Create a data collection in the Wix dashboard → CMS (or via the REST `POST /collections` above).
172
+ 2. Add fields matching the use case schema (see the specific use case reference under `../astro/cms/`).
173
+ 3. Add at least 2–3 items with all fields populated, including `slug` and `published` (if applicable).
174
+ 4. Run the verify-after-insert query and confirm every field persisted.
367
175
 
368
- 1. Create a data collection in the Wix dashboard → CMS
369
- 2. Add fields matching the use case schema (see the specific use case reference)
370
- 3. Add at least 2–3 items with all fields populated, including `slug` and `published` (if applicable)
371
- 4. Run `npx @wix/cli dev`
372
- 5. Navigate to the listing page — should show items
373
- 6. Click an item — should navigate to the detail page
176
+ Page rendering / SDK query patterns for these collections are in `../astro/cms/CMS_FOUNDATIONS.md`.
@@ -5,14 +5,14 @@ description: "Implements structured content pages (About, FAQ, portfolios, team
5
5
 
6
6
  # CMS Implementer
7
7
 
8
- Extends `references/shared/IMPLEMENTER.md`. Read that file first for phase routing, MCP prefix, site.json read pattern, return contract, style conventions, and common failure modes.
8
+ Extends `references/shared/IMPLEMENTER.md`. Read that file first for phase routing, REST auth + doc lookups, prompt-inlined inputs (read only your `.wix/seeded.json` slice), return contract, style conventions, and common failure modes.
9
9
 
10
10
  ## Scope routing
11
11
 
12
12
  | Scope | Phase | Reference |
13
13
  |-------|-------|-----------|
14
- | `seed` | Seed (create collections + seed items via MCP) | `./CMS_FOUNDATIONS.md` (§ seeding) + use-case ref |
15
- | `pages` | Pages (About + FAQ pages read CMS via @wix/data inline) | `./CMS_FOUNDATIONS.md` (§ code patterns) + use-case ref |
14
+ | `seed` | Seed (create collections + seed items via REST) | `./CMS_FOUNDATIONS.md` (seeding, business half) + use-case ref under `../astro/cms/` (collection schema + seed-with-images) |
15
+ | `pages` | Pages (About + FAQ pages read CMS via @wix/data inline) | `../astro/cms/CMS_FOUNDATIONS.md` (code patterns) + use-case ref under `../astro/cms/` |
16
16
 
17
17
  No `components` scope — CMS pages SSR content inline via `@wix/data`; no React islands.
18
18
 
@@ -20,21 +20,52 @@ No `components` scope — CMS pages SSR content inline via `@wix/data`; no React
20
20
 
21
21
  Pick based on the business type (the orchestrator names one in your prompt):
22
22
 
23
- - `./FAQ_KNOWLEDGE_BASE.md` — Q&A accordions, category sections, search
24
- - `./PORTFOLIO.md` — project grid, category filter tabs, project detail
25
- - `./TEAM_DIRECTORY.md` — department-grouped directory, staff cards
26
- - `./RESOURCE_LIBRARY.md` — file listings, download buttons, file type badges
23
+ - `../astro/cms/FAQ_KNOWLEDGE_BASE.md` — Q&A accordions, category sections, search
24
+ - `../astro/cms/PORTFOLIO.md` — project grid, category filter tabs, project detail
25
+ - `../astro/cms/TEAM_DIRECTORY.md` — department-grouped directory, staff cards
26
+ - `../astro/cms/RESOURCE_LIBRARY.md` — file listings, download buttons, file type badges
27
27
 
28
28
  ## Files this vertical creates / contributes
29
29
 
30
30
  See `<SKILL_ROOT>/references/verticals/cms.md` frontmatter.
31
31
 
32
+ ## Seed return
33
+
34
+ The `seed` scope emits this `data` shape in its return JSON (envelope rules in `../shared/RETURN_CONTRACT.md`). Phase 4 CMS page agents reference these collection names; the image agent attaches entity images to CMS items by ID.
35
+
36
+ ```json
37
+ {
38
+ "status": "complete",
39
+ "phase": "cms-seed",
40
+ "scope": "seed",
41
+ "data": {
42
+ "collections": [
43
+ {
44
+ "name": "about-content",
45
+ "itemIds": ["665f3363-..."],
46
+ "fields": ["heading", "body", "image"]
47
+ },
48
+ {
49
+ "name": "faq",
50
+ "itemIds": ["abc", "def", "ghi", "jkl", "mno", "pqr"],
51
+ "fields": ["question", "answer", "sortOrder"]
52
+ }
53
+ ]
54
+ }
55
+ }
56
+ ```
57
+
58
+ ## Page width (FAQ, About, long-form CMS)
59
+
60
+ Read `references/shared/STYLING.md` § "Prose / reading width". **Do not** wrap FAQ/About body copy in `max-w-3xl` unless `--container-3xl` exists in `src/styles/global.css` `@theme`. Prefer `container-reading`, `max-w-6xl` (when `--container-6xl` is defined), or `max-w-[48rem]`. A bare `max-w-3xl` with only a spacing scale ships a ~80px column.
61
+
32
62
  ## CMS-specific failure modes
33
63
 
34
64
  | Wrong | Right |
35
65
  |---|---|
36
66
  | `items.queryDataItems(...)` / `items.query({ dataCollectionId })` | `items.query("CollectionId").find()` — queryDataItems doesn't exist |
37
67
  | React islands for static content pages | SSR inline with `@wix/data`; no islands needed |
68
+ | `max-w-3xl` on FAQ/About wrappers without `--container-3xl` in `@theme` | `container-reading` or `max-w-[48rem]` / `max-w-6xl` per STYLING.md |
38
69
  | Return `status: "complete"` without re-querying the collection | Always run the verify-after-insert query (see CMS_FOUNDATIONS.md § "Verify inserts with a live query"); fail fast if any field is missing |
39
70
  | Report `fields: [...]` guessed from the insert body | Report `storedFields: [...]` matching the actual keys in the query response's `data` object — pages agents compare against these |
40
- | Assume text fields survive downstream image PATCHes | Seeder's job is to verify content is present; images agent must preserve via read-merge-PUT (images INSTRUCTIONS.md § "CMS Items") |
71
+ | Assume text fields survive downstream image PATCHes | Seeder's job is to verify content is present; images agent must preserve via read-merge-PUT (images INSTRUCTIONS.md § "CMS Items") |
@@ -1,5 +1,6 @@
1
1
  {
2
2
  "wix-stores": "215238eb-22a5-4c36-9e7b-e7c08025e04e",
3
3
  "wix-forms": "225dd912-7dea-4738-8688-4b8c6955ffc2",
4
- "wix-blog": "14bcded7-0066-7c35-14d7-466cb3f09103"
4
+ "wix-blog": "14bcded7-0066-7c35-14d7-466cb3f09103",
5
+ "wix-gift-cards": "d80111c5-a0f4-47a8-b63a-65b54d774a27"
5
6
  }
@@ -0,0 +1,142 @@
1
+ ---
2
+ name: connection-plan
3
+ description: "Integration-mode subagent: read the brought-in site and emit the connection plan — a binding map (existing dynamic regions to wire to Wix) plus an augmentation spec (the connected component to add when the design has none). The orchestrator feeds this to the per-capability wiring subagents. Input-general: infer from the markup; a Claude-Design bundle is optional enrichment."
4
+ ---
5
+
6
+ # Connection plan (integration mode)
7
+
8
+ You are a planning subagent for the `wix-headless` skill's **integration mode** (`frontend = "custom"`). The user brought a finished, working site (HTML+CSS/JS) and the skill is connecting it to a live Wix backend. **Your job is to read the site and decide exactly what to connect** — you write **no code**; you return a structured plan the wiring subagents execute.
9
+
10
+ ## Inputs (inlined by the orchestrator)
11
+
12
+ - The project's file list + the entry HTML path(s).
13
+ - The **inferred capability set** from Discovery (e.g. `["forms"]`, `["stores"]`, `["blog","forms"]`, `["cms"]` for a client-state app).
14
+ - The resolved **`frontendBuild`** (`none` ⇒ read rendered markup; `own` ⇒ read un-built `src/**` source). The entry-HTML shape is enough on its own (see § "What to read"), but this confirms it.
15
+ - Whether a Claude-Design handoff bundle is present (`README.md`, `chats/`).
16
+
17
+ ## What to read — rendered markup OR un-built source
18
+
19
+ A brought-in frontend comes in **two shapes**, and you read whichever you're given (this is input-adaptation, *not* a framework branch of the flow — the structures you emit are the same regardless of framework):
20
+
21
+ 1. **Rendered markup (static HTML).** The entry HTML carries real content. Read the entry HTML and any other pages. Extract: `<title>`, headings, body copy, `<form>`s, repeated element structures, and the **CSS custom-property token block** (`:root { --… }` — names + values).
22
+ 2. **Un-built SPA source.** The entry HTML is a near-empty shell — `<div id="root"></div>` + `<script type="module" src="/src/main.jsx">` — so it has **no rendered content** to detect regions in. **Read the source instead** (`src/**`: the root component, any data/store modules, `*.css`). Identify how the app **persists state today** — a `localStorage` read/write, an in-memory store, a `fetch` to a stub — and the **in-memory data shape** it keeps. This is the signal for a `persistenceSwap` (structure (c)). Detecting this is what stops an SPA from collapsing to the contact-form floor.
23
+ 3. **The handoff bundle (opportunistic, if present).** Read `chats/` and `README.md` to sharpen intent — but the plan must stand on the source/markup alone, since most inputs have no bundle.
24
+
25
+ > **How do you know which shape you're reading?** If the entry HTML has a `<div id="root">`/`<div id="app">` mount + a module script pointing at `src/` and little else, it's un-built SPA source → read `src/**`. Otherwise it's rendered markup. (The orchestrator also passes the resolved `frontendBuild` — `own` ⇒ source, `none` ⇒ markup — but the markup signal alone is enough.)
26
+
27
+ ## Produce two structures
28
+
29
+ ### (a) Binding map — existing dynamic regions to wire
30
+
31
+ Detect regions the design already shaped for data. **Detection ladder, highest-confidence first:**
32
+
33
+ 1. **Explicit annotations** — `data-wix-*`, semantic `id`/`class` (`product-grid`, `post-list`), schema.org microdata / `itemtype`.
34
+ 2. **Repetition + shape** — a container with N near-identical children, each holding image + title-like text + price-like text ⇒ a product list; N dated heading+excerpt blocks ⇒ a post list.
35
+ 3. **Form semantics** — a `<form>` with recognizable fields ⇒ a submit target.
36
+ 4. **Single-detail** — one entity's worth of fields (gallery + title + price + description) ⇒ a detail view.
37
+
38
+ One entry per region:
39
+
40
+ ```jsonc
41
+ {
42
+ "file": "index.html",
43
+ "anchor": "section.product-grid", // a stable CSS selector into the existing DOM
44
+ "entity": "stores.products", // stores.products | blog.posts | forms.submit | data.items | bookings.services
45
+ "shape": "list", // list | detail | single | submit
46
+ "template": "article.product-card", // the repeated child to clone per result (list shapes)
47
+ "bindings": { // DOM node (relative to template) → entity field
48
+ "img.thumb@src": "media.mainMedia.image.url",
49
+ "h3.name": "name",
50
+ "span.price": "priceData.formatted.price"
51
+ },
52
+ "sampleCount": 3 // hard-coded samples to remove after wiring
53
+ }
54
+ ```
55
+
56
+ A purely static editorial design (e.g. a wedding invitation) yields an **empty binding map** — that is expected; the augmentation spec carries it.
57
+
58
+ ### (b) Augmentation spec — the connected feature to ADD
59
+
60
+ Per the **always-connect** rule (`INSTRUCTIONS.md` § "Always connect"), every run must end connected. If the inferred capability has no existing region to wire, emit the connected component to inject. Derive the capability from Discovery's inference; the universal floor is a Wix Forms contact/lead form.
61
+
62
+ ```jsonc
63
+ {
64
+ "capability": "rsvp", // rsvp | lead | contact | (or a read capability if augmenting reads)
65
+ "app": "wix-forms",
66
+ "component": "rsvp-form",
67
+ "injectAt": { "file": "index.html", "anchor": "section.closing", "position": "before" },
68
+ "fields": [ // becomes BOTH the Wix Form definition (seed) and the <form>
69
+ { "name": "fullName", "label": "Your name", "type": "text", "required": true },
70
+ { "name": "attending", "label": "Will you attend?", "type": "radio", "options": ["Joyfully accepts","Regretfully declines"] },
71
+ { "name": "guests", "label": "Number of guests", "type": "number" },
72
+ { "name": "dietary", "label": "Dietary notes", "type": "textarea" }
73
+ ],
74
+ "styleFrom": { "selector": ":root", "tokens": ["--terracotta","--sage","--display","--body","--label"] }
75
+ }
76
+ ```
77
+
78
+ - **`injectAt`** — pick a natural seam in the existing layout (before the closing/footer section, after the hero). Use a stable selector that exists in the markup.
79
+ - **`styleFrom`** — list the actual CSS custom-property names you found in the site, so the wiring subagent styles the injected component to match. If the site has no `:root` tokens, list the dominant colors/fonts you observed instead.
80
+ - Multiple capabilities → one augmentation entry each (an array).
81
+
82
+ ### (c) Persistence swap — replace a client-state app's data layer with a CMS collection
83
+
84
+ For an **app with client/local state** (todo, notes, tracker, planner, kanban — `INSTRUCTIONS.md` § "Always connect" client-state row), the connection is neither a binding map (no rendered regions in the un-built shell) nor an augmentation (nothing to *add* — the UI exists). It is a **persistence swap**: the app's existing load/save data layer is replaced with `@wix/data`, and the in-memory shape becomes a CMS collection schema. Emit one entry per persisted entity-shape:
85
+
86
+ ```jsonc
87
+ {
88
+ "sourceFile": "src/App.jsx", // the file holding the data layer (where the swap is applied)
89
+ "dataLayer": { // the functions/effects to rewrite — NAME them, don't rewrite here
90
+ "load": ["load() (reads localStorage 'lists')"],
91
+ "save": ["useEffect persisting 'lists'", "useEffect persisting 'activeId'"],
92
+ "storage": "localStorage" // localStorage | in-memory | fetch-stub
93
+ },
94
+ "inferredShape": { // the in-memory shape → becomes the collection schema (the seeder reads this)
95
+ "collection": "Todos", // PascalCase collection name to seed
96
+ "fields": [ // name + Wix Data field type
97
+ { "name": "text", "type": "text" },
98
+ { "name": "done", "type": "boolean" },
99
+ { "name": "listId", "type": "text" }
100
+ ]
101
+ },
102
+ "shared": true // ALWAYS true — visitor token ⇒ one shared/public collection (per-user is deferred)
103
+ }
104
+ ```
105
+
106
+ - **One entry per distinct entity-shape.** A todo app with `lists` and `todos` yields **two** persistence-swap entries (a `Lists` collection: `name`; a `Todos` collection: `text`, `done`, `listId`).
107
+ - **`dataLayer`** — *name* the functions/effects the wiring agent will rewrite (with a one-line description of what each does today); do not write replacement code (the wiring agent does that, adapting to the framework idiom).
108
+ - **`inferredShape.fields`** — map each in-memory field to a Wix Data type (`text` | `number` | `boolean` | `datetime` | `url` | `image` | `richText` | `reference`). The **seeder** turns this into a public-read collection; the **cms wiring agent** turns the data layer into `@wix/data` `query/insert/update/remove` calls against it.
109
+ - **`shared`** — always `true`. The visitor token gives no per-user identity, so the collection is shared/public across all visitors. The plan should also surface this in `notes[]` so the orchestrator can caveat it to the user (`INSTRUCTIONS.md` § "Scope — deferred").
110
+ - This is **framework-blind**: a React, Vue, or Svelte SPA all produce the same `persistenceSwap` shape; only the wiring agent's idiom differs.
111
+
112
+ ## When detection is ambiguous
113
+
114
+ Do **not** guess silently and do **not** call `AskUserQuestion`. Wire the regions you're confident about; for anything unclear, omit it from the binding map and note it in `notes[]` so the wiring subagent can leave a visible `<!-- wix: … -->` comment.
115
+
116
+ **Choose the right output structure before falling through:**
117
+ - **Un-built SPA with a client-state data layer** → emit a **`persistenceSwap`** (structure (c)). **Do NOT fall through to the contact-form floor** — that is the exact nonsense the client-state row was added to fix (a todo app is not a contact form). The persistence swap *is* the connection.
118
+ - **Rendered markup with dynamic regions** → binding map.
119
+ - **Static design with no dynamic region** → augmentation.
120
+
121
+ Fall back to the **Forms contact-form floor** (a contact-form augmentation) only when there is genuinely **no** data layer, **no** rendered region, **and** no capability was inferred — not for a client-state SPA (see the bullet above). Never return an empty plan (no binding map AND no augmentation AND no persistence swap) — that would violate always-connect.
122
+
123
+ ## Return
124
+
125
+ Return a single JSON object per `shared/RETURN_CONTRACT.md` conventions:
126
+
127
+ ```jsonc
128
+ {
129
+ "status": "ok",
130
+ "data": {
131
+ "bindingMap": [ /* (a) entries, possibly empty */ ],
132
+ "augmentation": [ /* (b) entries — possibly empty when a persistenceSwap carries the connection */ ],
133
+ "persistenceSwap": [ /* (c) entries — present for client-state SPAs; empty otherwise */ ],
134
+ "tokens": { "--terracotta": "#B26049", "--display": "\"Cormorant Garamond\", serif" }, // resolved :root/source tokens for styling
135
+ "notes": [ /* ambiguous regions, omitted-but-noticed structures, the shared-data caveat for any persistenceSwap */ ]
136
+ }
137
+ }
138
+ ```
139
+
140
+ **Always-connect invariant:** at least one of `bindingMap`, `augmentation`, or `persistenceSwap` MUST be non-empty. (`augmentation` is no longer required ≥1 — a client-state SPA connects via `persistenceSwap` with no augmentation.)
141
+
142
+ You return data only — no prose to the user, no files written.