From 9ae63893891f3ee2c2496b4a33e75dbe0aae7743 Mon Sep 17 00:00:00 2001 From: Oz Sayag Date: Mon, 8 Jun 2026 12:19:45 +0300 Subject: [PATCH 1/4] =?UTF-8?q?feat(sp-wix):=20Wix=20=C3=97=20Stripe=20Pro?= =?UTF-8?q?jects=20business-integration=20skill?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Standalone skill that connects Wix business services (Stores, Blog, CMS, Forms) to a Stripe Projects app after `stripe projects add wix/*` has provisioned a metasite + synced credentials to .env. The skill owns only the Wix backend work; the host keeps the frontend, build, and hosting. Flow: Discovery (infer capabilities/brand/intent) -> Setup (install apps) -> Seed (create content) -> Handoff (SDK integration guide) -> Register origin (post-deploy OAuth-app allowed-domain update, the step init normally does for hosted sites). - Standalone: only upstream is wix-manage (recipes loaded via Skill) - Pure curl against wixapis.com; token minted from .env client-credentials (no @wix/cli, no wix login, no wix.config.json) - Handoff links to live Wix SDK docs rather than inlining snippets - Descriptive, not restrictive: imperative on its own actions, imposes nothing on the host flow Co-Authored-By: Claude Opus 4.8 (1M context) --- skills/sp-wix/SKILL.md | 60 +++++++++++++++++++++ skills/sp-wix/references/AUTHENTICATION.md | 52 ++++++++++++++++++ skills/sp-wix/references/CAPABILITIES.md | 33 ++++++++++++ skills/sp-wix/references/DISCOVERY.md | 37 +++++++++++++ skills/sp-wix/references/REGISTER_ORIGIN.md | 50 +++++++++++++++++ skills/sp-wix/references/SDK_HANDOFF.md | 59 ++++++++++++++++++++ skills/sp-wix/references/SEED.md | 33 ++++++++++++ skills/sp-wix/references/SETUP.md | 51 ++++++++++++++++++ 8 files changed, 375 insertions(+) create mode 100644 skills/sp-wix/SKILL.md create mode 100644 skills/sp-wix/references/AUTHENTICATION.md create mode 100644 skills/sp-wix/references/CAPABILITIES.md create mode 100644 skills/sp-wix/references/DISCOVERY.md create mode 100644 skills/sp-wix/references/REGISTER_ORIGIN.md create mode 100644 skills/sp-wix/references/SDK_HANDOFF.md create mode 100644 skills/sp-wix/references/SEED.md create mode 100644 skills/sp-wix/references/SETUP.md diff --git a/skills/sp-wix/SKILL.md b/skills/sp-wix/SKILL.md new file mode 100644 index 00000000..a534d15b --- /dev/null +++ b/skills/sp-wix/SKILL.md @@ -0,0 +1,60 @@ +--- +name: sp-wix +description: "Connect Wix business services (Stores, Blog, CMS, Forms) to a Stripe Projects app. Use AFTER `stripe projects add wix/*` has provisioned a Wix metasite + synced its credentials to `.env`. Given the metasite and the user's intent, this skill runs the Wix business flow — infers which Wix capabilities the app needs, installs the apps, seeds backend content — then returns an SDK-integration guide (how to call Wix from the frontend) for the host agent to use. The host keeps ownership of the frontend, the build, and the hosting. Triggers: set up Wix in this Stripe project, add a Wix store/blog/CMS/forms backend, connect Wix Headless to my Stripe app, provision Wix content for this project, I added wix with stripe projects now wire it up. NOT for: building a new Wix-hosted site from scratch (use wix-headless), or anything outside a Stripe Projects app." +allowed-tools: + - Bash(curl *) + - Bash(ls *) + - Bash(cat *) + - Bash(grep *) + - Bash(head *) + - Bash(test *) + - Read + - Write + - Skill +--- + +# Wix Headless × Stripe Projects + +This skill connects **Wix business services** to an app managed by [Stripe Projects](https://docs.stripe.com/projects). The host agent (Claude Code / Cursor / an MCP agent, driven by Stripe's flow) owns the conversation, the frontend, the build, and the hosting. + +**This skill's job is to configure the Wix backend**: infer the needed capabilities, **install the Wix apps**, **seed the backend content**, return an integration guide describing how to call Wix from the frontend, and — once the site is deployed — **register the deployed origin on the OAuth app** so the frontend is actually allowed to call Wix. The configured backend is the work; the guide just describes it. A run is complete only when **Setup and Seed have run**, the guide has been emitted, and the deployed origin has been registered (or, if deployment is out of this flow, the user has been told it's required). + +## Preconditions (the host provides these — we read, never create) + +1. **A Stripe Project with Wix connected** — `stripe projects add wix/*` has run, provisioning a metasite + a headless OAuth app and syncing credentials to `.env`: `WIX_WIX_CLIENT_ID`, `WIX_WIX_CLIENT_SECRET`, `WIX_WIX_METASITE_ID` (see `references/AUTHENTICATION.md`). +2. **The user intent** — free text describing what Wix should power ("add a store", "blog + contact form", "persist my app's data"). +3. *(Optional)* the project on disk — read-only, to sharpen brand/capability inference. + +If the Wix credentials are absent, Wix isn't connected in this project — **stop with a clear error**. + +## What this skill does + +When invoked, **run these four steps in order, start to finish.** Steps 1–3 are the skill's actual work — they execute against the metasite over `curl`; step 4 reports the result. Open `DISCOVERY.md` and begin. + +1. **Discovery** (`references/DISCOVERY.md`) — infer the capability set + brand + per-capability intent from the user's words, then drive straight into Setup. +2. **Setup** (`references/SETUP.md`) — **install** the Wix apps those capabilities need on the metasite. +3. **Seed** (`references/SEED.md`) — **create** the backend content for each capability (products, posts, collections + items, forms). +4. **Handoff** (`references/SDK_HANDOFF.md`) — **only after Setup and Seed have run**, return the integration guide: the SDK bootstrap, per-capability call shapes, the **seeded IDs** (which exist only because Seed ran), and the `@wix/*` package list. +5. **Register origin** (`references/REGISTER_ORIGIN.md`) — **after the site is deployed**, register its URL on the OAuth app (the admin call `init` normally does for hosted sites). Do it **once per URL** (skip if already registered). If deployment isn't part of this flow, **flag to the user** that this step is required before the frontend can call Wix. + +Steps 1–4 run in one pass; step 5 happens once the deployed URL exists (the skill performs it if it sees the deploy, otherwise flags the user). The guide in step 4 describes the backend that Setup and Seed built. Each Wix call uses a token minted from `.env` (`references/AUTHENTICATION.md`). The skill runs non-interactively, inferring from the user's words rather than asking. + +## Path resolution + +Compute `` from this file (`/SKILL.md` — strip `/SKILL.md`); hold the absolute path in scratch. + +| What | Path | +|---|---| +| Authentication (token mint + REST contract + ladder) | `/references/AUTHENTICATION.md` | +| Capability map (intent → apps + seed-what + SDK packages) | `/references/CAPABILITIES.md` | +| Discovery (infer capabilities + brand + intent) | `/references/DISCOVERY.md` | +| Setup (install apps) | `/references/SETUP.md` | +| Seed (create backend content) | `/references/SEED.md` | +| SDK-integration handoff (the returned document) | `/references/SDK_HANDOFF.md` | +| Register the deployed origin on the OAuth app (post-deploy) | `/references/REGISTER_ORIGIN.md` | + +**Start a run by opening `DISCOVERY.md`.** + +## Upstream + +The **only** upstream dependency is **`wix-manage`** — the recipe library for app installation and content seeding, loaded via `Skill(name="wix-manage")` (Setup does this once; Seed reuses the in-context recipes). API request shapes (endpoints, payloads, field templates) live there and are the single source of truth; this skill carries the *what* (which capabilities, how much content) and searches `wix-manage` for the *how*. diff --git a/skills/sp-wix/references/AUTHENTICATION.md b/skills/sp-wix/references/AUTHENTICATION.md new file mode 100644 index 00000000..f29420e7 --- /dev/null +++ b/skills/sp-wix/references/AUTHENTICATION.md @@ -0,0 +1,52 @@ +# Authentication (Stripe-Projects → Wix) + +Every Wix call this skill makes is a plain `curl` against `wixapis.com` with a bearer token. The credentials come from the project's `.env` (synced by Stripe Projects when Wix was connected), and the token is minted directly from the OAuth client-credentials grant. + +## Inputs from `.env` + +Stripe Projects namespaces each provider's vars, and Wix's own names already begin with `WIX_`, so a real provision yields a **doubled prefix**: + +| Var | Role | +| ----------------------- | ------------------------------------------------------------------------------------------------- | +| `WIX_WIX_CLIENT_ID` | the OAuth app `client_id` — also the frontend `OAuthStrategy({ clientId })` | +| `WIX_WIX_CLIENT_SECRET` | the OAuth app `client_secret` — **server-side only**; mints the token, never goes to the frontend | +| `WIX_WIX_METASITE_ID` | the metasite id → the `wix-site-id` header on every site-scoped call | + +The plain `WIX_*` names are accepted as a fallback (in case the provider definition changes). Read them at runtime. If `client_id`/`client_secret` are absent, Wix isn't connected in this project — **stop with a clear error**. + +## Minting the token — inline, secret stays out of context + +Run this as a **single Bash call**. It sources `.env` *inside the shell*, so the command text references `$WIX_WIX_CLIENT_SECRET` but the secret value is never typed, printed, or returned. The minted token is written to a tmp file so later calls reuse it **without re-minting and without the token entering the model context**: + +```bash +set -a; . ./.env; set +a +curl -sS -X POST "https://www.wixapis.com/oauth2/token" \ + -H "Content-Type: application/json" \ + -d "{\"grant_type\":\"client_credentials\",\"client_id\":\"${WIX_WIX_CLIENT_ID:-$WIX_CLIENT_ID}\",\"client_secret\":\"${WIX_WIX_CLIENT_SECRET:-$WIX_CLIENT_SECRET}\"}" \ + | python3 -c "import sys,json;print(json.load(sys.stdin)['access_token'])" > /tmp/wix_token \ + && test -s /tmp/wix_token && echo "token minted" || echo "MINT FAILED — Wix not connected, or app/creds invalid" +``` + +That endpoint returns `{ "access_token": "<…>", "token_type": "Bearer", "expires_in": 14400 }`. `instance_id` is **optional and omitted**. The token is a real OAuth token with a **4-hour expiry**. + +> **Shell state does not persist between Bash calls** — that is *why* the token goes to `/tmp/wix_token`. Mint once at the start of the run; every later call reads it back. Do **not** import the CLI "byte-identical, never re-mint" lore — each mint here returns a *different, equally valid* token; "mint once" is for simplicity, not because re-minting is pointless. + +## REST call shape + +Every later call re-sources `.env` (for the non-secret metasite id) and reads the token from the tmp file — both cheap, both keep secrets out of context: + +```bash +set -a; . ./.env; set +a +TOKEN=$(cat /tmp/wix_token) +SITE_ID="${WIX_WIX_METASITE_ID:-$WIX_METASITE_ID}" +curl -sS -w "\nHTTP_STATUS:%{http_code}" \ + -X POST "https://www.wixapis.com/" \ + -H "Authorization: Bearer $TOKEN" \ + -H "wix-site-id: $SITE_ID" \ + -H "Content-Type: application/json" \ + -d '' +``` + +- **`Authorization: Bearer $TOKEN`** — the `Bearer` prefix is required. +- **`wix-site-id: $SITE_ID`** — required by every site-scoped family (Stores v3, CMS v2, Blog v3, Forms v4, Apps-Installer v1, …). Harmless where unread; include it always. +- **`Content-Type: application/json`** — on every POST/PATCH body. diff --git a/skills/sp-wix/references/CAPABILITIES.md b/skills/sp-wix/references/CAPABILITIES.md new file mode 100644 index 00000000..37149e53 --- /dev/null +++ b/skills/sp-wix/references/CAPABILITIES.md @@ -0,0 +1,33 @@ +# Capability map + +The skill's own **what** table — the single source the other steps key off. Each capability names: the **app to install** (Setup), the **content to seed** + the wix-manage **capability phrase** to search (Seed), and the **SDK package(s) + docs link** to hand off (Handoff). It deliberately carries **no API request shapes or call snippets** — request shapes are wix-manage's job (found by the capability phrase); frontend call shapes are the live SDK docs' job (the Handoff links to them, never reproduces them). This is the *what*; wix-manage and the SDK docs are the *how*. + +| Capability | Install (appDefId) | Seed — *what* | wix-manage capability phrase | SDK package(s) | SDK docs (for the Handoff) | +|---|---|---|---|---|---| +| **stores** | Wix Stores `215238eb-22a5-4c36-9e7b-e7c08025e04e` | `intent.stores.productCount` products fitting `brand`; the named categories in `intent.stores.categoriesNamed` (none if empty) | *"set up an online store catalog and bulk-create products"* | `@wix/stores` (+ `@wix/ecom @wix/redirects` for cart/checkout) | dev.wix.com/docs/sdk/business-solutions/stores.md (cart: …/ecom.md) | +| **blog** | Wix Blog `14bcded7-0066-7c35-14d7-466cb3f09103` | `intent.blog.postCount` posts on `intent.blog.topics` (else brand-derived) | *"create blog posts (bulk)"* | `@wix/blog` (+ `@wix/ricos` for rich content) | dev.wix.com/docs/sdk/business-solutions/blog.md | +| **forms** | Wix Forms `225dd912-7dea-4738-8688-4b8c6955ffc2` | one form per `intent.forms.forms` entry; fields from each entry | *"create a Wix form"* | `@wix/forms` | dev.wix.com/docs/sdk/business-solutions.md (locate forms/submissions) | +| **cms** | **none** — Wix Data is core (no install) | one collection per `intent.cms.collections` entry + `itemCount` items, content from `brand`; **public-read** | *"create a CMS collection schema"* + *"insert CMS collection items"* | `@wix/data` | dev.wix.com/docs/sdk/business-solutions/data.md | + +Always-on package (every capability): **`@wix/sdk`** (provides `createClient` + `OAuthStrategy`). + +## Notes that are genuinely the skill's *what* (not recipe *how*, not SDK-usage) + +- **stores** — products are **text-only** (no imagery sourced); use the recipe's documented no-image/placeholder path. Categories: create exactly `intent.stores.categoriesNamed`; **if empty, create none** (overrides any recipe default). +- **blog** — text-only (no cover imagery). Bulk-create when `postCount ≥ 2`. +- **cms** — collections are **public-read** (a visitor token has no per-user identity; data is shared/public — surface this to the host in the handoff). Frontend reads are visitor-safe; visitor writes go through Forms. +- **forms** — `purpose` ("contact"/"lead"/"signup") drives the form name; the Wix Forms app is installed in Setup, so the seed step does not reinstall. + +## Intent → capability resolution (used by DISCOVERY) + +Map the user's words to the set above. The floor is **forms** (a contact/lead form) when nothing richer fits: + +| Signal in intent | Capabilities | +|---|---| +| sell / shop / products / catalog / store | `stores` (+ cart via ecom packages) | +| blog / posts / articles / publication / news | `blog` | +| collection / directory / portfolio / structured content / "persist my app's data" | `cms` | +| contact / RSVP / lead / signup / waitlist / "let people reach me" | `forms` | +| nothing dynamic named | `forms` (contact-form floor) | + +Multiple signals → multiple capabilities. On ambiguity pick the first row that matches, top-to-bottom. diff --git a/skills/sp-wix/references/DISCOVERY.md b/skills/sp-wix/references/DISCOVERY.md new file mode 100644 index 00000000..4032f3ab --- /dev/null +++ b/skills/sp-wix/references/DISCOVERY.md @@ -0,0 +1,37 @@ +# Discovery — infer, don't interview + +The run starts here. **Infer** the Wix capability set, the brand, and per-capability intent from the user's words (and, optionally, the project on disk). Inference is just the first step — its output **drives Setup (install apps) and Seed (create content)**, which are the actual work; flow straight through into them. The host already has the user's buy-in to add Wix, so resolve everything from what's given and keep moving; when something isn't specified, use the defaults below. + +## 0 · Pre-flight + +Confirm the project has Wix connected: the `.env` carries `WIX_WIX_CLIENT_ID` / `WIX_WIX_CLIENT_SECRET` / `WIX_WIX_METASITE_ID` (or the plain `WIX_*` fallback). The cleanest check is to mint the token (`references/AUTHENTICATION.md` § "Minting the token"): + +- **Mint succeeds** → continue. +- **Mint fails / creds absent** → Wix isn't connected in this project. **Stop with a clear error** ("Wix is not connected to this Stripe project — run `stripe projects add wix/*` first"). + +Hold `WIX_WIX_METASITE_ID` as `SITE_ID` in scratch. + +## 1 · Resolve the capability set + +Map the **user intent** (+ optional project signals: `package.json` name, README, visible copy) to `verticals[]` using `references/CAPABILITIES.md` § "Intent → capability resolution". Multiple signals → multiple capabilities. On ambiguity, pick the first matching row top-to-bottom; if nothing dynamic is named, fall to the **forms** floor (a contact form). Never return an empty set. + +## 2 · Infer brand + +A short brand object for seeded-content naming: `{ name, description, vibe? }`. Source from the intent text and any project signals (the package name, a README title/tagline, headline copy). If nothing is available, derive a neutral name from the project directory. This is only used to make seeded content read naturally — keep it light. + +## 3 · Derive per-capability intent + +For each capability, build its `intent.` block — the inputs the seed step translates into recipe calls. Use sensible brand-appropriate defaults when the user didn't specify counts: + +| Capability | `intent.` shape | Defaults when unspecified | +|---|---|---| +| stores | `{ productCount, categoriesNamed: [] }` | `productCount: 3`, `categoriesNamed: []` (no categories) | +| blog | `{ postCount, topics: [] }` | `postCount: 3`, topics derived from `brand.description` | +| cms | `{ collections: [{ name, purpose, itemCount, fields? }] }` | one collection inferred from intent, `itemCount: 5` | +| forms | `{ forms: [{ purpose, fields: [...] }] }` | one `contact` form: name, email, message | + +Counts are deliberately small (text-only seed; the host's app shows the shape, not a full catalog). Don't invent imagery — seed is text-only. + +## 4 · Hold the contract, proceed + +Hold in scratch: `SITE_ID`, `verticals[]`, `brand`, `intent.` per capability. Nothing is written to disk (there is no `wix.config.json` here). Then **continue to `SETUP.md`** and install the apps — this is the start of the actual work, not a separate decision. A brief plain-prose line stating what will be set up is fine. diff --git a/skills/sp-wix/references/REGISTER_ORIGIN.md b/skills/sp-wix/references/REGISTER_ORIGIN.md new file mode 100644 index 00000000..7bde30ad --- /dev/null +++ b/skills/sp-wix/references/REGISTER_ORIGIN.md @@ -0,0 +1,50 @@ +# Register the deployed origin on the OAuth app + +For the frontend's visitor calls (`OAuthStrategy` with the public `clientId`) to be **accepted from the deployed site**, the site's origin must be on the OAuth app's allowed domains. Otherwise every browser SDK call from the live URL is rejected. + +In regular `wix-headless` this is done by `init` — it knows the hosting URL up front and registers `localhost` + preview + prod domains on the OAuth app. **Here we don't own the hosting, so the deployed URL is unknown until the site is deployed.** That makes this a **post-deploy step the skill performs once the URL is known** — it can't be done during Setup/Seed. + +## When to run + +After the site is deployed and its URL is known. The OAuth app's id **is the clientId** — `WIX_WIX_CLIENT_ID`. Use the admin token from `.env` (`references/AUTHENTICATION.md`). + +## Idempotent — register a given URL only once + +First **read** the app's current allowed domains; if the deployed origin is already present, the registration is already done — **skip it**. Only ever add a URL that isn't there yet. + +```bash +set -a; . ./.env; set +a +TOKEN=$(cat /tmp/wix_token); ID="${WIX_WIX_CLIENT_ID:-$WIX_CLIENT_ID}" +curl -sS -w "\nHTTP_STATUS:%{http_code}" \ + "https://www.wixapis.com/oauth-app/v1/oauth-apps/$ID" \ + -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" +# → read oAuthApp.allowedRedirectDomains; if the deployed origin is already in it, you're done. +``` + +## Add the deployed origin + +`PATCH` the app, sending the **existing** `allowedRedirectDomains` **plus** the new origin (the API replaces the field, so include what's already there), with a field mask: + +```bash +set -a; . ./.env; set +a +TOKEN=$(cat /tmp/wix_token); ID="${WIX_WIX_CLIENT_ID:-$WIX_CLIENT_ID}" +curl -sS -w "\nHTTP_STATUS:%{http_code}" -X PATCH \ + "https://www.wixapis.com/oauth-app/v1/oauth-apps/$ID" \ + -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ + -d '{ + "oAuthApp": { "id": "'"$ID"'", "allowedRedirectDomains": [ , "" ] }, + "mask": { "paths": ["allowedRedirectDomains"] } + }' +``` + +- `` is the live site's domain/URL (what the browser SDK runs on). +- For the **exact field semantics and format** (domain vs. full URL, member-login redirect URIs vs. allowed domains), read the doc — don't guess: . Member-login redirect URIs are a separate, deferred concern; the visitor SDK only needs the origin allowed. +- This call needs OAuth-app management permission on the app (same provider-side scope story as Setup/Seed); a non-200 here surfaces and stops, like any other Wix call. + +## If deployment is NOT part of this agent flow + +If the agent isn't the one deploying — the user will deploy the site themselves — the skill **cannot know the deployed URL**, so it cannot register the origin. **Flag this to the user clearly**, e.g.: + +> *"One required step remains before the frontend can talk to Wix: once your site is live, its URL must be registered on the Wix OAuth app (allowed domains). Give me the deployed URL — or re-run this skill with it — and I'll register it. Until then, Wix SDK calls from the live site will be rejected."* + +This is the one piece `init` normally handles for hosted sites; because hosting is the host's, it has to be closed out here. diff --git a/skills/sp-wix/references/SDK_HANDOFF.md b/skills/sp-wix/references/SDK_HANDOFF.md new file mode 100644 index 00000000..e300bff5 --- /dev/null +++ b/skills/sp-wix/references/SDK_HANDOFF.md @@ -0,0 +1,59 @@ +# SDK-integration handoff + +**This is the last step — reach it only after Setup and Seed have run.** The guide below is filled from the `seeded` map (created IDs), which exists only because Seed executed; if you're here without having installed the apps and seeded content, go back and do that first. The guide *describes* the backend the earlier steps built. + +The skill **returns this document** describing how to call Wix from the frontend, then **exits**. The host agent — which owns the frontend, the framework, and the build — does the wiring. We describe what to use and **link to the live Wix SDK docs for the API shapes**; the host decides where they go. + +> **Link to the docs; do not inline API examples.** The Wix SDK docs are versioned and complete; hand-written snippets under-specify the hard parts (rich-content rendering, package versions, types) and lead the host to build against a wrong or stale shape. The handoff's job is to point at the *right* doc page and supply the three things the docs can't know: the **seeded IDs**, the **`clientId` source**, and the **package set**. Let the host read the current API from the docs. +> +> **The linked docs are the source of truth for current API shapes and versions — read them for the integration. Existing code (in this or any other project) is not a substitute: it may target a different SDK version and silently mislead.** + +Emit the document as the skill's final message (a Markdown block the host can act on or save). Fill it from the run's `verticals[]`, the `seeded` map, and `WIX_WIX_CLIENT_ID`. Include **only** the loaded capabilities. + +## What the document contains + +### 1 · Packages to install +The union of the loaded capabilities' SDK packages (`references/CAPABILITIES.md`) plus the always-on `@wix/sdk` — **runtime packages only** (no scaffold/build deps). For install details and current versions, link: . + +### 2 · Client setup (and the clientId source) +The frontend authenticates as an **anonymous visitor** via `OAuthStrategy`, with `clientId` = the **`WIX_WIX_CLIENT_ID`** value. The `clientId` is **not secret** (it's the public OAuth id) — the host exposes it to client code via its framework's public-env convention (`NEXT_PUBLIC_*`, `VITE_*`, `PUBLIC_*`, …). The **`client_secret` never reaches the frontend.** For the current `createClient` + auth-strategy shape, link: +- +- + +### 3 · Per-capability API docs (link, don't snippet) +For each loaded capability, give the package and its SDK doc page: + +| Capability | Package(s) | SDK docs | +|---|---|---| +| stores | `@wix/stores` (+ `@wix/ecom`, `@wix/redirects` for cart/checkout) | · cart: | +| blog | `@wix/blog` (+ `@wix/ricos` to render rich post content) | — for rendering `richContent`, follow the blog docs to the current `@wix/ricos` viewer API + version (don't pin blind) | +| cms | `@wix/data` | | +| forms | `@wix/forms` | not a standalone business-solutions page — find the forms/submissions module from the menu () or via `SearchWixSDKDocumentation` | + +### 4 · Seeded IDs (what the host binds to) +From the `seeded` map — the IDs only this run knows: +- **stores:** `productIds`, product `slug`s, `categoryIds` +- **blog:** `postIds`, post `slug`s +- **cms:** `collectionId` + field keys per collection +- **forms:** `formId` + each form's field **`target`** keys (frontend input `name` = `target`) + +### 5 · Integration notes (headless-auth specifics the per-module docs won't frame) +- The visitor token has **no per-user identity** → seeded **CMS collections are public/shared** across all visitors (not per-user, not cross-device). Per-user storage needs member auth. +- Frontend CMS access is **read**; visitor writes go through **Forms** submissions. + +## How to navigate the Wix docs + +> - Append `.md` to any URL under `https://dev.wix.com/docs/` to get its markdown version. +> - Pages are either content pages (article/reference text) or menu pages (a list of links to child pages). +> - To get a menu page, truncate any URL to a parent path and append `.md` (e.g. `https://dev.wix.com/docs/sdk.md`, `https://dev.wix.com/docs/sdk/business-solutions.md`). +> - Top-level index of all portals: +> - Full concatenated docs: +> - Or use the `SearchWixSDKDocumentation` tool for a targeted lookup. + +## One required step remains: register the deployed origin + +The guide describes the backend, but the frontend's visitor calls will be **rejected from the live site until its origin is registered on the OAuth app** (the step `init` does for hosted sites; here the deployed URL is only known after deploy). So after deployment, register the origin per `references/REGISTER_ORIGIN.md` — once per URL. If deployment is out of this agent flow, tell the user plainly that this step is required before the frontend can call Wix (`REGISTER_ORIGIN.md` has the wording). + +## After emitting the document + +Once the guide is emitted and the deployed origin is registered (or the user has been flagged), the skill's work is done. Close with a short plain-prose summary of what was set up (apps installed, content seeded per capability, origin registered or pending). What happens with the guide — installing packages, wiring components, choosing a framework — is the host's to decide. diff --git a/skills/sp-wix/references/SEED.md b/skills/sp-wix/references/SEED.md new file mode 100644 index 00000000..ec73808b --- /dev/null +++ b/skills/sp-wix/references/SEED.md @@ -0,0 +1,33 @@ +# Seed — create the backend content + +For each capability, create the backend content its *what* names. This step carries **only the *what*** (entities, count source, policy); the **API *how*** is found by searching the in-context `wix-manage` recipes. **No endpoints, payloads, field templates, caps, or batching mechanics live in this file** — if you find yourself writing one, it belongs to a recipe. + +## How it runs + +`wix-manage` is already in context (loaded in Setup). The token is in `/tmp/wix_token`. The capabilities are **independent** — no ordering or data dependency between them. For each one: + +1. **Find the recipe** by its capability phrase (`references/CAPABILITIES.md` → "wix-manage capability phrase") against the in-context recipe index. **Fail loud** if no recipe matches a required capability — a missing recipe is a real error, not a cue to guess. +2. **Read the matched recipe** and build request bodies from `intent.` + `brand`. The recipe is the source of truth for URL/method/body. +3. **Execute** against `wixapis.com` with the call shape in `references/AUTHENTICATION.md` (Bearer from `/tmp/wix_token` + `wix-site-id`). +4. **Collect the created IDs** into a `seeded` map keyed by capability. + +> **Text-only seed.** Use each recipe's documented no-image/placeholder path; don't source imagery. The host's app demonstrates the data *shape*, not a full media catalog. + +## Per-capability *what* + +Each block states only the entities, where their count/content comes from, the policy that is genuinely the skill's call, and the IDs to keep. The capability phrase (CAPABILITIES.md) finds the recipe that supplies the rest. + +- **stores** — *A product catalog.* `intent.stores.productCount` products whose names/prices fit `brand`. If `intent.stores.categoriesNamed` is non-empty, create exactly those categories and assign products into them; **if empty, create none** (skill policy — overrides any recipe default). Text-only. **Keep:** `productIds[]`, `categoryIds[]`, and product `slug`s (the frontend links by slug). +- **blog** — *Initial posts.* `intent.blog.postCount` posts on `intent.blog.topics` (or brand-derived topics). Text-only (no covers). Bulk-create when `postCount ≥ 2`. **Keep:** `postIds[]`, post `slug`s. +- **cms** — *Content collections.* One collection per `intent.cms.collections` entry; `itemCount` items each, content from `brand`. Collections are **public-read** (visitor reads on the frontend). **Keep:** `collectionIds{}`, `itemIds{:[]}`, and each collection's field keys (the frontend binds by them). +- **forms** — *Lead-capture forms.* One form per `intent.forms.forms` entry; fields from the entry; `purpose` names the form. **Keep:** `formIds[]`, and each form's field **`target`** keys (the frontend sets input `name` = target). + +## Aggregate + +Hold a `seeded` map in scratch — `seeded[] = { …kept IDs… }`. This is the producer for the handoff (`SDK_HANDOFF.md`), which inlines the IDs so the host can bind immediately. Whether to also write a sidecar file is a host-preference choice (default: return-only, in the handoff message). + +On a per-capability error, keep the other capabilities' results and surface the failing recipe-call response verbatim; partial state is fine — a targeted re-run is bounded. + +## Proceed to Handoff + +With `seeded` populated, continue to **`SDK_HANDOFF.md`** to produce the document the host wires from. diff --git a/skills/sp-wix/references/SETUP.md b/skills/sp-wix/references/SETUP.md new file mode 100644 index 00000000..c3fcfad1 --- /dev/null +++ b/skills/sp-wix/references/SETUP.md @@ -0,0 +1,51 @@ +# Setup — install the business apps + +Install the Wix apps the resolved capabilities need, on the given metasite. That is the whole of setup — the frontend toolchain stays with the host. + +## 1 · Load the recipe library + +Invoke `Skill(name="wix-manage")` **once**. This loads the recipe files into context — Setup uses the app-install recipe now, and **Seed reuses the in-context recipes** (it does not re-invoke). A directory path is not a substitute; the recipes must be in context. + +Then read the install recipe for the exact body shape: + +``` +Read /references/app-installation/install-wix-apps.md +``` + +## 2 · Mint the token + +Per `references/AUTHENTICATION.md` § "Minting the token" — one Bash call, secret stays out of context, token to `/tmp/wix_token`. Mint once; later calls read it back. + +## 3 · Install one app per capability + +For each capability in `verticals[]`, look up its `appDefId` in `references/CAPABILITIES.md`: + +- **stores** → `215238eb-22a5-4c36-9e7b-e7c08025e04e` +- **blog** → `14bcded7-0066-7c35-14d7-466cb3f09103` +- **forms** → `225dd912-7dea-4738-8688-4b8c6955ffc2` +- **cms** → **no install** (Wix Data is core) — skip + +Fire one install `curl` per app (the recipe's `POST /apps-installer-service/v1/app-instance/install`), body shape from the recipe: + +```bash +set -a; . ./.env; set +a +TOKEN=$(cat /tmp/wix_token) +SITE_ID="${WIX_WIX_METASITE_ID:-$WIX_METASITE_ID}" +curl -sS -w "\nHTTP_STATUS:%{http_code}" \ + -X POST "https://www.wixapis.com/apps-installer-service/v1/app-instance/install" \ + -H "Authorization: Bearer $TOKEN" \ + -H "wix-site-id: $SITE_ID" \ + -H "Content-Type: application/json" \ + -d '{ + "tenant": { "tenantType": "SITE", "id": "'"$SITE_ID"'" }, + "appInstance": { "appDefId": "", "enabled": true } + }' +``` + +The installs are independent — issue them in whatever order is convenient. + +A **200** confirms the install. On a non-200, surface the response verbatim and stop. + +## 4 · Proceed to Seed + +Confirm every required app returned 200 (cms skipped). Then continue to **`SEED.md`** — the `wix-manage` recipes are already in context. From 5b382dba15562b3180d029c8867468a4b1b191da Mon Sep 17 00:00:00 2001 From: Oz Sayag Date: Tue, 9 Jun 2026 16:03:05 +0300 Subject: [PATCH 2/4] work --- skills/sp-wix/SKILL.md | 2 +- skills/sp-wix/references/SEED.md | 2 +- skills/sp-wix/references/SETUP.md | 20 +++++--------------- 3 files changed, 7 insertions(+), 17 deletions(-) diff --git a/skills/sp-wix/SKILL.md b/skills/sp-wix/SKILL.md index a534d15b..6540c59c 100644 --- a/skills/sp-wix/SKILL.md +++ b/skills/sp-wix/SKILL.md @@ -57,4 +57,4 @@ Compute `` from this file (`/SKILL.md` — strip `/SKILL ## Upstream -The **only** upstream dependency is **`wix-manage`** — the recipe library for app installation and content seeding, loaded via `Skill(name="wix-manage")` (Setup does this once; Seed reuses the in-context recipes). API request shapes (endpoints, payloads, field templates) live there and are the single source of truth; this skill carries the *what* (which capabilities, how much content) and searches `wix-manage` for the *how*. +The **only** upstream dependency is **`wix-manage`** — the recipe library for **content seeding**, loaded via `Skill(name="wix-manage")` in **Seed**. Setup doesn't need it: the app-install call is a single fixed shape carried inline in `SETUP.md`. For seeding, the API request shapes (endpoints, payloads, field templates) live in the recipes and are the single source of truth; this skill carries the *what* (which content, how much) and searches `wix-manage` for the *how*. diff --git a/skills/sp-wix/references/SEED.md b/skills/sp-wix/references/SEED.md index ec73808b..d858e79a 100644 --- a/skills/sp-wix/references/SEED.md +++ b/skills/sp-wix/references/SEED.md @@ -4,7 +4,7 @@ For each capability, create the backend content its *what* names. This step carr ## How it runs -`wix-manage` is already in context (loaded in Setup). The token is in `/tmp/wix_token`. The capabilities are **independent** — no ordering or data dependency between them. For each one: +First, **load the recipe library**: invoke `Skill(name="wix-manage")` **once** — this brings the recipe files into context (a directory path is not a substitute). The token is already in `/tmp/wix_token` from Setup. The capabilities are **independent** — no ordering or data dependency between them. For each one: 1. **Find the recipe** by its capability phrase (`references/CAPABILITIES.md` → "wix-manage capability phrase") against the in-context recipe index. **Fail loud** if no recipe matches a required capability — a missing recipe is a real error, not a cue to guess. 2. **Read the matched recipe** and build request bodies from `intent.` + `brand`. The recipe is the source of truth for URL/method/body. diff --git a/skills/sp-wix/references/SETUP.md b/skills/sp-wix/references/SETUP.md index c3fcfad1..19d1de57 100644 --- a/skills/sp-wix/references/SETUP.md +++ b/skills/sp-wix/references/SETUP.md @@ -2,21 +2,11 @@ Install the Wix apps the resolved capabilities need, on the given metasite. That is the whole of setup — the frontend toolchain stays with the host. -## 1 · Load the recipe library - -Invoke `Skill(name="wix-manage")` **once**. This loads the recipe files into context — Setup uses the app-install recipe now, and **Seed reuses the in-context recipes** (it does not re-invoke). A directory path is not a substitute; the recipes must be in context. - -Then read the install recipe for the exact body shape: - -``` -Read /references/app-installation/install-wix-apps.md -``` - -## 2 · Mint the token +## 1 · Mint the token Per `references/AUTHENTICATION.md` § "Minting the token" — one Bash call, secret stays out of context, token to `/tmp/wix_token`. Mint once; later calls read it back. -## 3 · Install one app per capability +## 2 · Install one app per capability For each capability in `verticals[]`, look up its `appDefId` in `references/CAPABILITIES.md`: @@ -25,7 +15,7 @@ For each capability in `verticals[]`, look up its `appDefId` in `references/CAPA - **forms** → `225dd912-7dea-4738-8688-4b8c6955ffc2` - **cms** → **no install** (Wix Data is core) — skip -Fire one install `curl` per app (the recipe's `POST /apps-installer-service/v1/app-instance/install`), body shape from the recipe: +Fire one install `curl` per app — `POST /apps-installer-service/v1/app-instance/install`: ```bash set -a; . ./.env; set +a @@ -46,6 +36,6 @@ The installs are independent — issue them in whatever order is convenient. A **200** confirms the install. On a non-200, surface the response verbatim and stop. -## 4 · Proceed to Seed +## 3 · Proceed to Seed -Confirm every required app returned 200 (cms skipped). Then continue to **`SEED.md`** — the `wix-manage` recipes are already in context. +Confirm every required app returned 200 (cms skipped). Then continue to **`SEED.md`**, which loads the `wix-manage` recipes for content seeding. From 13745410cc71e81a3be3d05eb36453bf86e6c708 Mon Sep 17 00:00:00 2001 From: Oz Sayag Date: Wed, 10 Jun 2026 14:45:03 +0300 Subject: [PATCH 3/4] work --- skills/sp-wix/SKILL.md | 14 ++-- skills/sp-wix/references/CAPABILITIES.md | 82 +++++++++++++++++------- skills/sp-wix/references/DISCOVERY.md | 9 ++- skills/sp-wix/references/SDK_HANDOFF.md | 30 ++++++--- skills/sp-wix/references/SEED.md | 50 +++++++++++---- skills/sp-wix/references/SETUP.md | 9 ++- 6 files changed, 141 insertions(+), 53 deletions(-) diff --git a/skills/sp-wix/SKILL.md b/skills/sp-wix/SKILL.md index 6540c59c..5e0221c2 100644 --- a/skills/sp-wix/SKILL.md +++ b/skills/sp-wix/SKILL.md @@ -1,6 +1,6 @@ --- name: sp-wix -description: "Connect Wix business services (Stores, Blog, CMS, Forms) to a Stripe Projects app. Use AFTER `stripe projects add wix/*` has provisioned a Wix metasite + synced its credentials to `.env`. Given the metasite and the user's intent, this skill runs the Wix business flow — infers which Wix capabilities the app needs, installs the apps, seeds backend content — then returns an SDK-integration guide (how to call Wix from the frontend) for the host agent to use. The host keeps ownership of the frontend, the build, and the hosting. Triggers: set up Wix in this Stripe project, add a Wix store/blog/CMS/forms backend, connect Wix Headless to my Stripe app, provision Wix content for this project, I added wix with stripe projects now wire it up. NOT for: building a new Wix-hosted site from scratch (use wix-headless), or anything outside a Stripe Projects app." +description: "Connect Wix business services (Stores, Blog, CMS, Forms, Events, Bookings, Pricing Plans) to a Stripe Projects app. Use AFTER `stripe projects add wix/*` has provisioned a Wix metasite + synced its credentials to `.env`. Given the metasite and the user's intent, this skill runs the Wix business flow — infers which Wix capabilities the app needs, installs the apps, seeds backend content — then returns an SDK-integration guide (how to call Wix from the frontend) for the host agent to use. The host keeps ownership of the frontend, the build, and the hosting. Triggers: set up Wix in this Stripe project, add a Wix store/blog/CMS/forms/events/bookings/pricing-plans backend, connect Wix Headless to my Stripe app, provision Wix content for this project, I added wix with stripe projects now wire it up. NOT for: building a new Wix-hosted site from scratch (use wix-headless), or anything outside a Stripe Projects app." allowed-tools: - Bash(curl *) - Bash(ls *) @@ -10,7 +10,6 @@ allowed-tools: - Bash(test *) - Read - Write - - Skill --- # Wix Headless × Stripe Projects @@ -46,7 +45,7 @@ Compute `` from this file (`/SKILL.md` — strip `/SKILL | What | Path | |---|---| | Authentication (token mint + REST contract + ladder) | `/references/AUTHENTICATION.md` | -| Capability map (intent → apps + seed-what + SDK packages) | `/references/CAPABILITIES.md` | +| Vertical index (intent matching + per-vertical site spec) | `/references/CAPABILITIES.md` | | Discovery (infer capabilities + brand + intent) | `/references/DISCOVERY.md` | | Setup (install apps) | `/references/SETUP.md` | | Seed (create backend content) | `/references/SEED.md` | @@ -55,6 +54,11 @@ Compute `` from this file (`/SKILL.md` — strip `/SKILL **Start a run by opening `DISCOVERY.md`.** -## Upstream +## Where the *how* comes from -The **only** upstream dependency is **`wix-manage`** — the recipe library for **content seeding**, loaded via `Skill(name="wix-manage")` in **Seed**. Setup doesn't need it: the app-install call is a single fixed shape carried inline in `SETUP.md`. For seeding, the API request shapes (endpoints, payloads, field templates) live in the recipes and are the single source of truth; this skill carries the *what* (which content, how much) and searches `wix-manage` for the *how*. +This skill has **no skill upstream** — the *how* is read from the **live Wix docs** at `dev.wix.com/docs`, fetched as raw markdown via `curl` (append `.md` to any docs URL; menu pages list child links, content pages carry the schema): + +- **Seed** reads the **REST docs** for each capability's create method — navigated from the Business Solutions index (`api-reference/business-solutions.md`) per the mechanism in `SEED.md` (Forms lives under `api-reference/crm/forms.md`). +- **Handoff** links the **SDK docs** for each capability's API shape, and supplies the runtime package set from the inlined map in `SDK_HANDOFF.md` (the SDK `.md` pages don't expose `@wix/*` import strings to navigation, so packages are mapped, not navigated). + +Setup carries its app-install call (and the appDefId constants) inline in `SETUP.md`; `CAPABILITIES.md` is the vertical index that lets Discovery match intent **and** declares, per built vertical, the *Required site features* + *Implementation checklist* that Seed enables (backend-backed features) and the Handoff carries into the guide (so the host builds a complete site, not a bare data dump). This skill carries the *what* (which capabilities, how much content, what a finished site includes) and reads the *how* off the docs. diff --git a/skills/sp-wix/references/CAPABILITIES.md b/skills/sp-wix/references/CAPABILITIES.md index 37149e53..4916db95 100644 --- a/skills/sp-wix/references/CAPABILITIES.md +++ b/skills/sp-wix/references/CAPABILITIES.md @@ -1,33 +1,67 @@ -# Capability map +# Wix vertical index -The skill's own **what** table — the single source the other steps key off. Each capability names: the **app to install** (Setup), the **content to seed** + the wix-manage **capability phrase** to search (Seed), and the **SDK package(s) + docs link** to hand off (Handoff). It deliberately carries **no API request shapes or call snippets** — request shapes are wix-manage's job (found by the capability phrase); frontend call shapes are the live SDK docs' job (the Handoff links to them, never reproduces them). This is the *what*; wix-manage and the SDK docs are the *how*. +A catalog of the Wix business verticals. It does two jobs: -| Capability | Install (appDefId) | Seed — *what* | wix-manage capability phrase | SDK package(s) | SDK docs (for the Handoff) | -|---|---|---|---|---|---| -| **stores** | Wix Stores `215238eb-22a5-4c36-9e7b-e7c08025e04e` | `intent.stores.productCount` products fitting `brand`; the named categories in `intent.stores.categoriesNamed` (none if empty) | *"set up an online store catalog and bulk-create products"* | `@wix/stores` (+ `@wix/ecom @wix/redirects` for cart/checkout) | dev.wix.com/docs/sdk/business-solutions/stores.md (cart: …/ecom.md) | -| **blog** | Wix Blog `14bcded7-0066-7c35-14d7-466cb3f09103` | `intent.blog.postCount` posts on `intent.blog.topics` (else brand-derived) | *"create blog posts (bulk)"* | `@wix/blog` (+ `@wix/ricos` for rich content) | dev.wix.com/docs/sdk/business-solutions/blog.md | -| **forms** | Wix Forms `225dd912-7dea-4738-8688-4b8c6955ffc2` | one form per `intent.forms.forms` entry; fields from each entry | *"create a Wix form"* | `@wix/forms` | dev.wix.com/docs/sdk/business-solutions.md (locate forms/submissions) | -| **cms** | **none** — Wix Data is core (no install) | one collection per `intent.cms.collections` entry + `itemCount` items, content from `brand`; **public-read** | *"create a CMS collection schema"* + *"insert CMS collection items"* | `@wix/data` | dev.wix.com/docs/sdk/business-solutions/data.md | +1. **Discovery** maps the user's words to the right vertical(s) — read every *Intent* line against what they asked for, and pick each vertical that genuinely fits. +2. For the verticals this skill builds end-to-end, it also says **what a complete site for that vertical looks like** — the features it must have and the details that make it feel finished — so the handoff asks the host for a *real* site, not a bare data dump. -Always-on package (every capability): **`@wix/sdk`** (provides `createClient` + `OAuthStrategy`). +This file is **the what, never the how** — plain language only. No endpoints, methods, payloads, appDefIds, or SDK packages. The *how* lives in the live docs (Seed navigates the REST docs; the Handoff navigates the SDK docs); the *which apps to install* lives in `SETUP.md`. -## Notes that are genuinely the skill's *what* (not recipe *how*, not SDK-usage) +Each built vertical has three parts: -- **stores** — products are **text-only** (no imagery sourced); use the recipe's documented no-image/placeholder path. Categories: create exactly `intent.stores.categoriesNamed`; **if empty, create none** (overrides any recipe default). -- **blog** — text-only (no cover imagery). Bulk-create when `postCount ≥ 2`. -- **cms** — collections are **public-read** (a visitor token has no per-user identity; data is shared/public — surface this to the host in the handoff). Frontend reads are visitor-safe; visitor writes go through Forms. -- **forms** — `purpose` ("contact"/"lead"/"signup") drives the form name; the Wix Forms app is installed in Setup, so the seed step does not reinstall. +- **Intent** — the words that point to it. +- **Required site features** — the surfaces and capabilities the site must have to be usable. These are non-negotiable for a complete site; if one needs a backend feature switched on, Seed sets it up, and the Handoff tells the host to build the rest. +- **Implementation checklist** — the presentation details a finished site shows, so it doesn't feel half-built. The Handoff carries these into the guide it returns. -## Intent → capability resolution (used by DISCOVERY) +## Built verticals — installed, seeded, and described in the Handoff -Map the user's words to the set above. The floor is **forms** (a contact/lead form) when nothing richer fits: +The verticals the skill operates end-to-end today: **stores · blog · cms · forms · events · bookings · pricing-plans** (with `forms` as the floor when nothing richer is named). -| Signal in intent | Capabilities | -|---|---| -| sell / shop / products / catalog / store | `stores` (+ cart via ecom packages) | -| blog / posts / articles / publication / news | `blog` | -| collection / directory / portfolio / structured content / "persist my app's data" | `cms` | -| contact / RSVP / lead / signup / waitlist / "let people reach me" | `forms` | -| nothing dynamic named | `forms` (contact-form floor) | +### stores — sell products +- **Intent:** sell / shop / products / catalog / merch / store. +- **Required site features:** a product list or grid; a page per product; categories to browse by; a cart; a checkout. +- **Implementation checklist:** show each product's image, name, and price; show options and variants (size, colour…) where they exist; show availability / out-of-stock; a quantity picker and an add-to-cart that updates a visible cart; the product description; link each product to its category. -Multiple signals → multiple capabilities. On ambiguity pick the first row that matches, top-to-bottom. +### blog — publish posts +- **Intent:** blog / posts / articles / publication / news. +- **Required site features:** a list of posts; a page per post; readers can leave **comments** on a post; categories or tags to browse by topic. +- **Implementation checklist:** show the **author** (name and photo) on each post; show the publish date and the reading time; show the cover image; render the full formatted content — headings, images, quotes, lists — not flattened to plain text; show the post's category and tags; a clear path back to the full list. + +### cms — structured content collections +- **Intent:** collection / directory / portfolio-as-data / structured content / "persist my app's data". +- **Required site features:** an index/list view of the collection; a detail page per item. (Visitor reads are public; visitor writes go through a form.) +- **Implementation checklist:** show each item's main fields with clear labels; link the list to each item's detail page; show a sensible empty state when there are no items yet. + +### forms — capture leads +- **Intent:** contact / lead / signup / waitlist / "let people reach me" / nothing dynamic named. +- **Required site features:** a visible form; a confirmation after submitting; basic field validation. +- **Implementation checklist:** render every field with a clear label; mark which fields are required; a clear submit button; show a thank-you / success state after sending; show a friendly message if the submit fails. + +### events — events and registration +- **Intent:** event / ticket / RSVP / registration / attendees. +- **Required site features:** a list of events; a page per event; a way to register or RSVP. +- **Implementation checklist:** show each event's title, date and time, and location; show the description; show ticket types where they exist; a register/RSVP action; a confirmation after registering. + +### bookings — appointments and classes +- **Intent:** book / appointment / schedule / class / session / reserve a slot / reserve a table. +- **Required site features:** a list of services; a page per service; a way to pick a time and book it. +- **Implementation checklist:** show each service's name, duration, and price; show the staff or provider; show the available time slots; a book action; a confirmation after booking. + +### pricing-plans — memberships and subscriptions +- **Intent:** membership / subscription / plans / paid tiers. +- **Required site features:** a plans / pricing page; a way to choose and subscribe to a plan. +- **Implementation checklist:** show each plan's name, price, and billing cycle; list what each plan includes (the perks); a clear "choose plan" action; highlight a recommended tier where it makes sense. + +## Other verticals — recognized for intent, not yet wired + +If a user's intent points squarely at one of these, surface it plainly as **not-yet-wired** rather than forcing a poor fit. Extending the skill to one means adding its install in `SETUP.md` and its seed *what* in `SEED.md`, then giving it a full section above. + +- **eCommerce** — the shared cart, checkout, orders, and payments layer the catalog verticals (Stores, Bookings…) plug into; rarely chosen alone, it rides along when a purchase flow is needed. *Intent: checkout / cart / "let people buy".* +- **restaurants** — menus and online food ordering; a table-reservation intent goes to **bookings** instead. *Intent: menu / restaurant / order food / dine-in.* +- **forum** — community discussion boards: categories, threads, member posts. *Intent: forum / community / discussion board.* +- **portfolio** — showcase collections of projects and work. *Intent: portfolio / showcase / gallery of projects / creative work.* +- **donations** — donation campaigns and contributions. *Intent: donate / fundraise / campaign / nonprofit.* +- **gift-cards** — issue and redeem stored-value gift cards. *Intent: gift card / store credit / voucher.* +- **coupons** — discount codes and promotions applied at checkout. *Intent: coupon / promo code / discount.* +- **benefit-programs** — loyalty/benefit programs that grant members perks. *Intent: loyalty / rewards / member perks / benefits.* +- **suppliers-hub** — supplier-side B2B product catalog management. *Intent: supplier / wholesale / B2B catalog.* diff --git a/skills/sp-wix/references/DISCOVERY.md b/skills/sp-wix/references/DISCOVERY.md index 4032f3ab..6ef4aaf7 100644 --- a/skills/sp-wix/references/DISCOVERY.md +++ b/skills/sp-wix/references/DISCOVERY.md @@ -13,7 +13,9 @@ Hold `WIX_WIX_METASITE_ID` as `SITE_ID` in scratch. ## 1 · Resolve the capability set -Map the **user intent** (+ optional project signals: `package.json` name, README, visible copy) to `verticals[]` using `references/CAPABILITIES.md` § "Intent → capability resolution". Multiple signals → multiple capabilities. On ambiguity, pick the first matching row top-to-bottom; if nothing dynamic is named, fall to the **forms** floor (a contact form). Never return an empty set. +Read the **user intent** (+ optional project signals: `package.json` name, README, visible copy) against the vertical index in `references/CAPABILITIES.md` — each entry there carries the intent signals that point to it. Pick every vertical that genuinely fits → `verticals[]`. Multiple signals → multiple capabilities. On ambiguity, prefer the more specific vertical; if nothing dynamic is named, fall to the **forms** floor (a contact form). **Never return an empty set.** + +Resolve to the skill's operational set — **stores · blog · cms · forms · events · bookings · pricing-plans** (`CAPABILITIES.md` § "What this skill currently installs + seeds"). If intent points squarely at a vertical outside that set, note it plainly as not-yet-wired (per the index) and resolve the rest; don't force an unrelated capability in its place. ## 2 · Infer brand @@ -21,7 +23,7 @@ A short brand object for seeded-content naming: `{ name, description, vibe? }`. ## 3 · Derive per-capability intent -For each capability, build its `intent.` block — the inputs the seed step translates into recipe calls. Use sensible brand-appropriate defaults when the user didn't specify counts: +For each capability, build its `intent.` block — the inputs the seed step translates into REST calls. Use sensible brand-appropriate defaults when the user didn't specify counts: | Capability | `intent.` shape | Defaults when unspecified | |---|---|---| @@ -29,6 +31,9 @@ For each capability, build its `intent.` block — the inputs the seed step | blog | `{ postCount, topics: [] }` | `postCount: 3`, topics derived from `brand.description` | | cms | `{ collections: [{ name, purpose, itemCount, fields? }] }` | one collection inferred from intent, `itemCount: 5` | | forms | `{ forms: [{ purpose, fields: [...] }] }` | one `contact` form: name, email, message | +| events | `{ eventCount, titles: [] }` | `eventCount: 2`, titles brand-derived, future dates | +| bookings | `{ serviceCount, servicesNamed: [] }` | `serviceCount: 2`, brand-derived service names | +| pricing-plans | `{ planCount, tiersNamed: [] }` | `planCount: 2` (e.g. Basic / Pro), monthly billing | Counts are deliberately small (text-only seed; the host's app shows the shape, not a full catalog). Don't invent imagery — seed is text-only. diff --git a/skills/sp-wix/references/SDK_HANDOFF.md b/skills/sp-wix/references/SDK_HANDOFF.md index e300bff5..9eb44e51 100644 --- a/skills/sp-wix/references/SDK_HANDOFF.md +++ b/skills/sp-wix/references/SDK_HANDOFF.md @@ -4,31 +4,36 @@ The skill **returns this document** describing how to call Wix from the frontend, then **exits**. The host agent — which owns the frontend, the framework, and the build — does the wiring. We describe what to use and **link to the live Wix SDK docs for the API shapes**; the host decides where they go. -> **Link to the docs; do not inline API examples.** The Wix SDK docs are versioned and complete; hand-written snippets under-specify the hard parts (rich-content rendering, package versions, types) and lead the host to build against a wrong or stale shape. The handoff's job is to point at the *right* doc page and supply the three things the docs can't know: the **seeded IDs**, the **`clientId` source**, and the **package set**. Let the host read the current API from the docs. +> **Link to the docs for API shapes; don't inline examples.** The Wix SDK docs are versioned and complete; hand-written snippets under-specify the hard parts (rich-content rendering, package versions, types) and lead the host to build against a wrong shape. The handoff supplies what the docs can't: the **seeded IDs**, the **`clientId` source**, and the **package set**. The package set is the **inlined map in §3** — the SDK doc `.md` pages don't surface the `@wix/*` import string to navigation, so the map is the source of truth for *which* packages; the linked module pages remain the source of truth for *how* to call them (current API shape + version). > > **The linked docs are the source of truth for current API shapes and versions — read them for the integration. Existing code (in this or any other project) is not a substitute: it may target a different SDK version and silently mislead.** -Emit the document as the skill's final message (a Markdown block the host can act on or save). Fill it from the run's `verticals[]`, the `seeded` map, and `WIX_WIX_CLIENT_ID`. Include **only** the loaded capabilities. +Emit the document as the skill's final message (a Markdown block the host can act on or save). Fill it from the run's `verticals[]`, the `seeded` map, `WIX_WIX_CLIENT_ID`, and — for each loaded capability — its **Required site features** and **Implementation checklist** from `references/CAPABILITIES.md` (§6). Include **only** the loaded capabilities. The guide isn't just "here are the IDs and packages"; it's the spec for a *complete* site, so the host builds real features (author, comments, dates…) rather than a bare data dump. ## What the document contains ### 1 · Packages to install -The union of the loaded capabilities' SDK packages (`references/CAPABILITIES.md`) plus the always-on `@wix/sdk` — **runtime packages only** (no scaffold/build deps). For install details and current versions, link: . +The always-on package is **`@wix/sdk`** (provides `createClient` + `OAuthStrategy`). Add the union of the loaded capabilities' runtime packages from the **map in §3**. **Runtime packages only** (no scaffold/build deps). For install details and current versions, link: . ### 2 · Client setup (and the clientId source) The frontend authenticates as an **anonymous visitor** via `OAuthStrategy`, with `clientId` = the **`WIX_WIX_CLIENT_ID`** value. The `clientId` is **not secret** (it's the public OAuth id) — the host exposes it to client code via its framework's public-env convention (`NEXT_PUBLIC_*`, `VITE_*`, `PUBLIC_*`, …). The **`client_secret` never reaches the frontend.** For the current `createClient` + auth-strategy shape, link: - - -### 3 · Per-capability API docs (link, don't snippet) -For each loaded capability, give the package and its SDK doc page: +### 3 · Per-capability packages + API docs (package from the map; link for shapes) +For each loaded capability, give the host the **package(s)** from the map below and the **SDK module doc link** — the current API shape, methods, and version live on that page; let the host read them there rather than snippeting. -| Capability | Package(s) | SDK docs | +| Capability | Package(s) | SDK module docs (read for the API shape) | |---|---|---| | stores | `@wix/stores` (+ `@wix/ecom`, `@wix/redirects` for cart/checkout) | · cart: | -| blog | `@wix/blog` (+ `@wix/ricos` to render rich post content) | — for rendering `richContent`, follow the blog docs to the current `@wix/ricos` viewer API + version (don't pin blind) | +| blog | `@wix/blog` (+ `@wix/ricos` to render `richContent` — follow the blog page to the current viewer API, don't pin a version blind) | | | cms | `@wix/data` | | -| forms | `@wix/forms` | not a standalone business-solutions page — find the forms/submissions module from the menu () or via `SearchWixSDKDocumentation` | +| forms | `@wix/forms` | under CRM: (forms/submissions module) | +| events | `@wix/events` | | +| bookings | `@wix/bookings` | | +| pricing-plans | `@wix/pricing-plans` | (lives under frontend-modules, not business-solutions) | + +> **Why a map and not navigation:** the SDK doc `.md` pages don't expose the `@wix/*` import string to a reader (it's only in the page's interactive UI), so the package column is inlined here as the source of truth. If a package name ever drifts, reconcile it against the SDK install article (§1) — not by guessing from the module URL. The linked pages remain authoritative for the API itself. ### 4 · Seeded IDs (what the host binds to) From the `seeded` map — the IDs only this run knows: @@ -36,11 +41,20 @@ From the `seeded` map — the IDs only this run knows: - **blog:** `postIds`, post `slug`s - **cms:** `collectionId` + field keys per collection - **forms:** `formId` + each form's field **`target`** keys (frontend input `name` = `target`) +- **events:** `eventIds`, event `slug`s +- **bookings:** `serviceIds`, service `slug`s +- **pricing-plans:** `planIds` ### 5 · Integration notes (headless-auth specifics the per-module docs won't frame) - The visitor token has **no per-user identity** → seeded **CMS collections are public/shared** across all visitors (not per-user, not cross-device). Per-user storage needs member auth. - Frontend CMS access is **read**; visitor writes go through **Forms** submissions. +### 6 · What a complete site must include (per loaded capability) +For each loaded capability, carry its **Required site features** and **Implementation checklist** from `references/CAPABILITIES.md` into the guide — in plain product language, lightly tailored to what was seeded. **This is the build spec, not optional polish:** the host should build every *required feature* and cover every *checklist* item. For example, a blog must show the **author** (name + photo), the publish date and reading time, the cover image, the **full formatted content** (not flattened text), and let readers **comment** — a posts-list-plus-plain-text-body is incomplete. The host maps these onto its own components using the packages/docs in §3 and the seeded IDs in §4. + +- State them as the *what* (product behaviour), not the *how* (no component code, no API calls) — the host owns the build. +- If a *required feature* depends on backend support that **Seed** enabled (e.g., comments), note it's available so the host wires it. If Seed could **not** enable it, say so plainly rather than implying the site is complete. + ## How to navigate the Wix docs > - Append `.md` to any URL under `https://dev.wix.com/docs/` to get its markdown version. diff --git a/skills/sp-wix/references/SEED.md b/skills/sp-wix/references/SEED.md index d858e79a..203aeac4 100644 --- a/skills/sp-wix/references/SEED.md +++ b/skills/sp-wix/references/SEED.md @@ -1,32 +1,58 @@ # Seed — create the backend content -For each capability, create the backend content its *what* names. This step carries **only the *what*** (entities, count source, policy); the **API *how*** is found by searching the in-context `wix-manage` recipes. **No endpoints, payloads, field templates, caps, or batching mechanics live in this file** — if you find yourself writing one, it belongs to a recipe. +For each resolved capability, create the backend content its *what* names. This file carries **only the *what*** (entities, counts, policy) and the **navigation mechanism** for finding the API *how* in the live Wix REST docs. **No endpoints, payloads, field templates, caps, or batching mechanics live here** — if you find yourself writing one, read it off the docs page instead. -## How it runs +The token is already in `/tmp/wix_token` from Setup. The capabilities are **independent** — no ordering or data dependency. For each one: navigate the docs to its create method (§1), build the body from `intent.` + `brand`, execute against `wixapis.com` with the call shape in `references/AUTHENTICATION.md` (Bearer from `/tmp/wix_token` + `wix-site-id`), and collect the created IDs into a `seeded` map keyed by capability. -First, **load the recipe library**: invoke `Skill(name="wix-manage")` **once** — this brings the recipe files into context (a directory path is not a substitute). The token is already in `/tmp/wix_token` from Setup. The capabilities are **independent** — no ordering or data dependency between them. For each one: +## 1 · The navigation mechanism — find the *how* in the docs -1. **Find the recipe** by its capability phrase (`references/CAPABILITIES.md` → "wix-manage capability phrase") against the in-context recipe index. **Fail loud** if no recipe matches a required capability — a missing recipe is a real error, not a cue to guess. -2. **Read the matched recipe** and build request bodies from `intent.` + `brand`. The recipe is the source of truth for URL/method/body. -3. **Execute** against `wixapis.com` with the call shape in `references/AUTHENTICATION.md` (Bearer from `/tmp/wix_token` + `wix-site-id`). -4. **Collect the created IDs** into a `seeded` map keyed by capability. +Every Wix docs URL serves raw markdown when you append `.md` and `curl` it. A **menu page** lists links to child pages; a **content/method page** carries the endpoint, HTTP verb, and request/response schema. -> **Text-only seed.** Use each recipe's documented no-image/placeholder path; don't source imagery. The host's app demonstrates the data *shape*, not a full media catalog. +**To learn how to seed a capability, start at its `Introduction` and continue from there:** -## Per-capability *what* +1. From the base index (§2), follow the link for the capability's vertical. +2. Open the vertical's **`Introduction`** (and any "About …" page) first — it orients you to the vertical's objects and the create flow, so you pick the *right* method instead of guessing a URL. +3. Drill (menu → menu) to the specific **create** method page, `curl ….md`, and read the endpoint, verb, and body schema **off the page**. Never invent a URL or body from memory. +4. **Fail loud** if you can't locate a required method — a missing method page is a real error, not a cue to guess. -Each block states only the entities, where their count/content comes from, the policy that is genuinely the skill's call, and the IDs to keep. The capability phrase (CAPABILITIES.md) finds the recipe that supplies the rest. +> **Public host, not `/_api/`.** Some method pages show an internal `https://www.wixapis.com/_api//...` URL in the schema header while the examples use the bare `https://www.wixapis.com//...`. Always call the **public (non-`/_api/`) form** — that's the external/headless endpoint; the `/_api/` prefix is internal and may be rejected. -- **stores** — *A product catalog.* `intent.stores.productCount` products whose names/prices fit `brand`. If `intent.stores.categoriesNamed` is non-empty, create exactly those categories and assign products into them; **if empty, create none** (skill policy — overrides any recipe default). Text-only. **Keep:** `productIds[]`, `categoryIds[]`, and product `slug`s (the frontend links by slug). +> **Text-only seed.** Omit image fields, or use the placeholder the method's schema documents; don't source imagery. The host's app demonstrates the data *shape*, not a full media catalog. + +## 2 · Where to start — base links + +- **REST API index (per-vertical entry point):** — start here for **stores**, **blog**, **cms**, and every other Business Solutions vertical. +- **Forms (CRM portal, *not* under Business Solutions):** — the standalone Wix Forms API. Its `Form Schemas ▸ Create Form` is the create method; the events/bookings "form" pages are a different thing (per-event registration forms), not this. + +## 3 · What to seed per capability + +Each entry states only the entities, where their count/content comes from, the policy that is genuinely the skill's call, and the IDs to keep. §1 finds the method that supplies the rest. + +- **stores** — *A product catalog.* `intent.stores.productCount` products whose names/prices fit `brand`. If `intent.stores.categoriesNamed` is non-empty, create exactly those categories and assign products into them; **if empty, create none** (skill policy — overrides any docs default). Text-only. **Keep:** `productIds[]`, `categoryIds[]`, and product `slug`s (the frontend links by slug). - **blog** — *Initial posts.* `intent.blog.postCount` posts on `intent.blog.topics` (or brand-derived topics). Text-only (no covers). Bulk-create when `postCount ≥ 2`. **Keep:** `postIds[]`, post `slug`s. - **cms** — *Content collections.* One collection per `intent.cms.collections` entry; `itemCount` items each, content from `brand`. Collections are **public-read** (visitor reads on the frontend). **Keep:** `collectionIds{}`, `itemIds{:[]}`, and each collection's field keys (the frontend binds by them). - **forms** — *Lead-capture forms.* One form per `intent.forms.forms` entry; fields from the entry; `purpose` names the form. **Keep:** `formIds[]`, and each form's field **`target`** keys (the frontend sets input `name` = target). +- **events** — *Upcoming events.* `intent.events.eventCount` events with brand-appropriate titles and **future** start dates (a default location/timezone is fine). One create call per event. Text-only. **Keep:** `eventIds[]`, event `slug`s. +- **bookings** — *Bookable services.* `intent.bookings.serviceCount` services (name + short description fitting `brand`, a simple duration and price). One create call per service against the **public** `POST https://www.wixapis.com/bookings/v2/services` (the method page's schema header shows the internal `/_api/bookings/v2/services` — don't use that form); keep the schedule minimal — a single default availability is enough for the experiment. **Keep:** `serviceIds[]`, service `slug`s. +- **pricing-plans** — *Membership tiers.* `intent.pricing-plans.planCount` recurring plans (name, price, a monthly billing cycle) fitting `brand`. One create call per plan. **Keep:** `planIds[]`. + +> **Simple seeds (experiment).** For these newer capabilities, create the minimum that demonstrates the shape — a couple of entities with required fields only. Read the create method's `Introduction` (§1) for which fields are *required* and stop there; don't seed optional structure (variants, multi-session schedules, perks) the host's app won't exercise. + +## 4 · Enable the backend-backed required features + +A capability's **Required site features** (`references/CAPABILITIES.md`) are part of a complete site, and some of them need a backend feature switched on — not just content created. The clearest case: **blog comments** (readers commenting on posts). For each loaded capability, check its *Required site features*: + +- If one depends on a backend feature that isn't on by default, enable it via its docs method (navigate as in §1). +- If it's already on by default, there's nothing to seed — but record it as **available** so the Handoff tells the host to surface it. +- If it genuinely can't be enabled, note that, so the Handoff doesn't imply the site is complete. + +Don't silently skip a required feature — a bare list-and-detail with none of its required features is the "half-built site" this is meant to prevent. (Purely presentational items — showing the author, the date — need no backend and belong to the Handoff's *Implementation checklist*, not here.) ## Aggregate Hold a `seeded` map in scratch — `seeded[] = { …kept IDs… }`. This is the producer for the handoff (`SDK_HANDOFF.md`), which inlines the IDs so the host can bind immediately. Whether to also write a sidecar file is a host-preference choice (default: return-only, in the handoff message). -On a per-capability error, keep the other capabilities' results and surface the failing recipe-call response verbatim; partial state is fine — a targeted re-run is bounded. +On a per-capability error, keep the other capabilities' results and surface the failing REST-call response verbatim; partial state is fine — a targeted re-run is bounded. ## Proceed to Handoff diff --git a/skills/sp-wix/references/SETUP.md b/skills/sp-wix/references/SETUP.md index 19d1de57..b630724a 100644 --- a/skills/sp-wix/references/SETUP.md +++ b/skills/sp-wix/references/SETUP.md @@ -8,13 +8,18 @@ Per `references/AUTHENTICATION.md` § "Minting the token" — one Bash call, sec ## 2 · Install one app per capability -For each capability in `verticals[]`, look up its `appDefId` in `references/CAPABILITIES.md`: +For each capability in `verticals[]`, install its app by `appDefId` (these are the constants the install call needs): - **stores** → `215238eb-22a5-4c36-9e7b-e7c08025e04e` - **blog** → `14bcded7-0066-7c35-14d7-466cb3f09103` - **forms** → `225dd912-7dea-4738-8688-4b8c6955ffc2` +- **events** → `140603ad-af8d-84a5-2c80-a0f60cb47351` +- **bookings** → `13d21c63-b5ec-5912-8397-c3a5ddb27a97` +- **pricing-plans** → `1522827f-c56c-a5c9-2ac9-00f9e6ae12d3` - **cms** → **no install** (Wix Data is core) — skip +For any vertical added later, its appDefId is in the docs — "Apps Created by Wix": . + Fire one install `curl` per app — `POST /apps-installer-service/v1/app-instance/install`: ```bash @@ -38,4 +43,4 @@ A **200** confirms the install. On a non-200, surface the response verbatim and ## 3 · Proceed to Seed -Confirm every required app returned 200 (cms skipped). Then continue to **`SEED.md`**, which loads the `wix-manage` recipes for content seeding. +Confirm every required app returned 200 (cms skipped). Then continue to **`SEED.md`**, which reads the live Wix REST docs for content seeding. From 339d65fa49187fdbd197c3ea5e891e21e6f31f32 Mon Sep 17 00:00:00 2001 From: Oz Sayag Date: Thu, 11 Jun 2026 13:21:18 +0300 Subject: [PATCH 4/4] fixes --- skills/sp-wix/SKILL.md | 9 ++--- ...STER_ORIGIN.md => DEPLOYMENT_CHECKLIST.md} | 35 +++++++++++++------ skills/sp-wix/references/SDK_HANDOFF.md | 10 +++--- skills/sp-wix/references/SEED.md | 6 +++- 4 files changed, 38 insertions(+), 22 deletions(-) rename skills/sp-wix/references/{REGISTER_ORIGIN.md => DEPLOYMENT_CHECKLIST.md} (56%) diff --git a/skills/sp-wix/SKILL.md b/skills/sp-wix/SKILL.md index 5e0221c2..d70e18de 100644 --- a/skills/sp-wix/SKILL.md +++ b/skills/sp-wix/SKILL.md @@ -3,11 +3,6 @@ name: sp-wix description: "Connect Wix business services (Stores, Blog, CMS, Forms, Events, Bookings, Pricing Plans) to a Stripe Projects app. Use AFTER `stripe projects add wix/*` has provisioned a Wix metasite + synced its credentials to `.env`. Given the metasite and the user's intent, this skill runs the Wix business flow — infers which Wix capabilities the app needs, installs the apps, seeds backend content — then returns an SDK-integration guide (how to call Wix from the frontend) for the host agent to use. The host keeps ownership of the frontend, the build, and the hosting. Triggers: set up Wix in this Stripe project, add a Wix store/blog/CMS/forms/events/bookings/pricing-plans backend, connect Wix Headless to my Stripe app, provision Wix content for this project, I added wix with stripe projects now wire it up. NOT for: building a new Wix-hosted site from scratch (use wix-headless), or anything outside a Stripe Projects app." allowed-tools: - Bash(curl *) - - Bash(ls *) - - Bash(cat *) - - Bash(grep *) - - Bash(head *) - - Bash(test *) - Read - Write --- @@ -34,7 +29,7 @@ When invoked, **run these four steps in order, start to finish.** Steps 1–3 ar 2. **Setup** (`references/SETUP.md`) — **install** the Wix apps those capabilities need on the metasite. 3. **Seed** (`references/SEED.md`) — **create** the backend content for each capability (products, posts, collections + items, forms). 4. **Handoff** (`references/SDK_HANDOFF.md`) — **only after Setup and Seed have run**, return the integration guide: the SDK bootstrap, per-capability call shapes, the **seeded IDs** (which exist only because Seed ran), and the `@wix/*` package list. -5. **Register origin** (`references/REGISTER_ORIGIN.md`) — **after the site is deployed**, register its URL on the OAuth app (the admin call `init` normally does for hosted sites). Do it **once per URL** (skip if already registered). If deployment isn't part of this flow, **flag to the user** that this step is required before the frontend can call Wix. +5. **Finalize deployment** (`references/DEPLOYMENT_CHECKLIST.md`) — **after the site is deployed**, run the two one-time backend steps: **publish the metasite** (always), and **register the deployed origin** on the OAuth app (the admin call `init` normally does for hosted sites; once per URL, skip if already registered). If deployment isn't part of this flow, **flag to the user** that the origin step is required before the frontend can call Wix. Steps 1–4 run in one pass; step 5 happens once the deployed URL exists (the skill performs it if it sees the deploy, otherwise flags the user). The guide in step 4 describes the backend that Setup and Seed built. Each Wix call uses a token minted from `.env` (`references/AUTHENTICATION.md`). The skill runs non-interactively, inferring from the user's words rather than asking. @@ -50,7 +45,7 @@ Compute `` from this file (`/SKILL.md` — strip `/SKILL | Setup (install apps) | `/references/SETUP.md` | | Seed (create backend content) | `/references/SEED.md` | | SDK-integration handoff (the returned document) | `/references/SDK_HANDOFF.md` | -| Register the deployed origin on the OAuth app (post-deploy) | `/references/REGISTER_ORIGIN.md` | +| Finalize deployment — publish the site + register the deployed origin (post-deploy) | `/references/DEPLOYMENT_CHECKLIST.md` | **Start a run by opening `DISCOVERY.md`.** diff --git a/skills/sp-wix/references/REGISTER_ORIGIN.md b/skills/sp-wix/references/DEPLOYMENT_CHECKLIST.md similarity index 56% rename from skills/sp-wix/references/REGISTER_ORIGIN.md rename to skills/sp-wix/references/DEPLOYMENT_CHECKLIST.md index 7bde30ad..0684b260 100644 --- a/skills/sp-wix/references/REGISTER_ORIGIN.md +++ b/skills/sp-wix/references/DEPLOYMENT_CHECKLIST.md @@ -1,14 +1,28 @@ -# Register the deployed origin on the OAuth app +# Deployment checklist — finalize the live site -For the frontend's visitor calls (`OAuthStrategy` with the public `clientId`) to be **accepted from the deployed site**, the site's origin must be on the OAuth app's allowed domains. Otherwise every browser SDK call from the live URL is rejected. +After the frontend is built and deployed, two one-time backend actions finalize the site. Both use the admin token from `.env` (`references/AUTHENTICATION.md`); run them once the deployed site is up. + +## 1 · Publish the Wix site + +**Always publish the metasite after deploying.** Some Wix-hosted flows the frontend relies on — redirects to Wix-hosted pages and other features served from the published site — only work once the site has been published. The skill doesn't track which seeded capabilities need it, and shouldn't: just publish every time, so a flow that needs it never silently fails on the live site. The call is idempotent and takes **no body**: + +```bash +set -a; . ./.env; set +a +TOKEN=$(cat /tmp/wix_token); SITE_ID="${WIX_WIX_METASITE_ID:-$WIX_METASITE_ID}" +curl -sS -w "\nHTTP_STATUS:%{http_code}" \ + -X POST "https://www.wixapis.com/site-publisher/v1/site/publish" \ + -H "Authorization: Bearer $TOKEN" -H "wix-site-id: $SITE_ID" \ + -H "Content-Type: application/json" -d '{}' +# 200 with an empty body `{}` means published — that 200 is the only success signal (no URL is returned). +``` -In regular `wix-headless` this is done by `init` — it knows the hosting URL up front and registers `localhost` + preview + prod domains on the OAuth app. **Here we don't own the hosting, so the deployed URL is unknown until the site is deployed.** That makes this a **post-deploy step the skill performs once the URL is known** — it can't be done during Setup/Seed. +## 2 · Register the deployed origin on the OAuth app -## When to run +For the frontend's visitor calls (`OAuthStrategy` with the public `clientId`) to be **accepted from the deployed site**, the site's origin must be on the OAuth app's allowed domains. Otherwise every browser SDK call from the live URL is rejected. -After the site is deployed and its URL is known. The OAuth app's id **is the clientId** — `WIX_WIX_CLIENT_ID`. Use the admin token from `.env` (`references/AUTHENTICATION.md`). +In regular `wix-headless` this is done by `init` — it knows the hosting URL up front and registers `localhost` + preview + prod domains on the OAuth app. **Here we don't own the hosting, so the deployed URL is unknown until the site is deployed.** That makes this a **post-deploy step the skill performs once the URL is known** — it can't be done during Setup/Seed. The OAuth app's id **is the clientId** — `WIX_WIX_CLIENT_ID`. -## Idempotent — register a given URL only once +### Idempotent — register a given URL only once First **read** the app's current allowed domains; if the deployed origin is already present, the registration is already done — **skip it**. Only ever add a URL that isn't there yet. @@ -21,7 +35,7 @@ curl -sS -w "\nHTTP_STATUS:%{http_code}" \ # → read oAuthApp.allowedRedirectDomains; if the deployed origin is already in it, you're done. ``` -## Add the deployed origin +### Add the deployed origin `PATCH` the app, sending the **existing** `allowedRedirectDomains` **plus** the new origin (the API replaces the field, so include what's already there), with a field mask: @@ -39,12 +53,13 @@ curl -sS -w "\nHTTP_STATUS:%{http_code}" -X PATCH \ - `` is the live site's domain/URL (what the browser SDK runs on). - For the **exact field semantics and format** (domain vs. full URL, member-login redirect URIs vs. allowed domains), read the doc — don't guess: . Member-login redirect URIs are a separate, deferred concern; the visitor SDK only needs the origin allowed. -- This call needs OAuth-app management permission on the app (same provider-side scope story as Setup/Seed); a non-200 here surfaces and stops, like any other Wix call. + +> **If the live site's visitor token call still 400s after the origin is registered, suspect the bundle — not CORS.** An unregistered origin and an `undefined` `clientId` in the build produce the same browser-side 400. Before chasing CORS/propagation, confirm the real `clientId` value is actually inlined in the deployed bundle (see `SDK_HANDOFF.md` §2). ## If deployment is NOT part of this agent flow -If the agent isn't the one deploying — the user will deploy the site themselves — the skill **cannot know the deployed URL**, so it cannot register the origin. **Flag this to the user clearly**, e.g.: +If the agent isn't the one deploying — the user will deploy the site themselves — the skill **cannot know the deployed URL**, so it cannot register the origin. (It can still publish the site — step 1 doesn't need the URL.) **Flag the origin step to the user clearly**, e.g.: > *"One required step remains before the frontend can talk to Wix: once your site is live, its URL must be registered on the Wix OAuth app (allowed domains). Give me the deployed URL — or re-run this skill with it — and I'll register it. Until then, Wix SDK calls from the live site will be rejected."* -This is the one piece `init` normally handles for hosted sites; because hosting is the host's, it has to be closed out here. +This is the piece `init` normally handles for hosted sites; because hosting is the host's, it has to be closed out here. diff --git a/skills/sp-wix/references/SDK_HANDOFF.md b/skills/sp-wix/references/SDK_HANDOFF.md index 9eb44e51..1042ad94 100644 --- a/skills/sp-wix/references/SDK_HANDOFF.md +++ b/skills/sp-wix/references/SDK_HANDOFF.md @@ -20,6 +20,8 @@ The frontend authenticates as an **anonymous visitor** via `OAuthStrategy`, with - - +> **Confirm the `clientId` reached the built bundle before deploying.** Public-env wiring fails silently — a mis-wired public var inlines as `undefined`, and then *every* visitor token call from the live site 400s with no other clue. After the production build, verify the **actual `clientId` value** is present in the built output (check that the value resolves — not merely that the variable *name* appears somewhere). Doing this pre-deploy stops it from being mistaken for an origin/CORS problem afterward. + ### 3 · Per-capability packages + API docs (package from the map; link for shapes) For each loaded capability, give the host the **package(s)** from the map below and the **SDK module doc link** — the current API shape, methods, and version live on that page; let the host read them there rather than snippeting. @@ -62,12 +64,12 @@ For each loaded capability, carry its **Required site features** and **Implement > - To get a menu page, truncate any URL to a parent path and append `.md` (e.g. `https://dev.wix.com/docs/sdk.md`, `https://dev.wix.com/docs/sdk/business-solutions.md`). > - Top-level index of all portals: > - Full concatenated docs: -> - Or use the `SearchWixSDKDocumentation` tool for a targeted lookup. +> - **Prefer `SearchWixSDKDocumentation` when the host exposes it.** Curling a module menu (e.g. `…/sdk/business-solutions/blog.md`) often surfaces only dashboard/extension pages, not the runtime query functions — `SearchWixSDKDocumentation "blog query posts"` returns the actual `posts.queryPosts`/`listPosts` shapes (with `?apiView=SDK` schema links) that the menu doesn't expose. Fall back to curling `.md` only when no MCP doc tool is present. -## One required step remains: register the deployed origin +## After deploy: publish the site and register the origin -The guide describes the backend, but the frontend's visitor calls will be **rejected from the live site until its origin is registered on the OAuth app** (the step `init` does for hosted sites; here the deployed URL is only known after deploy). So after deployment, register the origin per `references/REGISTER_ORIGIN.md` — once per URL. If deployment is out of this agent flow, tell the user plainly that this step is required before the frontend can call Wix (`REGISTER_ORIGIN.md` has the wording). +The guide describes the backend, but the frontend's visitor calls will be **rejected from the live site until its origin is registered on the OAuth app** (the step `init` does for hosted sites; here the deployed URL is only known after deploy). So after deployment, run `references/DEPLOYMENT_CHECKLIST.md` — **publish the metasite** and **register the origin** (once per URL). If deployment is out of this agent flow, tell the user plainly that the origin step is required before the frontend can call Wix (`DEPLOYMENT_CHECKLIST.md` has the wording). ## After emitting the document -Once the guide is emitted and the deployed origin is registered (or the user has been flagged), the skill's work is done. Close with a short plain-prose summary of what was set up (apps installed, content seeded per capability, origin registered or pending). What happens with the guide — installing packages, wiring components, choosing a framework — is the host's to decide. +Once the guide is emitted and the deployment checklist is done — site published, origin registered (or the user has been flagged) — the skill's work is done. Close with a short plain-prose summary of what was set up (apps installed, content seeded per capability, site published, origin registered or pending). What happens with the guide — installing packages, wiring components, choosing a framework — is the host's to decide. diff --git a/skills/sp-wix/references/SEED.md b/skills/sp-wix/references/SEED.md index 203aeac4..6a811e4e 100644 --- a/skills/sp-wix/references/SEED.md +++ b/skills/sp-wix/references/SEED.md @@ -8,7 +8,11 @@ The token is already in `/tmp/wix_token` from Setup. The capabilities are **inde Every Wix docs URL serves raw markdown when you append `.md` and `curl` it. A **menu page** lists links to child pages; a **content/method page** carries the endpoint, HTTP verb, and request/response schema. -**To learn how to seed a capability, start at its `Introduction` and continue from there:** +> **Prefer the Wix MCP doc tools when the host exposes them** (`SearchWixRESTDocumentation`, `SearchWixAPISpec`). They beat curling `.md` for two reasons: targeted search reaches the method without walking the menu, and `SearchWixAPISpec → getResourceSchema()` returns the **whole resource** (every method + the shared object schema) in one payload — so a requirement documented on a *sibling* method surfaces even when the method you're calling omits it. (Concretely: the blog **bulk**-create page never says 3rd-party apps must send a post-owner `memberId`, but the sibling **single**-create method does, and the resource view carries both — curling the isolated bulk `.md` page hides it.) **Fall back to curling `.md`** when no MCP doc tool is present. + +> **Look for the vertical's *recipe / flow* page first — before assembling raw method calls.** Most verticals publish opinionated, multi-step business recipes under a **`…/business-solutions//skills`** menu node (browse it with `BrowseWixRESTDocsMenu`, or `SearchWixRESTDocumentation " setup recipe"`). A recipe gives what per-method schemas can't: the **correct ordering**, the cross-step gotchas, and — critically — the **bundled endpoint** that does the whole job in one call, which the method index doesn't flag as the one to reach for. For **stores**, the *Setup Online Store* + *Bulk Create Products with Options* recipes specify `POST /stores/v3/bulk/products-with-inventory/create` — one call that creates each product **with its variants in-stock inline** (`inventoryItem.quantity`), plus `physicalProperties: {}` and "products before categories" ordering. (Reaching for bare `CreateProduct` instead leaves every product OUT_OF_STOCK and unbuyable, then needs a separate inventory-item create per variant — a flow the recipe sidesteps entirely.) If a recipe exists, follow it; drop to the per-method steps below only for shapes it leaves unpinned. + +**Otherwise — to find a capability's create method, start at its `Introduction` and continue from there:** 1. From the base index (§2), follow the link for the capability's vertical. 2. Open the vertical's **`Introduction`** (and any "About …" page) first — it orients you to the vertical's objects and the create flow, so you pick the *right* method instead of guessing a URL.