@wix/agent-skills 1.22.0 → 1.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/skills/wix-app/SKILL.md +12 -4
- package/skills/wix-app/references/APP_VALIDATION.md +16 -10
- package/skills/wix-app/references/EDITOR_REACT_COMPONENT.md +64 -50
- package/skills/wix-app/references/SDK_MODULE_MAP.md +2 -0
- package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE.md +1 -1
- package/skills/wix-app/references/editor-react-component/ACCESSIBILITY.md +4 -3
- package/skills/wix-app/references/editor-react-component/ANIMATED-COMPONENTS.md +28 -25
- package/skills/wix-app/references/editor-react-component/BRANDED-COMPONENTS.md +8 -2
- package/skills/wix-app/references/editor-react-component/COMPONENT-CONTRACT.md +12 -14
- package/skills/wix-app/references/editor-react-component/CSS-GUIDELINES.md +4 -3
- package/skills/wix-app/references/editor-react-component/DESIGN-STATES.md +66 -9
- package/skills/wix-app/references/editor-react-component/EDITOR-EXTENSION-CONFIGURATION.md +25 -0
- package/skills/wix-app/references/editor-react-component/OVERFLOW.md +146 -0
- package/skills/wix-app/references/editor-react-component/PARTS.md +6 -0
- package/skills/wix-app/scripts/scan-a11y-eslint.cjs +25 -1
- package/skills/{wix-headless-fast → wix-headless-kit}/SKILL.md +96 -50
- package/skills/{wix-headless-fast → wix-headless-kit}/cold-start/bootstrap.mjs +2 -2
- package/skills/{wix-headless-fast → wix-headless-kit}/cold-start/cold-start.md +26 -31
- package/skills/wix-headless-kit/guides/capabilities.md +76 -0
- package/skills/{wix-headless-fast → wix-headless-kit}/guides/existing-site.md +3 -1
- package/skills/wix-headless-kit/guides/feedback.md +98 -0
- package/skills/wix-headless-kit/guides/migration.md +54 -0
- package/skills/{wix-headless-fast → wix-headless-kit}/guides/reference-mode.md +4 -1
- package/skills/{wix-headless-fast → wix-headless-kit}/install/AGENTS.md +6 -1
- package/skills/{wix-headless-fast → wix-headless-kit}/install/agents-md.mjs +5 -1
- package/skills/{wix-headless-fast → wix-headless-kit}/install/attach.mjs +14 -1
- package/skills/wix-headless-kit/install/check.mjs +87 -0
- package/skills/wix-headless-kit/install/context.mjs +169 -0
- package/skills/{wix-headless-fast → wix-headless-kit}/install/deploy.mjs +101 -23
- package/skills/{wix-headless-fast → wix-headless-kit}/install/setup.mjs +115 -41
- package/skills/{wix-headless-fast → wix-headless-kit}/install/templates.mjs +1 -1
- package/skills/wix-manage/SKILL.md +3 -3
- package/skills/wix-manage/references/app-installation/install-wix-apps.md +68 -2
- package/skills/wix-manage/references/cms/cms-dashboard-navigation.md +2 -2
- package/skills/wix-manage/references/cms/cms-data-items-crud.md +16 -16
- package/skills/wix-manage/references/cms/cms-publishing-flow.md +15 -15
- package/skills/wix-manage/references/cms/cms-schema-management.md +6 -6
- package/skills/wix-manage/references/contacts/bulk-label-and-unlabel-contacts.md +37 -4
- package/skills/wix-manage/references/ecommerce/ecom-pricing.md +29 -3
- package/skills/wix-manage/references/sites/query-sites.md +1 -8
- package/skills/wix-manage/references/sites/site-import.md +101 -37
- package/skills/wix-auth/SKILL.md +0 -12
- package/skills/wix-auth/references/device-flow.md +0 -140
- /package/skills/{wix-headless-fast → wix-headless-kit}/install/lock.mjs +0 -0
|
@@ -37,7 +37,7 @@ curl -X GET \
|
|
|
37
37
|
|
|
38
38
|
## Get Collection Schema
|
|
39
39
|
|
|
40
|
-
**Endpoint**: `GET /wix-data/v2/collections/{collectionId}`
|
|
40
|
+
**Endpoint**: `GET https://www.wixapis.com/wix-data/v2/collections/{collectionId}`
|
|
41
41
|
|
|
42
42
|
```bash
|
|
43
43
|
curl -X GET \
|
|
@@ -47,7 +47,7 @@ curl -X GET \
|
|
|
47
47
|
|
|
48
48
|
## Create a New Collection
|
|
49
49
|
|
|
50
|
-
**Endpoint**: `POST /wix-data/v2/collections`
|
|
50
|
+
**Endpoint**: `POST https://www.wixapis.com/wix-data/v2/collections`
|
|
51
51
|
|
|
52
52
|
```json
|
|
53
53
|
{
|
|
@@ -72,7 +72,7 @@ curl -X GET \
|
|
|
72
72
|
|
|
73
73
|
## Add a Field to Existing Collection
|
|
74
74
|
|
|
75
|
-
**Endpoint**: `POST /wix-data/v2/collections/create-field`
|
|
75
|
+
**Endpoint**: `POST https://www.wixapis.com/wix-data/v2/collections/create-field`
|
|
76
76
|
|
|
77
77
|
```json
|
|
78
78
|
{
|
|
@@ -90,7 +90,7 @@ curl -X GET \
|
|
|
90
90
|
|
|
91
91
|
> **Warning**: This permanently deletes all data stored in this field across all items.
|
|
92
92
|
|
|
93
|
-
**Endpoint**: `POST /wix-data/v2/collections/delete-field`
|
|
93
|
+
**Endpoint**: `POST https://www.wixapis.com/wix-data/v2/collections/delete-field`
|
|
94
94
|
|
|
95
95
|
```json
|
|
96
96
|
{
|
|
@@ -101,7 +101,7 @@ curl -X GET \
|
|
|
101
101
|
|
|
102
102
|
## Update Collection Settings
|
|
103
103
|
|
|
104
|
-
**Endpoint**: `PATCH /wix-data/v2/collections/{collectionId}`
|
|
104
|
+
**Endpoint**: `PATCH https://www.wixapis.com/wix-data/v2/collections/{collectionId}`
|
|
105
105
|
|
|
106
106
|
```json
|
|
107
107
|
{
|
|
@@ -116,7 +116,7 @@ This works for `displayName`/`displayField`. **Permission updates currently fail
|
|
|
116
116
|
|
|
117
117
|
**To change permissions on an existing collection, use the full-replace endpoint instead** (`UpdateDataCollection`, not `PatchDataCollection`) — it requires the collection's current `revision` and full `fields` array (get both from a `GET` first), but it does work:
|
|
118
118
|
|
|
119
|
-
**Endpoint**: `PUT /wix-data/v2/collections`
|
|
119
|
+
**Endpoint**: `PUT https://www.wixapis.com/wix-data/v2/collections`
|
|
120
120
|
|
|
121
121
|
```json
|
|
122
122
|
{
|
|
@@ -1,12 +1,29 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: "Bulk Label and Unlabel Contacts"
|
|
3
|
-
description:
|
|
3
|
+
description: Creates contact label definitions or adds/removes labels from matching contacts. Use Find or Create Label for label creation alone; use bulk labeling only when the user requests contact assignments.
|
|
4
4
|
---
|
|
5
5
|
# Bulk Label And Unlabel Contacts
|
|
6
6
|
|
|
7
7
|
## Description
|
|
8
8
|
Adds and removes labels from multiple contacts using the Wix Contacts REST API.
|
|
9
9
|
|
|
10
|
+
## Create labels or assign labels?
|
|
11
|
+
|
|
12
|
+
If the user asks to **create a label** (for example, "Create VIP, Wholesale, and Newsletter labels"), use [Find or Create Label](https://dev.wix.com/docs/api-reference/crm/members-contacts/contacts/labels/find-or-create-label) directly. Creating a label definition does not require finding contacts or starting a bulk labeling job.
|
|
13
|
+
|
|
14
|
+
```http
|
|
15
|
+
POST https://www.wixapis.com/contacts/v4/labels
|
|
16
|
+
Content-Type: application/json
|
|
17
|
+
|
|
18
|
+
{"displayName":"VIP"}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Use the returned `label` and its `key`; `newLabel` distinguishes a newly created label from an existing one. For several names, make one call per name and check each result. Stop here when the request is only to create labels: do not assign them to contacts.
|
|
22
|
+
|
|
23
|
+
If the user asks to **label or unlabel contacts**, resolve the requested label keys first, then follow the bulk assignment flow below. Create a missing label only when that is part of the authorized request. An explicit request to create labels or apply them to a specified set of contacts authorizes that operation; otherwise confirm the target and intended change before mutating.
|
|
24
|
+
|
|
25
|
+
## Bulk assignment flow
|
|
26
|
+
|
|
10
27
|
Labels are added to and removed from all contacts that meet the specified `filter` and `search` criteria.
|
|
11
28
|
The request should specify a `filter` value, a `search` value, or both.
|
|
12
29
|
To perform a dry run, call [Query Contacts](https://dev.wix.com/docs/api-reference/crm/members-contacts/contacts/contacts/contact-v4/query-contacts) with the intended filter options.
|
|
@@ -17,6 +34,22 @@ The job's status can be retrieved with [Get Bulk Job](https://dev.wix.com/docs/a
|
|
|
17
34
|
|
|
18
35
|
**IMPORTANT NOTE:** When specific contacts are to be labeled, they should be filtered by id.
|
|
19
36
|
|
|
37
|
+
### Steps
|
|
38
|
+
|
|
39
|
+
1. **Resolve label keys.** When adding, Find or Create Label (above) returns the `key`. To remove a label, or to
|
|
40
|
+
use only a label that already exists, look it up by name instead of creating it:
|
|
41
|
+
`POST https://www.wixapis.com/contacts/v4/labels/query` with
|
|
42
|
+
`{"query":{"filter":{"displayName":{"$eq":"Newsletter"}}}}`, and take each returned label's `key`.
|
|
43
|
+
2. **Resolve named contacts to IDs** with Search Contacts, as in
|
|
44
|
+
[Update a Contact](update-a-contact.md) — Query Contacts cannot filter on a name:
|
|
45
|
+
`POST https://www.wixapis.com/contacts/v5/contacts/search` with `{"search":{"search":{"expression":"Leo Marsh"}}}`.
|
|
46
|
+
Each result in `contacts` has an `id` and `name.first` / `name.last`; keep only exact name matches. If none or
|
|
47
|
+
more than one contact matches, stop and ask the user.
|
|
48
|
+
3. **Start the job** with the endpoint below, filtering by the resolved IDs:
|
|
49
|
+
`{"filter":{"id":{"$in":["<CONTACT_ID>"]}},"labelKeysToAdd":["<LABEL_KEY>"]}` (or `labelKeysToRemove`).
|
|
50
|
+
4. **Confirm the job finished** with `GET https://www.wixapis.com/contacts/v4/bulk/jobs/{jobId}`; repeat until
|
|
51
|
+
`job.status` is `COMPLETED`, then report `job.successTotal` and `job.failedTotal`.
|
|
52
|
+
|
|
20
53
|
## API Endpoint
|
|
21
54
|
`POST https://www.wixapis.com/contacts/v4/bulk/contacts/add-remove-labels`
|
|
22
55
|
|
|
@@ -29,10 +62,10 @@ curl -X POST \
|
|
|
29
62
|
-H 'Content-Type: application/json' \
|
|
30
63
|
-d '{
|
|
31
64
|
"filter": {
|
|
32
|
-
"
|
|
65
|
+
"id": { "$in": ["<CONTACT_ID_1>", "<CONTACT_ID_2>"] }
|
|
33
66
|
},
|
|
34
|
-
"labelKeysToAdd": ["custom.
|
|
35
|
-
"labelKeysToRemove": ["custom.
|
|
67
|
+
"labelKeysToAdd": ["custom.newsletter"],
|
|
68
|
+
"labelKeysToRemove": ["custom.prospect"]
|
|
36
69
|
}'
|
|
37
70
|
```
|
|
38
71
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: "Pricing & Promotions"
|
|
3
|
-
description:
|
|
3
|
+
description: Routes discounts, coupons, sales and bundles to promotion recipes, and visual product ribbons to the Catalog Ribbons API. Load this dispatcher for mixed pricing/refund/payment/product-price/shipping requests to choose the appropriate APIs.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Pricing & Promotions
|
|
@@ -14,7 +14,9 @@ Discount rules, coupon codes, sales, ribbons, bundles, tiered pricing, and the s
|
|
|
14
14
|
- A standing $0 shipping option/region rate → see **Shipping & fulfillment**.
|
|
15
15
|
- Refunding a previous discounted order → route to verified Get Paid/payment docs or Dashboard guidance.
|
|
16
16
|
|
|
17
|
-
> **
|
|
17
|
+
> **Ribbon-only requests** — go directly to the ribbon path below; skip MerchantContext and promotion-strategy discovery.
|
|
18
|
+
>
|
|
19
|
+
> **Before dispatching promotion requests** — confirm MerchantContext is loaded. If `siteData.country` is not in your conversation context, load it via [Load Merchant Context](https://dev.wix.com/docs/api-reference/business-solutions/e-commerce/skills/e-commerce-load-context). Skip if already loaded.
|
|
18
20
|
>
|
|
19
21
|
> **Promotion dispatch.** Score each entry below by (a) the merchant's query → `intent:*` tags, (b) MerchantContext → context tags. Load the **highest-scoring** entry. Ties → highest `priority`. No match → follow the base recipe at the bottom.
|
|
20
22
|
>
|
|
@@ -24,9 +26,33 @@ Discount rules, coupon codes, sales, ribbons, bundles, tiered pricing, and the s
|
|
|
24
26
|
|
|
25
27
|
> - [Create coupon](https://dev.wix.com/docs/api-reference/business-solutions/e-commerce/skills/pricing-create-coupon) — tags: `[intent:create-coupon]` · priority 0
|
|
26
28
|
> - [Create discount rule (auto-apply)](https://dev.wix.com/docs/api-reference/business-solutions/e-commerce/skills/pricing-create-discount-rule) — tags: `[intent:create-discount-rule]` · priority 0
|
|
27
|
-
> - [
|
|
29
|
+
> - [Create or reuse a Catalog V3 ribbon](https://dev.wix.com/docs/api-reference/business-solutions/stores/catalog-v3/ribbons-v3/get-or-create-ribbon) — tags: `[intent:add-ribbon]` · priority 0 · *a ribbon is a visual product label, not a discount rule; follow the ribbon path below*
|
|
28
30
|
> - [Schedule a future sale](https://dev.wix.com/docs/api-reference/business-solutions/e-commerce/skills/pricing-create-discount-rule) — tags: `[intent:schedule-sale]` · priority 0 · *uses Discount Rules with `startTime` in the future*
|
|
29
31
|
|
|
32
|
+
### Ribbon path
|
|
33
|
+
|
|
34
|
+
For a Catalog V3 request such as "Create a Bestseller ribbon", use the idempotent name-based [Get or Create Ribbon](https://dev.wix.com/docs/api-reference/business-solutions/stores/catalog-v3/ribbons-v3/get-or-create-ribbon) method:
|
|
35
|
+
|
|
36
|
+
```http
|
|
37
|
+
POST https://www.wixapis.com/stores/v3/ribbons/get-or-create
|
|
38
|
+
Content-Type: application/json
|
|
39
|
+
|
|
40
|
+
{"ribbonName":"Bestseller"}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Read the returned `ribbon.id`. If the user requested only the ribbon definition, report that result and stop. If they also requested assignment to a product, read the product's current `revision` with `GET https://www.wixapis.com/stores/v3/products/{productId}`, as in [Update Product with Options](../stores/update-product-with-options.md). Then send only the ribbon with that `revision` through [Update Product](https://dev.wix.com/docs/api-reference/business-solutions/stores/catalog-v3/products-v3/update-product); fields you omit are left unchanged:
|
|
44
|
+
|
|
45
|
+
```http
|
|
46
|
+
PATCH https://www.wixapis.com/stores/v3/products/{productId}
|
|
47
|
+
Content-Type: application/json
|
|
48
|
+
|
|
49
|
+
{"product":{"id":"<PRODUCT_ID>","revision":"<CURRENT_REVISION>","ribbon":{"id":"<RIBBON_ID>"}}}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
This path covers Catalog V3.
|
|
53
|
+
|
|
54
|
+
Do not create a coupon, discount rule, or price change just because a ribbon says "Sale". Those require a separate discount request. An explicit ribbon creation or assignment request authorizes that operation; otherwise confirm the intended change first. Merchant context needed for promotion recommendations is not a prerequisite to creating a named visual ribbon.
|
|
55
|
+
|
|
30
56
|
### Business flows — the orchestrator
|
|
31
57
|
|
|
32
58
|
The single business-flow orchestrator (`recommend-ecommerce-strategy`) handles all strategic discount intents. It classifies internally (SEASONAL / UPSELL_BOOST / STOCK_MOVER / BUNDLE_AND_SAVE / ABANDONED_CART) and loads its `goal-*` / `flow-*` support files from the kept ecommerce-root siblings.
|
|
@@ -6,7 +6,7 @@ description: List, count, and find the sites in a Wix account. Covers the namesp
|
|
|
6
6
|
|
|
7
7
|
List, count, and find the sites in a Wix account.
|
|
8
8
|
|
|
9
|
-
- **Auth**: account-level (a Wix user token, or an account-level API key).
|
|
9
|
+
- **Auth**: account-level (a Wix user token, or an account-level API key).
|
|
10
10
|
- **Permission**: `SITE_LIST.READ` (scope `SCOPE.ACC-DC-OS.READ-SITE`).
|
|
11
11
|
- **Endpoints**: list `POST https://www.wixapis.com/site-list/v2/sites/query` · count
|
|
12
12
|
`POST https://www.wixapis.com/site-list/v2/sites/count`.
|
|
@@ -99,10 +99,3 @@ interface Site {
|
|
|
99
99
|
parentChildRole: string; // e.g. NONE
|
|
100
100
|
}
|
|
101
101
|
```
|
|
102
|
-
|
|
103
|
-
## Next Steps
|
|
104
|
-
|
|
105
|
-
Use a site's `id` for site-level API calls — derive a site token from the account token
|
|
106
|
-
(`wix token --site <id>`, or the `oauth2/token` refresh-grant in wix-auth `device-flow`), then read
|
|
107
|
-
its context via [Read Site Context](read-site-context.md) or create sites with
|
|
108
|
-
[Create Site from Template](create-site-from-template.md).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: "Site Import"
|
|
3
|
-
description: Drive the Wix Site Import agent to migrate an existing store or site from another platform (Shopify, WooCommerce, Magento, or any URL) into Wix
|
|
3
|
+
description: Drive the Wix Site Import agent to migrate an existing store or site from another platform (Shopify, WooCommerce, Magento, or any URL) into Wix — as a brand-new site or into the user's existing one — or to import from CSV/TSV export files with no source site. Use this skill whenever the user wants to import, migrate, or clone a store/site into Wix, mentions moving off Shopify/WooCommerce/Magento, or gives a source store URL and asks to bring it into Wix. Covers starting the import, polling progress, answering the agent's mid-import questions, handling deploy/failure/auth-expiry states, and sending post-deploy follow-up changes.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Site Import
|
|
@@ -24,8 +24,7 @@ and report the final result.
|
|
|
24
24
|
5. **This API is the only site-creation tool for this task** — never
|
|
25
25
|
substitute other Wix site-builder tools (see Scope).
|
|
26
26
|
|
|
27
|
-
Base URL: `https://www.wixapis.com/site-import`.
|
|
28
|
-
scope on the signed-in Wix user's account. A full import typically takes
|
|
27
|
+
Base URL: `https://www.wixapis.com/site-import`. A full import typically takes
|
|
29
28
|
15–60 minutes.
|
|
30
29
|
|
|
31
30
|
## Calling the API
|
|
@@ -46,11 +45,12 @@ nothing useful.
|
|
|
46
45
|
page, or any client-side code — those fail with CORS. The entire experience
|
|
47
46
|
is plain chat — API calls plus short messages.
|
|
48
47
|
|
|
49
|
-
Use the Wix
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
Use the Wix REST API tool available in your environment with the **full
|
|
49
|
+
URL** (account-level, or site-scoped with a target `siteId` — see Start
|
|
50
|
+
below for when each applies). Start, Send-a-message, and Cancel are mutating
|
|
51
|
+
(POST); Poll is read-only (GET).
|
|
52
52
|
|
|
53
|
-
Example — Start:
|
|
53
|
+
Example — Start, account-level (creates a new site):
|
|
54
54
|
|
|
55
55
|
```
|
|
56
56
|
POST https://www.wixapis.com/site-import/v1/imports
|
|
@@ -60,6 +60,19 @@ Body: {
|
|
|
60
60
|
}
|
|
61
61
|
```
|
|
62
62
|
|
|
63
|
+
Example — Start, site-scoped (imports into the user's existing site — same
|
|
64
|
+
body, plus a `wix-site-id` header naming the destination site; see the
|
|
65
|
+
Destination note under Start below):
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
POST https://www.wixapis.com/site-import/v1/imports
|
|
69
|
+
Headers: { "wix-site-id": "<destination siteId>" }
|
|
70
|
+
Body: {
|
|
71
|
+
"request": "Import https://example-store.com into my site",
|
|
72
|
+
"source_url": "https://example-store.com"
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
63
76
|
Example — Start from exported files (no source site, FILE run):
|
|
64
77
|
|
|
65
78
|
```
|
|
@@ -96,11 +109,10 @@ API. Never fall back to other site-building tools (site-builder/template/AI
|
|
|
96
109
|
site-generation tools) to "compensate" — not when the import is slow, and
|
|
97
110
|
especially not when it FAILS.
|
|
98
111
|
|
|
99
|
-
**Status comes ONLY from this API's Poll endpoint.** Never call
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
A failed import ends with a clear failure report and a full stop; the user
|
|
112
|
+
**Status comes ONLY from this API's Poll endpoint.** Never call another
|
|
113
|
+
site-building or site-creation capability to "check on the build" — some
|
|
114
|
+
such tools start a new site build on every call, even when asked only for
|
|
115
|
+
status. A failed import ends with a clear failure report and a full stop; the user
|
|
104
116
|
must never discover a different site in their account that they didn't ask
|
|
105
117
|
for. If an alternative makes sense, propose it AFTER reporting the failure
|
|
106
118
|
and act only on the user's explicit yes.
|
|
@@ -112,6 +124,17 @@ calling **Start**, confirm:
|
|
|
112
124
|
- The source URL and platform are correct — or, for a file-only import, the
|
|
113
125
|
export file URL(s) are correct
|
|
114
126
|
- The user understands it runs for up to ~60 minutes and may ask questions mid-way
|
|
127
|
+
- Which destination they want: a brand-new site, or their existing site by id
|
|
128
|
+
(site-scoped) — this can't be changed once Start is called. Importing into
|
|
129
|
+
an existing site writes into it directly and can add or overwrite its
|
|
130
|
+
current pages and content, so make sure they understand that before you
|
|
131
|
+
proceed — it isn't a safe side-by-side preview.
|
|
132
|
+
**If they want their existing site but haven't given a `siteId`, resolve
|
|
133
|
+
it yourself first** — from the account/site context already available to
|
|
134
|
+
you, or by querying the account's sites (see the Query Sites skill) — and
|
|
135
|
+
ask the user to pick when more than one candidate matches what they
|
|
136
|
+
described. Never guess a `siteId` or silently default to an account-level
|
|
137
|
+
call just because none was supplied.
|
|
115
138
|
|
|
116
139
|
Also confirm before calling **Cancel** — it's irreversible.
|
|
117
140
|
|
|
@@ -183,14 +206,34 @@ You are the user experience; the API is plumbing. Keep the protocol invisible:
|
|
|
183
206
|
`request`, and no `fileUrls`, is rejected with `SITE_UNIDENTIFIED`.
|
|
184
207
|
Returns: `importId`, `sourcePlatform`, `sourceConfidence`, `destinationSiteId`.
|
|
185
208
|
`sourcePlatform` comes back as `CSV` for a FILE run (no site was probed, so
|
|
186
|
-
`sourceConfidence` is meaningless there).
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
209
|
+
`sourceConfidence` is meaningless there).
|
|
210
|
+
**Destination (new site vs. an existing site) is decided by call scope, not
|
|
211
|
+
a body field:** account-level (no site context) always creates a brand-new
|
|
212
|
+
site — the default when the user has none yet or wants a fresh one;
|
|
213
|
+
site-scoped (adding a `wix-site-id: <siteId>` header, same body — see the
|
|
214
|
+
examples above) writes into that existing site instead. Ask the user which
|
|
215
|
+
they want before calling Start — it can't change afterward. Get this
|
|
216
|
+
wrong at Start and you'll silently create an unwanted second site instead
|
|
217
|
+
of writing into the one they meant. Once Start has scoped the import,
|
|
218
|
+
keep sending that same `wix-site-id` header on every later call for that
|
|
219
|
+
`importId` (Poll, Send-a-message, Cancel included) — it won't create
|
|
220
|
+
another site at this point, but omitting it will fail authorization
|
|
221
|
+
against the site-scoped import. `destinationSiteId` in the
|
|
222
|
+
response echoes this (empty = new site, set = that existing site), returned
|
|
223
|
+
as soon as Start succeeds, even before a source is confirmed.
|
|
224
|
+
**One import per store at a time, keyed on `source_url` (or the file set
|
|
225
|
+
when there's no `source_url`) together with call scope** — account-level
|
|
226
|
+
and a given `wix-site-id` are different keys even for the identical
|
|
227
|
+
`source_url`/file set: re-starting with the same identity (same source
|
|
228
|
+
AND same scope) continues the SAME migration (server returns the
|
|
229
|
+
existing `importId`, no new import created). A different identity —
|
|
230
|
+
a different source, a different file set, or the same source at a
|
|
231
|
+
*different* call scope — always starts an independent migration, even
|
|
232
|
+
for the same user. This is why getting the scope wrong at Start matters
|
|
233
|
+
(see above): re-calling Start with the corrected scope does not fix the
|
|
234
|
+
original import, it starts a second, independent one. To redo a
|
|
235
|
+
mis-scoped import, **Cancel it first**, then Start again with the
|
|
236
|
+
correct scope. If a different user on the account already owns an
|
|
194
237
|
import for that identity, Start returns
|
|
195
238
|
`409 { "code": "IMPORT_IN_PROGRESS" }` — tell the user and stop.
|
|
196
239
|
|
|
@@ -238,7 +281,9 @@ You are the user experience; the API is plumbing. Keep the protocol invisible:
|
|
|
238
281
|
- `FAILED` — terminal. Relay `message` in plain words.
|
|
239
282
|
- `AUTH_EXPIRED` — recoverable, NOT success, nothing is live (golden rule 1).
|
|
240
283
|
Tell the user the connection to their account expired and you're restarting,
|
|
241
|
-
then call Start again with the same request
|
|
284
|
+
then call Start again with the same request, using the same call scope
|
|
285
|
+
(account-level, or the same `wix-site-id`) as the original Start — work so
|
|
286
|
+
far is preserved.
|
|
242
287
|
- `CANCELLED` — terminal.
|
|
243
288
|
- **Anything the user says mid-import goes straight to Send-a-message** — no
|
|
244
289
|
need to wait for `NEEDS_INPUT`.
|
|
@@ -269,26 +314,45 @@ the user has no way to open a file.
|
|
|
269
314
|
- Never invent a `deployUrl` — only report the one returned with `DEPLOYED`.
|
|
270
315
|
- Treat `NEEDS_INPUT` and `AUTH_EXPIRED` as normal conversation turns, not
|
|
271
316
|
errors.
|
|
272
|
-
- **Site Import is in
|
|
273
|
-
|
|
274
|
-
|
|
317
|
+
- **Site Import is in closed beta, with no self-service enablement path.**
|
|
318
|
+
A `"code": "NOT_ENABLED"` on a `401`, `403`, or `404` from Start always means this
|
|
319
|
+
account isn't in the beta — whether the call was account-level or
|
|
320
|
+
site-scoped. The code isn't always present on an **account-level** call:
|
|
321
|
+
a not-yet-enrolled account's Start has been observed to come back as a
|
|
322
|
+
plain `401`/`403` (`{"message": "The caller is not permitted to perform this
|
|
323
|
+
action."}`, no code) as well as a plain `404` — treat any of those shapes there
|
|
324
|
+
as the beta-lockout case too. Don't probe other endpoints to diagnose it,
|
|
325
|
+
don't retry, and **don't create a site through any other site-building
|
|
326
|
+
capability to compensate — creating a site through a different path is
|
|
327
|
+
not a workaround here, it's the specific mistake this rule exists to
|
|
328
|
+
prevent.** Tell the user plainly and warmly that Site Import is
|
|
329
|
+
currently in a closed beta, that you'd be happy to help once they're
|
|
330
|
+
in, and that they can request access by filling out this short form:
|
|
331
|
+
https://forms.gle/RfZqVRtGCsPv7U7M6 — the team will follow up. Then
|
|
332
|
+
stop, having created nothing.
|
|
275
333
|
**Do not tell them to "contact Wix support"**: this API is unlisted and
|
|
276
334
|
ALPHA, Wix Support has no visibility into it or way to grant access, and the
|
|
277
335
|
public "importing a site created outside of Wix" help-center article is an
|
|
278
336
|
unrelated, long-stalled feature-request page — sending a user to either is a
|
|
279
|
-
dead end.
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
337
|
+
dead end. The form above is the only channel that reaches the team.
|
|
338
|
+
**A `401`, `403`, or `404` on a site-scoped call *without* `"code": "NOT_ENABLED"`
|
|
339
|
+
is different** — it means the caller isn't authorized for that `siteId`
|
|
340
|
+
(wrong id, wrong account, no access), not a beta-enrollment issue. Tell
|
|
341
|
+
the user the destination site isn't accessible with their current
|
|
342
|
+
connection and stop; don't send them to the beta form for this.
|
|
343
|
+
- For any other unrecognized error or exception on Start — a transient server
|
|
344
|
+
error, a timeout, a rate limit, or anything that isn't the closed-beta case
|
|
345
|
+
above or one of the specific cases below — don't guess that it's a
|
|
346
|
+
beta-enrollment issue and don't retry silently. Tell the user the import
|
|
347
|
+
couldn't be started, share what went wrong in plain language, and stop.
|
|
348
|
+
- A `400` on Start means a required field is missing (`request`/`message`
|
|
349
|
+
must be 1–20000 chars), `source_url` exceeds 2048 chars, or `fileUrls` has
|
|
350
|
+
more than 20 entries or one over 2048 chars. A request with no identifiable
|
|
351
|
+
site (no `source_url` and no URL in `request`) and no `fileUrls` is rejected
|
|
352
|
+
with `SITE_UNIDENTIFIED` — ask the user for the store URL or export file(s)
|
|
353
|
+
and retry. A `fileUrls` entry that isn't a reachable http/https URL rejects
|
|
354
|
+
the whole call with `INVALID_FILE_URL` — tell the user which link failed and
|
|
355
|
+
ask for a working one.
|
|
292
356
|
- Requesting an unknown id in `artifactIds` is silently ignored — not an error.
|
|
293
357
|
A document simply may not exist yet on an earlier turn.
|
|
294
358
|
- **The user cannot open files.** If a message mentions a document by filename,
|
package/skills/wix-auth/SKILL.md
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: wix-auth
|
|
3
|
-
description: "Authenticate with Wix to obtain an access token for calling Wix APIs. Use when an agent needs a valid Wix access token and has none, or when the stored token is expired."
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Wix Auth
|
|
7
|
-
|
|
8
|
-
Wix supports multiple authentication flows. This skill currently covers:
|
|
9
|
-
|
|
10
|
-
- [Device Flow](references/device-flow.md) — interactive login via browser, no client secret required. Use when the agent is acting on behalf of a logged-in Wix user.
|
|
11
|
-
|
|
12
|
-
Other flows (OAuth authorization code, API key) are documented at [https://www.wix.com/skills/docs](https://www.wix.com/skills/docs).
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
# Device Flow
|
|
2
|
-
|
|
3
|
-
Implements the OAuth 2.0 Device Authorization Grant (RFC 8628). The user approves in a browser while the agent polls for tokens.
|
|
4
|
-
|
|
5
|
-
Produces two kinds of token:
|
|
6
|
-
- **Account token** — works for account-level APIs (e.g. list sites). Expires in ~4 hours.
|
|
7
|
-
- **Site token** — required for any site-specific API (contacts, products, bookings, …). Derived on demand from the account `refreshToken` + a `siteId`. Expires in ~15 minutes.
|
|
8
|
-
|
|
9
|
-
## Constants
|
|
10
|
-
|
|
11
|
-
```
|
|
12
|
-
BASE_URL = https://manage.wix.com
|
|
13
|
-
CLIENT_ID = 6f95cec8-3e98-48b9-b4e5-1fb92fcd9973
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
Required headers on every request:
|
|
17
|
-
|
|
18
|
-
```
|
|
19
|
-
X-XSRF-TOKEN: nocheck
|
|
20
|
-
Cookie: XSRF-TOKEN=nocheck
|
|
21
|
-
User-Agent: wix-cli
|
|
22
|
-
Content-Type: application/json (on POST requests)
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
## Step 1 — Request a device code
|
|
26
|
-
|
|
27
|
-
```
|
|
28
|
-
GET /oauth2/device/code?clientId=CLIENT_ID
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
Response:
|
|
32
|
-
|
|
33
|
-
```json
|
|
34
|
-
{ "deviceCode": "…", "userCode": "XXXXXXXX", "verificationUri": "https://users.wix.com/login/device-login", "expiresIn": 600 }
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
## Step 2 — Ask the user to authorize
|
|
38
|
-
|
|
39
|
-
Show the user this URL and code:
|
|
40
|
-
|
|
41
|
-
```
|
|
42
|
-
URL: {verificationUri}?color=developer&studio=true
|
|
43
|
-
Code: {userCode}
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
Make sure the user has copied or noted the code **before** opening the link — they'll need to enter it on the page. Present the URL as a clickable link that opens in a new tab if your interface supports it.
|
|
47
|
-
|
|
48
|
-
## Step 3 — Poll for the token
|
|
49
|
-
|
|
50
|
-
Every 3 seconds, POST:
|
|
51
|
-
|
|
52
|
-
```
|
|
53
|
-
POST /oauth2/token
|
|
54
|
-
{ "clientId": "CLIENT_ID", "grantType": "urn:ietf:params:oauth:grant-type:device_code", "scope": "offline_access", "deviceCode": "{deviceCode}" }
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
- While waiting: server returns `400` with `{ "error": "authorization_pending" }` or `{ "message": "Device code is not yet verified" }` — keep polling.
|
|
58
|
-
- On approval: `200` with `{ "access_token": "…", "refresh_token": "…", "expires_in": 14400 }`.
|
|
59
|
-
- Stop polling after `expiresIn` seconds total.
|
|
60
|
-
|
|
61
|
-
## Step 4 — Fetch user info
|
|
62
|
-
|
|
63
|
-
```
|
|
64
|
-
GET /_serverless/wix-cli-userinfo/userinfo
|
|
65
|
-
Authorization: Bearer {access_token}
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
Response: `{ "userId": "…", "email": "…" }`
|
|
69
|
-
|
|
70
|
-
## Step 5 — Persist
|
|
71
|
-
|
|
72
|
-
At this point you already hold all the values in memory — store them securely to whatever credential store your platform provides (file, secrets manager, environment variables, etc.), without asking the user to enter them manually. **Treat these as secrets: never print them in the conversation, never include them in logs, and never send them to any service other than the Wix APIs.**
|
|
73
|
-
|
|
74
|
-
```
|
|
75
|
-
accessToken string
|
|
76
|
-
refreshToken string
|
|
77
|
-
expiresIn number (seconds)
|
|
78
|
-
issuedAt number (Unix timestamp in seconds, recorded at the moment tokens were received)
|
|
79
|
-
userInfo { userId, email }
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
## Getting a valid token on subsequent calls
|
|
83
|
-
|
|
84
|
-
**Account token**
|
|
85
|
-
|
|
86
|
-
1. Load stored credentials. If missing → run the device flow above.
|
|
87
|
-
2. Check validity: `issuedAt + expiresIn - 600 > now` (10-min buffer).
|
|
88
|
-
3. If expired → refresh silently:
|
|
89
|
-
|
|
90
|
-
```
|
|
91
|
-
POST /oauth2/token
|
|
92
|
-
{ "clientId": "CLIENT_ID", "grantType": "refresh_token", "refreshToken": "{refreshToken}" }
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
Same response shape as Step 3. Persist the new tokens with a fresh `issuedAt`.
|
|
96
|
-
|
|
97
|
-
4. If refresh returns `400 invalid_grant` → session revoked; run the device flow again.
|
|
98
|
-
|
|
99
|
-
**Site token**
|
|
100
|
-
|
|
101
|
-
The account token returns `403` on site-level endpoints. Derive a site token on demand:
|
|
102
|
-
|
|
103
|
-
```
|
|
104
|
-
POST /oauth2/token
|
|
105
|
-
{ "clientId": "CLIENT_ID", "grantType": "refresh_token", "refreshToken": "{refreshToken}", "siteId": "{siteId}" }
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
Response: `{ "access_token": "…", "refresh_token": "…", "expires_in": 900 }`
|
|
109
|
-
|
|
110
|
-
Re-derive on each use rather than caching — it expires in 15 minutes.
|
|
111
|
-
|
|
112
|
-
## Examples
|
|
113
|
-
|
|
114
|
-
**List sites (account token)**
|
|
115
|
-
|
|
116
|
-
```
|
|
117
|
-
POST https://www.wixapis.com/site-list/v2/sites/query
|
|
118
|
-
Authorization: Bearer {accountToken}
|
|
119
|
-
{ "query": { "filter": { "namespace": { "$in": ["WIX", "HEADLESS"] } }, "cursorPaging": { "limit": 100 } } }
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
Returns `{ sites: [{ id, displayName, namespace, … }] }` — the `id` is the `siteId` for site-scoped calls.
|
|
123
|
-
|
|
124
|
-
> Without the `namespace` filter, headless sites are silently excluded from results.
|
|
125
|
-
|
|
126
|
-
**List contacts (site token)**
|
|
127
|
-
|
|
128
|
-
```
|
|
129
|
-
POST https://www.wixapis.com/contacts/v4/contacts/query
|
|
130
|
-
Authorization: Bearer {siteToken}
|
|
131
|
-
{ "query": { "paging": { "limit": 10 } } }
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
Returns `{ contacts: […] }`.
|
|
135
|
-
|
|
136
|
-
---
|
|
137
|
-
|
|
138
|
-
For the full Wix REST API reference — endpoints, request/response shapes, and field details — see [https://www.wix.com/skills/docs](https://www.wix.com/skills/docs).
|
|
139
|
-
|
|
140
|
-
For REST API recipes covering common management operations (stores, bookings, contacts, CMS, and more) — see [https://www.wix.com/skills/manage](https://www.wix.com/skills/manage).
|
|
File without changes
|