@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.
- package/README.md +5 -9
- package/package.json +1 -1
- package/skills/wix-app/SKILL.md +51 -42
- package/skills/wix-app/references/BACKEND_EVENT.md +10 -65
- package/skills/wix-app/references/CUSTOM_ELEMENT_WIDGET.md +101 -406
- package/skills/wix-app/references/DASHBOARD_MENU_PLUGIN.md +14 -111
- package/skills/wix-app/references/DASHBOARD_MODAL.md +56 -205
- package/skills/wix-app/references/DASHBOARD_PAGE.md +19 -98
- package/skills/wix-app/references/DASHBOARD_PLUGIN.md +6 -108
- package/skills/wix-app/references/DATA_COLLECTION.md +113 -198
- package/skills/wix-app/references/EMBEDDED_SCRIPT.md +41 -268
- package/skills/wix-app/references/EXTENSION_REGISTRATION.md +27 -76
- package/skills/wix-app/references/SERVICE_PLUGIN.md +35 -188
- package/skills/wix-app/references/SITE_PLUGIN.md +8 -92
- package/skills/wix-app/references/STORES_VERSIONING.md +1 -0
- package/skills/wix-app/references/backend-event/COMMON-EVENTS.md +0 -44
- package/skills/wix-app/references/custom-element-widget/SETTINGS_PANEL.md +19 -330
- package/skills/wix-app/references/dashboard-menu-plugin/bookings-slots.md +0 -12
- package/skills/wix-app/references/dashboard-menu-plugin/ecommerce-slots.md +7 -0
- package/skills/wix-app/references/dashboard-menu-plugin/restaurants-slots.md +0 -12
- package/skills/wix-app/references/dashboard-plugin/SLOTS.md +3 -15
- package/skills/wix-app/references/service-plugin/ADDITIONAL-FEES.md +2 -18
- package/skills/wix-app/references/service-plugin/BOOKINGS-STAFF-SORTING.md +2 -42
- package/skills/wix-app/references/service-plugin/DISCOUNT-TRIGGERS.md +1 -11
- package/skills/wix-app/references/service-plugin/GIFT-CARDS.md +1 -11
- package/skills/wix-app/references/service-plugin/PAYMENT-SETTINGS.md +2 -40
- package/skills/wix-app/references/service-plugin/SHIPPING-RATES.md +2 -19
- package/skills/wix-app/references/service-plugin/VALIDATIONS.md +2 -18
- package/skills/wix-app/references/site-plugin/SLOTS.md +17 -68
- package/skills/wix-design-system/SKILL.md +4 -0
- package/skills/wix-headless/SKILL.md +131 -386
- package/skills/wix-headless/references/BUILD-astro.md +246 -0
- package/skills/wix-headless/references/BUILD-own-build.md +167 -0
- package/skills/wix-headless/references/BUILD.md +105 -0
- package/skills/wix-headless/references/DESIGN_SYSTEM.md +175 -0
- package/skills/wix-headless/references/DISCOVERY-connect.md +55 -0
- package/skills/wix-headless/references/DISCOVERY-create.md +238 -0
- package/skills/wix-headless/references/DISCOVERY.md +50 -306
- package/skills/wix-headless/references/PLAN-connect.md +19 -0
- package/skills/wix-headless/references/PLAN-create.md +17 -0
- package/skills/wix-headless/references/PLAN.md +92 -0
- package/skills/wix-headless/references/SEED.md +214 -0
- package/skills/wix-headless/references/SETUP.md +73 -248
- package/skills/wix-headless/references/{blog → astro/blog}/BLOG_PAGES.md +6 -5
- package/skills/wix-headless/references/{blog → astro/blog}/BLOG_SETUP.md +2 -2
- package/skills/wix-headless/references/astro/bookings/COMPONENTS.md +337 -0
- package/skills/wix-headless/references/astro/bookings/SERVICES_PAGES.md +428 -0
- package/skills/wix-headless/references/astro/cms/CMS_FOUNDATIONS.md +214 -0
- package/skills/wix-headless/references/{cms → astro/cms}/FAQ_KNOWLEDGE_BASE.md +14 -12
- package/skills/wix-headless/references/{cms → astro/cms}/PORTFOLIO.md +15 -16
- package/skills/wix-headless/references/{cms → astro/cms}/RESOURCE_LIBRARY.md +13 -15
- package/skills/wix-headless/references/{cms → astro/cms}/TEAM_DIRECTORY.md +11 -11
- package/skills/wix-headless/references/astro/designer/INSTRUCTIONS.md +354 -0
- package/skills/wix-headless/references/{ecom → astro/ecom}/CART_PAGES.md +8 -9
- package/skills/wix-headless/references/{ecom → astro/ecom}/CART_WIRING.md +6 -6
- package/skills/wix-headless/references/{ecom → astro/ecom}/COMPONENTS_CSS.md +6 -6
- package/skills/wix-headless/references/{forms → astro/forms}/CONTACT_FORM.md +18 -32
- package/skills/wix-headless/references/{gift-cards → astro/gift-cards}/COMPONENTS.md +3 -3
- package/skills/wix-headless/references/{gift-cards → astro/gift-cards}/PAGES.md +2 -2
- package/skills/wix-headless/references/{stores → astro/stores}/BACK_IN_STOCK.md +7 -7
- package/skills/wix-headless/references/{stores → astro/stores}/CATEGORY_PAGES.md +12 -13
- package/skills/wix-headless/references/{stores → astro/stores}/COMPONENTS_CSS.md +7 -7
- package/skills/wix-headless/references/{stores → astro/stores}/HOME_AND_NAV.md +11 -9
- package/skills/wix-headless/references/{stores → astro/stores}/PRODUCT_PAGES.md +11 -9
- package/skills/wix-headless/references/{stores → astro/stores}/SHARED_WIRING.md +8 -7
- package/skills/wix-headless/references/astro/templates/Footer.astro +27 -0
- package/skills/wix-headless/references/astro/templates/Layout.astro +132 -0
- package/skills/wix-headless/references/astro/templates/Navigation.astro +38 -0
- package/skills/wix-headless/references/astro/templates/astro.config.mjs +41 -0
- package/skills/wix-headless/references/astro/templates/bookings/AvailabilityCalendar.tsx +218 -0
- package/skills/wix-headless/references/astro/templates/bookings/BookingForm.tsx +194 -0
- package/skills/wix-headless/references/astro/templates/bookings/ManageBooking.tsx +84 -0
- package/skills/wix-headless/references/astro/templates/bookings/SeoTags.astro +25 -0
- package/skills/wix-headless/references/astro/templates/bookings/ServiceBookingFlow.tsx +50 -0
- package/skills/wix-headless/references/astro/templates/bookings/ServiceCard.astro +45 -0
- package/skills/wix-headless/references/astro/templates/bookings/api/confirm-booking.ts +34 -0
- package/skills/wix-headless/references/astro/templates/bookings/api/waitlist.ts +74 -0
- package/skills/wix-headless/references/astro/templates/bookings/booking-confirmation.astro +111 -0
- package/skills/wix-headless/references/astro/templates/bookings/components-bookings.css +413 -0
- package/skills/wix-headless/references/astro/templates/bookings/manage-booking.astro +76 -0
- package/skills/wix-headless/references/astro/templates/bookings/services/[slug].astro +81 -0
- package/skills/wix-headless/references/astro/templates/bookings/services/index.astro +65 -0
- package/skills/wix-headless/references/astro/templates/ecom/components-ecom.css +302 -0
- package/skills/wix-headless/references/astro/templates/global.css +286 -0
- package/skills/wix-headless/references/astro/templates/index.astro +56 -0
- package/skills/wix-headless/{templates → references/astro/templates}/stores/back-in-stock.ts +1 -1
- package/skills/wix-headless/{templates → references/astro/templates}/stores/components-stores.css +138 -33
- package/skills/wix-headless/references/blog/BLOG_CONTENT.md +28 -19
- package/skills/wix-headless/references/blog/INSTRUCTIONS.md +6 -6
- package/skills/wix-headless/references/bookings/INSTRUCTIONS.md +106 -0
- package/skills/wix-headless/references/bookings/SERVICES_DATA.md +295 -0
- package/skills/wix-headless/references/cms/CMS_FOUNDATIONS.md +35 -232
- package/skills/wix-headless/references/cms/INSTRUCTIONS.md +39 -8
- package/skills/wix-headless/references/commands/known-apps.json +2 -1
- package/skills/wix-headless/references/custom/CONNECTION_PLAN.md +142 -0
- package/skills/wix-headless/references/custom/INSTRUCTIONS.md +88 -0
- package/skills/wix-headless/references/custom/blog/WIRING.md +52 -0
- package/skills/wix-headless/references/custom/bookings/WIRING.md +88 -0
- package/skills/wix-headless/references/custom/cms/WIRING.md +97 -0
- package/skills/wix-headless/references/custom/ecom/WIRING.md +67 -0
- package/skills/wix-headless/references/custom/forms/WIRING.md +101 -0
- package/skills/wix-headless/references/custom/stores/WIRING.md +80 -0
- package/skills/wix-headless/references/ecom/INSTRUCTIONS.md +12 -12
- package/skills/wix-headless/references/forms/INSTRUCTIONS.md +6 -6
- package/skills/wix-headless/references/gift-cards/INSTRUCTIONS.md +13 -13
- package/skills/wix-headless/references/images/INSTRUCTIONS.md +58 -60
- package/skills/wix-headless/references/seed-recipes.md +49 -0
- package/skills/wix-headless/references/shared/AGENTS_MD.md +47 -0
- package/skills/wix-headless/references/shared/AUTHENTICATION.md +108 -0
- package/skills/wix-headless/references/shared/BUILD_NOISE.md +2 -2
- package/skills/wix-headless/references/shared/DESIGN_MD.md +85 -0
- package/skills/wix-headless/references/shared/DOCS_SEARCH.md +41 -0
- package/skills/wix-headless/references/shared/IMAGE_GENERATION.md +40 -39
- package/skills/wix-headless/references/shared/IMPLEMENTER.md +92 -41
- package/skills/wix-headless/references/shared/PRODUCTION_SHARP_EDGES.md +3 -3
- package/skills/wix-headless/references/shared/RETURN_CONTRACT.md +32 -312
- package/skills/wix-headless/references/shared/STYLING.md +48 -21
- package/skills/wix-headless/references/stores/INSTRUCTIONS.md +59 -29
- package/skills/wix-headless/references/stores/PRODUCT_CATALOG_DATA.md +31 -28
- package/skills/wix-headless/references/verticals/_schema.json +31 -117
- package/skills/wix-headless/references/verticals/_schema.md +60 -150
- package/skills/wix-headless/references/verticals/blog.md +5 -99
- package/skills/wix-headless/references/verticals/bookings.md +41 -0
- package/skills/wix-headless/references/verticals/cms.md +9 -100
- package/skills/wix-headless/references/verticals/ecom.md +6 -77
- package/skills/wix-headless/references/verticals/forms.md +5 -85
- package/skills/wix-headless/references/verticals/gift-cards.md +6 -103
- package/skills/wix-headless/references/verticals/stores.md +10 -144
- package/skills/wix-headless/scripts/check-manifest.mjs +148 -11
- package/skills/wix-headless/scripts/compose.mjs +540 -0
- package/skills/wix-headless/scripts/emit-design-tokens.mjs +136 -53
- package/skills/wix-headless/scripts/flatten.sh +61 -0
- package/skills/wix-headless/scripts/generate-images.mjs +242 -0
- package/skills/wix-headless/scripts/patch-decorative-slots.mjs +67 -43
- package/skills/wix-headless/scripts/plan-entity-image-waves.mjs +3 -3
- package/skills/wix-headless/scripts/scaffold.sh +113 -27
- package/skills/wix-headless/scripts/seed-utilities.sh +50 -12
- package/skills/wix-headless/scripts/write-decorative-json.mjs +62 -0
- package/skills/wix-manage/SKILL.md +4 -8
- package/skills/wix-manage/references/blog/how-to-create-blog-posts.md +2 -0
- package/skills/wix-manage/references/cms/cms-data-items-crud.md +4 -0
- package/skills/wix-manage/references/cms/cms-references-and-relationships.md +2 -0
- package/skills/wix-manage/references/cms/cms-schema-management.md +4 -0
- package/skills/wix-manage/references/domains/domain-search-and-purchase.md +10 -7
- package/skills/wix-manage/references/ecommerce/api-shipping.md +443 -0
- package/skills/wix-manage/references/ecommerce/flow-add-free-shipping.md +5 -6
- package/skills/wix-manage/references/ecommerce/flow-fix-coverage-gaps.md +4 -5
- package/skills/wix-manage/references/ecommerce/flow-optimize-shipping-rates.md +4 -5
- package/skills/wix-manage/references/ecommerce/goal-increase-aov.md +1 -1
- package/skills/wix-manage/references/ecommerce/goal-reduce-cart-abandonment.md +1 -2
- package/skills/wix-manage/references/ecommerce/guardrail-shipping-health.md +2 -2
- package/skills/wix-manage/references/ecommerce/recipe-apply-shipping-recommendations.md +4 -5
- package/skills/wix-manage/references/ecommerce/recommend-ecommerce-strategy.md +7 -7
- package/skills/wix-manage/references/ecommerce/setup-discount-rules.md +209 -72
- package/skills/wix-manage/references/ecommerce/setup-store-pickup-location.md +9 -10
- package/skills/wix-manage/references/ecommerce/skill-graph.md +4 -4
- package/skills/wix-manage/references/forms/create-form.md +50 -0
- package/skills/wix-manage/references/stores/bulk-create-products-with-options.md +2 -0
- package/skills/wix-manage/references/stores/create-product-from-image.md +91 -38
- package/skills/wix-manage/references/stores/setup-online-store-catalog-v3.md +2 -0
- package/skills/wix-app/references/custom-element-widget/default-thumbnail.png +0 -0
- package/skills/wix-app/references/data-collection/extension-template.ts +0 -107
- package/skills/wix-headless/references/ORCHESTRATION.md +0 -269
- package/skills/wix-headless/references/commands/install-app.md +0 -42
- package/skills/wix-headless/references/commands/mcp-bootstrap.md +0 -28
- package/skills/wix-headless/references/designer/INSTRUCTIONS.md +0 -828
- package/skills/wix-headless/references/shared/MCP_PREFIX.md +0 -105
- package/skills/wix-headless/scripts/copy-utility-templates.mjs +0 -153
- package/skills/wix-headless/scripts/finalize-run-json.mjs +0 -141
- package/skills/wix-headless/scripts/init-site-json.mjs +0 -63
- package/skills/wix-headless/scripts/preview.sh +0 -45
- package/skills/wix-headless/scripts/release.sh +0 -73
- package/skills/wix-headless/templates/ecom/components-ecom.css +0 -215
- package/skills/wix-manage/references/events/list-events.md +0 -203
- /package/skills/wix-headless/{templates → references/astro/templates}/ecom/CartBadge.tsx +0 -0
- /package/skills/wix-headless/{templates → references/astro/templates}/ecom/CartView.tsx +0 -0
- /package/skills/wix-headless/{templates → references/astro/templates}/ecom/cart.astro +0 -0
- /package/skills/wix-headless/{templates → references/astro/templates}/ecom/discounts.ts +0 -0
- /package/skills/wix-headless/{templates → references/astro/templates}/ecom/thank-you.astro +0 -0
- /package/skills/wix-headless/{templates → references/astro/templates}/gift-cards/GiftCardPurchase.tsx +0 -0
- /package/skills/wix-headless/{templates → references/astro/templates}/gift-cards/_home-teaser-snippet.astro +0 -0
- /package/skills/wix-headless/{templates → references/astro/templates}/gift-cards/_nav-snippet.astro +0 -0
- /package/skills/wix-headless/{templates → references/astro/templates}/gift-cards/components-gift-cards.css +0 -0
- /package/skills/wix-headless/{templates → references/astro/templates}/gift-cards/gift-cards.astro +0 -0
- /package/skills/wix-headless/{templates → references/astro/templates}/gift-cards/gift-cards.ts +0 -0
- /package/skills/wix-headless/{templates → references/astro/templates}/stores/AddToCartButton.tsx +0 -0
- /package/skills/wix-headless/{templates → references/astro/templates}/stores/BackInStockForm.tsx +0 -0
- /package/skills/wix-headless/{templates → references/astro/templates}/stores/CategoryRail.astro +0 -0
- /package/skills/wix-headless/{templates → references/astro/templates}/stores/ProductCard.astro +0 -0
- /package/skills/wix-headless/{templates → references/astro/templates}/stores/ProductPurchase.tsx +0 -0
- /package/skills/wix-headless/{templates → references/astro/templates}/stores/SeoTags.astro +0 -0
- /package/skills/wix-headless/{templates → references/astro/templates}/stores/categories.ts +0 -0
- /package/skills/wix-headless/{templates → references/astro/templates}/stores/category/[slug].astro +0 -0
- /package/skills/wix-headless/{templates → references/astro/templates}/stores/products/[slug].astro +0 -0
- /package/skills/wix-headless/{templates → references/astro/templates}/stores/products/index.astro +0 -0
|
@@ -1,225 +1,25 @@
|
|
|
1
|
-
# CMS Foundations —
|
|
1
|
+
# CMS Foundations — Seeding via `@wix/data` REST (business track)
|
|
2
2
|
|
|
3
|
-
|
|
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
|
-
> **
|
|
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
|
-
##
|
|
7
|
+
## Collection ID Format (seeding-relevant)
|
|
8
8
|
|
|
9
|
-
|
|
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
|
-
|
|
11
|
+
## Seeding via REST (Conditional)
|
|
12
12
|
|
|
13
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
###
|
|
92
|
+
### Seeding with Images
|
|
291
93
|
|
|
292
94
|
For use cases with image fields (`photo`, `coverImage`, `galleryImages`),
|
|
293
|
-
follow
|
|
294
|
-
generation and Wix Media import. Image generation
|
|
295
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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,
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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,
|
|
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
|
|
15
|
-
| `pages` | Pages (About + FAQ pages read CMS via @wix/data inline) |
|
|
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
|
-
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
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.
|