@wix/agent-skills 1.16.1 → 1.16.2
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 +72 -8
- package/skills/wix-app/references/CODE_QUALITY.md +0 -1
- package/skills/wix-app/references/DASHBOARD_MODAL.md +21 -14
- package/skills/wix-app/references/DASHBOARD_PAGE.md +30 -184
- package/skills/wix-app/references/EDITOR_REACT_COMPONENT.md +1 -0
- package/skills/wix-app/references/WIX_PATTERNS_DOCS.md +172 -0
- package/skills/wix-app/references/dashboard-page/WDS_LAYOUT.md +187 -0
- package/skills/wix-app/references/editor-react-component/ANIMATED-COMPONENTS.md +31 -2
- package/skills/wix-app/references/editor-react-component/COMPONENT-API.md +6 -1
- package/skills/wix-app/references/editor-react-component/FUNCTION-HANDLERS.md +167 -0
- package/skills/wix-app/references/editor-react-component/REACT-GUIDELINES.md +2 -2
- package/skills/wix-base44-connector/SKILL.md +185 -0
- package/skills/wix-base44-connector/scripts/utils.js +212 -0
- package/skills/wix-design-system/SKILL.md +19 -15
- package/skills/wix-docs/SKILL.md +75 -1
- package/skills/wix-manage/SKILL.md +12 -16
- package/skills/wix-manage/references/domains/domain-search-purchase-and-connect.md +2603 -0
- package/skills/wix-manage/references/events/create-wix-event.md +112 -90
- package/skills/wix-manage/references/events/manage-wix-events.md +33 -94
- package/skills/wix-manage/references/sites/create-headless-site.md +1 -0
- package/skills/wix-manage/references/sites/manage-oauth-apps.md +154 -0
- package/skills/wix-manage/references/sites/read-site-context.md +125 -0
- package/skills/wix-manage/references/stores/create-product-catalog-v3.md +273 -0
- package/skills/wix-vibe-headless/install/deploy.cjs +1 -2
- package/skills/wix-vibe-headless/platforms/base44-ecom-light-seed.md +104 -0
- package/skills/wix-vibe-headless/platforms/base44-ecom-light.md +74 -0
- package/skills/wix-vibe-headless/platforms/base44.md +3 -3
- package/skills/wix-vibe-headless/references/blog/seed/SEED.md +1 -1
- package/skills/wix-vibe-headless/references/bookings/seed/SEED.md +1 -1
- package/skills/wix-vibe-headless/references/events/seed/SEED.md +1 -1
- package/skills/wix-vibe-headless/references/portfolio/seed/SEED.md +1 -1
- package/skills/wix-vibe-headless/references/pricing-plans/seed/SEED.md +1 -1
- package/skills/wix-vibe-headless/references/restaurants/seed/SEED.md +1 -1
- package/skills/wix-vibe-headless/references/storefront/INSTRUCTIONS.md +68 -2
- package/skills/wix-vibe-headless/references/storefront/app/components/ProductCard.jsx +29 -86
- package/skills/wix-vibe-headless/references/storefront/app/components/ProductGrid.jsx +3 -8
- package/skills/wix-vibe-headless/references/storefront/app/components/VariantPicker.jsx +78 -105
- package/skills/wix-vibe-headless/references/storefront/app/hooks/useProductCard.js +92 -0
- package/skills/wix-vibe-headless/references/storefront/app/hooks/useVariantOptions.js +76 -0
- package/skills/wix-vibe-headless/references/storefront/seed/SEED.md +1 -1
- package/skills/wix-app/references/AUTO_PATTERNS_DASHBOARD.md +0 -326
- package/skills/wix-app/references/auto-patterns-dashboard/action-cell.md +0 -115
- package/skills/wix-app/references/auto-patterns-dashboard/app-config-structure.md +0 -264
- package/skills/wix-app/references/auto-patterns-dashboard/app-context.md +0 -37
- package/skills/wix-app/references/auto-patterns-dashboard/bulk-actions.md +0 -86
- package/skills/wix-app/references/auto-patterns-dashboard/collection-page-actions.md +0 -119
- package/skills/wix-app/references/auto-patterns-dashboard/collection-page.md +0 -103
- package/skills/wix-app/references/auto-patterns-dashboard/custom-actions-override.md +0 -76
- package/skills/wix-app/references/auto-patterns-dashboard/custom-columns-override.md +0 -82
- package/skills/wix-app/references/auto-patterns-dashboard/custom-components-override.md +0 -89
- package/skills/wix-app/references/auto-patterns-dashboard/custom-header-override.md +0 -124
- package/skills/wix-app/references/auto-patterns-dashboard/custom-sections-override.md +0 -91
- package/skills/wix-app/references/auto-patterns-dashboard/custom-slots-override.md +0 -71
- package/skills/wix-app/references/auto-patterns-dashboard/entity-page-actions.md +0 -70
- package/skills/wix-app/references/auto-patterns-dashboard/entity-page-view-actions.md +0 -73
- package/skills/wix-app/references/auto-patterns-dashboard/entity-page.md +0 -98
- package/skills/wix-app/references/auto-patterns-dashboard/example-patterns.json +0 -278
- package/skills/wix-app/references/auto-patterns-dashboard/pages-configuration.md +0 -94
- package/skills/wix-app/references/auto-patterns-dashboard/resolved-action.md +0 -43
- package/skills/wix-app/references/auto-patterns-dashboard/sdk-utilities.md +0 -66
- package/skills/wix-app/references/auto-patterns-dashboard/views.md +0 -76
- package/skills/wix-app/scripts/generate-auto-patterns.js +0 -510
- package/skills/wix-manage/references/domains/domain-search-and-purchase.md +0 -437
- package/skills/wix-manage/references/stores/create-product-from-image.md +0 -1031
- package/skills/wix-manage/references/stores/create-product-with-options-catalog-v3.md +0 -623
- package/skills/wix-manage/references/stores/setup-online-store-catalog-v3.md +0 -106
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: wix-base44-connector
|
|
3
|
+
description: "Build on Wix from the Base44 builder sandbox — this file is the complete guide (site context, doc discovery, API contracts, who calls Wix from where), and scripts/utils.js is its helper module, loaded from disk per exec. Triggers: build a Base44 app on a connected Wix site, look up a Wix API from the sandbox, decide frontend vs backend for a Wix call."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Building on Wix from Base44
|
|
7
|
+
|
|
8
|
+
The Wix connector is connected; this is how the app gets built on it — gather the site's context,
|
|
9
|
+
find the APIs and learn their contracts from the docs, write the code. **Discover everything**: endpoints, paths, doc URLs,
|
|
10
|
+
request and response fields all come from the calls below, never from memory or pattern. 404 or
|
|
11
|
+
empty ⇒ discover, not permute. Examples teach mechanics and go stale — verify before relying.
|
|
12
|
+
|
|
13
|
+
## What are you building?
|
|
14
|
+
|
|
15
|
+
The app's audience picks the token, and the token picks the architecture: the **visitor token is
|
|
16
|
+
public** — anyone can mint it from the site's `clientId` — and the **admin token is a secret**,
|
|
17
|
+
the connector's, server-side only.
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
browser ──(visitor token)─► wixapis.com the visitor's own reads & actions
|
|
21
|
+
base44/functions/* ──(admin token)───► wixapis.com work that needs the owner's identity
|
|
22
|
+
exec_tool ──(admin token)───► wixapis.com you: ad hoc probing/managing while building
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**A site for visitors** — storefront, blog, booking. Headless means the Wix site has no pages of
|
|
26
|
+
its own: your app IS its frontend. **The complete visitor experience —
|
|
27
|
+
every page, every read, every action a visitor takes — is browser calls on the visitor token;
|
|
28
|
+
none of it needs a backend function.** Public reads
|
|
29
|
+
included (the visitor token queries the catalog directly), and `carts/current/*` + checkout act
|
|
30
|
+
on the CALLER's cart, so only the visitor token reaches the visitor's cart. One file carries it
|
|
31
|
+
all: `src/lib/wixClient.js` (Write the code, below). `base44/functions/*` appear only where work
|
|
32
|
+
needs the owner's identity — elevated-permission ops a visitor triggers, webhooks, scheduled
|
|
33
|
+
jobs — and for the app's non-Wix backend.
|
|
34
|
+
|
|
35
|
+
**An admin tool for the owner** — dashboard, back office. The pages act as the owner, whose token
|
|
36
|
+
is a secret: `pages → base44/functions/* ──(admin token)──► wixapis.com`.
|
|
37
|
+
|
|
38
|
+
## The helpers
|
|
39
|
+
|
|
40
|
+
Research and probing run in exec_tool, and one loader opens every exec (execs share no state —
|
|
41
|
+
reload each round; the module lives on disk next to this file, network only as first-touch
|
|
42
|
+
fallback):
|
|
43
|
+
|
|
44
|
+
```js
|
|
45
|
+
const fs = require("fs"), P = ".agents/skills/wix-base44-connector/utils.js";
|
|
46
|
+
if (!fs.existsSync(P)) { fs.mkdirSync(".agents/skills/wix-base44-connector", { recursive: true });
|
|
47
|
+
fs.writeFileSync(P, await (await fetch("https://www.wix.com/skills/wix-base44-connector/scripts/utils.js")).text()); }
|
|
48
|
+
const wx = (() => { const m = { exports: {} };
|
|
49
|
+
new Function("module", "exports", "require", fs.readFileSync(P, "utf8"))(m, m.exports, require); return m.exports; })();
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Results ≤ 4,000 chars come back inline (exec results clip at ~5,000); anything bigger is saved
|
|
53
|
+
under `.agents/skills/wix-base44-connector/scratch/` and returns `{ path, bytes, lines, outline }` —
|
|
54
|
+
the outline is the map. Read a saved file the way you already know how:
|
|
55
|
+
`wx.bash("grep -n 'term' <path> | head -40")` to find (GNU grep/sed, awk is mawk, no rg;
|
|
56
|
+
across everything saved: `grep -rn 'term' .agents/skills/wix-base44-connector/scratch/`), and
|
|
57
|
+
`read_file` to quote — a window via `offset`/`limit` at the lines grep named, or the whole
|
|
58
|
+
file when it fits read_file's 45K cap. **API responses are site data and never land in
|
|
59
|
+
scratch** — project them to facts. Fetch every URL inside exec with `fetch()` — website/browser
|
|
60
|
+
tools clip at 10,000 chars silently. One exec per round; timeout 10s, up to 120 via `{timeout}`.
|
|
61
|
+
|
|
62
|
+
## Gather context — the dynamic context report
|
|
63
|
+
|
|
64
|
+
```js
|
|
65
|
+
const { accessToken } = await base44.asServiceRole.connectors.getConnection("wix");
|
|
66
|
+
return await wx.context(accessToken, "Apps"); // no section arg → the report's outline
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
One report: installed apps **with ids** (incl. Stores' catalog version — V1 vs V3 decides its
|
|
70
|
+
endpoints), the OAuth app id (**also the visitor `clientId`**), locale, currency, CMS collections.
|
|
71
|
+
An empty report = bad token, never an empty site.
|
|
72
|
+
|
|
73
|
+
## Learn Wix — find the APIs, learn their contracts
|
|
74
|
+
|
|
75
|
+
```js
|
|
76
|
+
// know the product? browse is deterministic — menuUrl alone orients (children + counts);
|
|
77
|
+
// filter before listing methods, unfiltered listings clip
|
|
78
|
+
await wx.browse("https://dev.wix.com/docs/api-reference/business-solutions/bookings/bookings",
|
|
79
|
+
{ include: ["METHOD"], filter: "resched", depth: 4 });
|
|
80
|
+
|
|
81
|
+
// don't know where it lives? search ranks, never says "no match" — drop wrong-product hits
|
|
82
|
+
await wx.search("pause a pricing plan subscription and resume it");
|
|
83
|
+
// → { hits: [{ method, endpoint /* callable */, docsUrl, gist }] } — hits often ARE the answer
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Go deeper for fields, enums, or absence — only the spec index proves absence.
|
|
87
|
+
|
|
88
|
+
### Read a doc page
|
|
89
|
+
|
|
90
|
+
Method pages are 100 KB+, twin REST and SDK halves repeating field names at different types —
|
|
91
|
+
map and window in the SAME exec; coordinates are for your code, not for a second round:
|
|
92
|
+
|
|
93
|
+
```js
|
|
94
|
+
const pg = await wx.page(docsUrl); // whole text when small; else { path, bytes, lines, outline }
|
|
95
|
+
// your half, windowed to your term and its Examples (a complete working request — URL, headers,
|
|
96
|
+
// body — usually all you need), one round:
|
|
97
|
+
return wx.bash(`sed -n '/^## REST API/,/^## JavaScript SDK/p' ${pg.path} | grep -B5 -A40 -i 'examples\\|<term>' | head -c 3800`);
|
|
98
|
+
// a giant fenced example → its field vocabulary instead of paging it:
|
|
99
|
+
// wx.bash(`sed -n '<a>,<b>p' ${pg.path} | grep -oE '"[a-zA-Z]+":' | sort -u | head -60`)
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
`search` also saves its raw content beside the inline hits — grep its `path` when a hit's six
|
|
103
|
+
lines weren't enough.
|
|
104
|
+
|
|
105
|
+
### The spec index
|
|
106
|
+
|
|
107
|
+
Answers questions about pages you already found — arrive with a `docsUrl`, match by it. Also the
|
|
108
|
+
only proof an API does NOT exist:
|
|
109
|
+
|
|
110
|
+
```js
|
|
111
|
+
await wx.spec(`
|
|
112
|
+
const r = lightIndex.find(x => x.docsUrl === "<docsUrl from browse/search>");
|
|
113
|
+
return r.methods.map(m => ({ op: m.operationId.split(".").pop(), verb: m.httpMethod,
|
|
114
|
+
call: m.publicUrl })); // publicUrl is callable — path is PARTIAL
|
|
115
|
+
`);
|
|
116
|
+
// request fields next round: getResourceSchemaByUrl(docsUrl) →
|
|
117
|
+
// m.requestBody.content["application/json"].schema.properties — names and types, drill deeper
|
|
118
|
+
// per round; $circular stubs resolve via s.components.schemas["<name>"]
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Management recipes — check before composing admin flows
|
|
122
|
+
|
|
123
|
+
~100 curated multi-step recipes (install apps, seed catalogs, set up whole verticals):
|
|
124
|
+
|
|
125
|
+
```js
|
|
126
|
+
await wx.recipes(); // categories with counts
|
|
127
|
+
await wx.recipes("stores"); // a category's list — or any task word: wx.recipes("coupon")
|
|
128
|
+
await wx.page(url); // read the chosen recipe — whole when small, saved + outline when
|
|
129
|
+
// big; then grep / read_file windows by the outline's line numbers
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
A matching recipe beats composing the flow from single endpoints: it carries ordering and
|
|
133
|
+
cross-step gotchas no method page mentions.
|
|
134
|
+
|
|
135
|
+
## Write the code
|
|
136
|
+
|
|
137
|
+
**Response shapes obey the discover rule in every lane**: code against fields you saw in a live
|
|
138
|
+
response or the schema — remembered names are often from older versions. Probe one real row first.
|
|
139
|
+
|
|
140
|
+
### Admin calls — exec ad hoc, backend functions deployed
|
|
141
|
+
|
|
142
|
+
```js
|
|
143
|
+
const { accessToken } = await base44.asServiceRole.connectors.getConnection("wix");
|
|
144
|
+
const data = await wx.post("https://www.wixapis.com/contacts/v5/contacts/query", // spec-index publicUrl
|
|
145
|
+
{ query: { cursorPaging: { limit: 10 } } }, accessToken);
|
|
146
|
+
// let it throw — the thrown message is your result; .catch hides the answer
|
|
147
|
+
return wx.clip({ error: null, count: data.contacts?.length, first: data.contacts?.[0] });
|
|
148
|
+
// ↑ one real row, whole — the shapes you code against live here, not in key names
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
The same call deploys as `base44/functions/*` (work the app does as the owner) — shipped code
|
|
152
|
+
carries its own four-line fetch; the helpers are a build tool, not a runtime dependency.
|
|
153
|
+
|
|
154
|
+
### A visitor client — src/lib/wixClient.js
|
|
155
|
+
|
|
156
|
+
The "site for visitors" shape (What are you building?), in code — one file pages import. Neither
|
|
157
|
+
`clientId` (from the context report) nor the minted token is a secret; together they are "an
|
|
158
|
+
anonymous visitor", safe in shipped code:
|
|
159
|
+
|
|
160
|
+
```js
|
|
161
|
+
// src/lib/wixClient.js
|
|
162
|
+
let token;
|
|
163
|
+
const mint = async (body) => {
|
|
164
|
+
const r = await (await fetch("https://www.wixapis.com/oauth2/token", { method: "POST",
|
|
165
|
+
headers: { "Content-Type": "application/json" }, body: JSON.stringify(body) })).json();
|
|
166
|
+
token = r.access_token; sessionStorage.setItem("wixRefresh", r.refresh_token); // expires_in: 14400s = 4h
|
|
167
|
+
};
|
|
168
|
+
// first visit: mint({ clientId: WIX_CLIENT_ID, grantType: "anonymous" });
|
|
169
|
+
// on expiry: mint({ refreshToken: sessionStorage.getItem("wixRefresh"), grantType: "refresh_token" });
|
|
170
|
+
// a fresh anonymous mint is a NEW visitor — the old one's cart goes with it
|
|
171
|
+
export const wix = (path, opts = {}) => fetch("https://www.wixapis.com" + path, { ...opts,
|
|
172
|
+
headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" } });
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Token contract: `…/headless/authentication/retrieve-tokens`. Prove the lane in one exec before
|
|
176
|
+
writing pages — mint a visitor, make one public read with it:
|
|
177
|
+
|
|
178
|
+
```js
|
|
179
|
+
const { access_token } = await wx.post("https://www.wixapis.com/oauth2/token",
|
|
180
|
+
{ clientId: WIX_CLIENT_ID, grantType: "anonymous" }); // clientId: from the context report
|
|
181
|
+
return await wx.post("<a public read from Learn Wix>", { query: {} }, access_token);
|
|
182
|
+
// 200 ⇒ every visitor-facing page in the app is this same call, no server between
|
|
183
|
+
// a lean default response isn't the whole shape — contracts often define a fields param
|
|
184
|
+
// that opts INTO heavier parts (formatted prices, media); read the contract for it
|
|
185
|
+
```
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
// Wix docs helpers for the Base44 sandbox — the scratch-lane set. Small results return
|
|
2
|
+
// inline; anything over ~4,000 chars (exec results clip at ~5,000) is saved under the
|
|
3
|
+
// scratch dir and comes back as { path, bytes, lines, outline } with the read tools
|
|
4
|
+
// pre-pointed at it.
|
|
5
|
+
//
|
|
6
|
+
// Load per exec (execs share no state) — from disk, network only as first-touch fallback:
|
|
7
|
+
// const fs = require("fs"), P = ".agents/skills/wix-base44-connector/utils.js";
|
|
8
|
+
// if (!fs.existsSync(P)) { fs.mkdirSync(".agents/skills/wix-base44-connector", { recursive: true });
|
|
9
|
+
// fs.writeFileSync(P, await (await fetch("https://www.wix.com/skills/wix-base44-connector/scripts/utils.js")).text()); }
|
|
10
|
+
// const wx = (() => { const m = { exports: {} };
|
|
11
|
+
// new Function("module", "exports", "require", fs.readFileSync(P, "utf8"))(m, m.exports, require); return m.exports; })();
|
|
12
|
+
//
|
|
13
|
+
// Read a saved file the way you already know how: wx.bash("grep -n 'term' <path> | head -40")
|
|
14
|
+
// to find, read_file(<path>) with offset/limit to window (numbered lines, 45K cap — no exec
|
|
15
|
+
// round needed), pipelines for the rest (GNU grep/sed; awk is mawk; no rg).
|
|
16
|
+
//
|
|
17
|
+
// API responses are site data and stay OUT of scratch (scratch ships with the app):
|
|
18
|
+
// post() never saves — project responses to facts.
|
|
19
|
+
|
|
20
|
+
const fs = require("fs");
|
|
21
|
+
const path = require("path");
|
|
22
|
+
|
|
23
|
+
const BUDGET = 4000;
|
|
24
|
+
const SCRATCH = ".agents/skills/wix-base44-connector/scratch";
|
|
25
|
+
|
|
26
|
+
const clip = (out) => {
|
|
27
|
+
if (typeof out === "string")
|
|
28
|
+
return out.length <= BUDGET ? out : { truncated: true, total: out.length, head: out.slice(0, BUDGET) };
|
|
29
|
+
// absence must be visible: JSON.stringify silently ERASES undefined keys, so a probe like
|
|
30
|
+
// { lineItems: resp.cart?.lineItems } loses the very field that proves the call failed —
|
|
31
|
+
// render undefined as null instead
|
|
32
|
+
const s = JSON.stringify(out, (k, v) => v === undefined ? null : v);
|
|
33
|
+
return s.length <= BUDGET ? JSON.parse(s) : { truncated: true, total: s.length, head: s.slice(0, BUDGET) };
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// One transport for every JSON call — Content-Type, optional Bearer, ok-guard.
|
|
37
|
+
// Admin calls are this with the connector token: post(publicUrl, body, accessToken).
|
|
38
|
+
async function post(url, body, token) {
|
|
39
|
+
const r = await fetch(url, { method: "POST", body: JSON.stringify(body),
|
|
40
|
+
headers: { "Content-Type": "application/json", ...(token && { Authorization: `Bearer ${token}` }) } });
|
|
41
|
+
if (!r.ok) {
|
|
42
|
+
const head = (await r.text()).slice(0, 300);
|
|
43
|
+
throw new Error(r.status + " " + head + (r.status < 500
|
|
44
|
+
? " — a 4xx means wrong body or reference: read this endpoint's contract before changing the call"
|
|
45
|
+
: ""));
|
|
46
|
+
}
|
|
47
|
+
return r.json();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function save(name, text) {
|
|
51
|
+
const dir = path.join(process.cwd(), SCRATCH);
|
|
52
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
53
|
+
fs.writeFileSync(path.join(dir, name), text);
|
|
54
|
+
return { path: SCRATCH + "/" + name, bytes: Buffer.byteLength(text), lines: text.split("\n").length };
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const outlineOf = (lines, cap = 30) => {
|
|
58
|
+
const heads = [];
|
|
59
|
+
lines.forEach((t, i) => { if (/^#{1,3} /.test(t)) heads.push({ line: i + 1, text: t.trim().slice(0, 80) }); });
|
|
60
|
+
return { outline: heads.slice(0, cap), outlineOmitted: Math.max(0, heads.length - cap) };
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
// A ref is a scratch path or the URL it came from — resolve to lines, fetching+saving
|
|
64
|
+
// URLs on first touch (the .md suffix is appended for extensionless docs URLs).
|
|
65
|
+
const slugOf = (url) => url.replace(/\?.*$/, "").split("/").pop().replace(/\.md$/, "") + ".md";
|
|
66
|
+
async function resolveRef(ref) {
|
|
67
|
+
const isUrl = /^https?:/.test(ref);
|
|
68
|
+
const name = isUrl ? slugOf(ref) : ref.split("/").pop();
|
|
69
|
+
const file = path.join(process.cwd(), SCRATCH, name);
|
|
70
|
+
if (fs.existsSync(file)) return { path: SCRATCH + "/" + name, lines: fs.readFileSync(file, "utf8").split("\n") };
|
|
71
|
+
if (!isUrl) throw new Error("no such scratch file: " + ref + " — pass a returned path or the source URL");
|
|
72
|
+
const mdUrl = /\.[a-z]{2,5}$/.test(ref.replace(/\?.*$/, "")) ? ref : ref.replace(/\?.*$/, "") + ".md";
|
|
73
|
+
const res = await fetch(mdUrl);
|
|
74
|
+
if (!res.ok) throw new Error(res.status + " on " + mdUrl + " — not a docs page; take URLs from output, don't compose");
|
|
75
|
+
const text = await res.text();
|
|
76
|
+
const saved = save(name, text);
|
|
77
|
+
return { path: saved.path, lines: text.split("\n") };
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// ── gather context ────────────────────────────────────────────────────────────
|
|
81
|
+
|
|
82
|
+
// The dynamic context report — site data, never saved. No section → the whole report
|
|
83
|
+
// when it fits, else its header outline; with one → that section's text. Empty
|
|
84
|
+
// report = bad token, never an empty site.
|
|
85
|
+
async function context(token, section) {
|
|
86
|
+
const { markdown } = await post(
|
|
87
|
+
"https://www.wixapis.com/_api/dynamic-context/v1/dynamic-context/markdown", {}, token);
|
|
88
|
+
if (!section) {
|
|
89
|
+
if (markdown.length <= BUDGET) return markdown; // most sites: the whole report, one round
|
|
90
|
+
return { truncated: true, total: markdown.length, head: markdown.slice(0, BUDGET),
|
|
91
|
+
note: "site data — never saved (no path); narrow: wx.context(token, '<section name>')" };
|
|
92
|
+
}
|
|
93
|
+
const m = markdown.match(new RegExp("^#{1,3} .*" + section + "[\\s\\S]*?(?=\\n#{1,3} |$)", "im"));
|
|
94
|
+
return clip({ total: markdown.length, section: m ? m[0] : "not found — call context(token) for the outline" });
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// ── find what to read ─────────────────────────────────────────────────────────
|
|
98
|
+
|
|
99
|
+
// Browse the docs tree — deterministic. menuUrl alone orients (children + counts);
|
|
100
|
+
// filter before listing methods. An oversized listing is saved with its outline.
|
|
101
|
+
async function browse(menuUrl, { include, filter, depth } = {}) {
|
|
102
|
+
const { content } = await post("https://www.wixapis.com/mcp-docs-search/v1/docs/menu/browse", {
|
|
103
|
+
menu_url: menuUrl, ...(include && { include }),
|
|
104
|
+
...(filter && { name_filter: filter }), ...(depth && { depth }),
|
|
105
|
+
}); // 404 "No menu node found" ⇒ re-orient a level up
|
|
106
|
+
if (content.length <= BUDGET) return content;
|
|
107
|
+
const s = save("browse-" + (menuUrl.replace(/\/+$/, "").split("/").pop() || "root") + ".md", content);
|
|
108
|
+
return { ...s, next: `wx.bash("grep -in 'term' ${s.path} | head -40") // one line per node — or re-browse with a filter` };
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Semantic search — ranks, never says "no match". The reduced hits come back inline
|
|
112
|
+
// AND the full raw content is saved for grep/window follow-ups.
|
|
113
|
+
async function search(term, { type = "REST", max = 5, lines = 6 } = {}) {
|
|
114
|
+
const { content } = await post("https://www.wixapis.com/mcp-docs-search/v1/docs/search/markdown",
|
|
115
|
+
{ search_term: term, document_type: type, maximum_results: max, lines_in_each_result: lines });
|
|
116
|
+
const hits = content.split(/\n---\n+(?=#### )/).map(b => ({
|
|
117
|
+
method: (b.match(/^# Method: (.+)$/m) || [])[1],
|
|
118
|
+
endpoint: (b.match(/^# Method API Endpoint: (.+)$/m) || [])[1], // callable
|
|
119
|
+
docsUrl: (b.match(/#### \[[^\]]+\]\((https:[^)]+)\)/) || [])[1],
|
|
120
|
+
gist: ((b.match(/## Method Description:\s*\n([\s\S]{0,400})/) || [])[1] || "")
|
|
121
|
+
.trim().replace(/\s+/g, " ").slice(0, 220),
|
|
122
|
+
})).filter(h => h.docsUrl);
|
|
123
|
+
const saved = save("search-" + term.toLowerCase().replace(/[^a-z0-9]+/g, "-").slice(0, 40) + ".md", content);
|
|
124
|
+
if (!hits.length) return clip({ ...saved, head: content.slice(0, 1200),
|
|
125
|
+
note: `no method blocks parsed — raw head above; wx.bash("grep -in 'term' ${saved.path}") for the rest` });
|
|
126
|
+
return clip({ ...saved, hits });
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// ── read a page (docs pages and recipes alike) ────────────────────────────────
|
|
130
|
+
|
|
131
|
+
// Fetch + save + map in one round: whole text inline when small, else
|
|
132
|
+
// { path, bytes, lines, outline } — the outline's line numbers feed grep and read_file windows.
|
|
133
|
+
async function page(url) {
|
|
134
|
+
const { path: p, lines } = await resolveRef(url);
|
|
135
|
+
const text = lines.join("\n");
|
|
136
|
+
if (text.length <= BUDGET) return text;
|
|
137
|
+
const o = outlineOf(lines);
|
|
138
|
+
const bytes = Buffer.byteLength(text);
|
|
139
|
+
return { path: p, bytes, lines: lines.length, ...o,
|
|
140
|
+
next: [
|
|
141
|
+
`wx.bash("grep -in 'term' ${p} | head -40")`,
|
|
142
|
+
bytes <= 45000 ? `read_file ${p} // whole (fits the 45K cap), or a window via offset/limit`
|
|
143
|
+
: `read_file ${p} with offset/limit // window a section by the outline's lines`,
|
|
144
|
+
] };
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// ── shell ─────────────────────────────────────────────────────────────────────
|
|
148
|
+
|
|
149
|
+
// Compose native pipelines over scratch — grep -n, sed -n, mawk, sort, uniq, wc
|
|
150
|
+
// (GNU grep/sed; awk is mawk; no rg). Cap your own output (| head -40); the return
|
|
151
|
+
// clips regardless. grep's exit 1 means no match, not failure — the return says so.
|
|
152
|
+
function bash(cmd) {
|
|
153
|
+
const { execSync } = require("child_process");
|
|
154
|
+
try {
|
|
155
|
+
const out = execSync(cmd, { timeout: 15000, encoding: "utf8", maxBuffer: 8 * 1024 * 1024 });
|
|
156
|
+
return out.trim() ? clip(out)
|
|
157
|
+
: "(no output — a filter may have swallowed the signal; rerun without the reducer)";
|
|
158
|
+
} catch (e) {
|
|
159
|
+
const exit = e.status ?? null, err = (e.stderr || "").toString().trim();
|
|
160
|
+
return { exit, ...(err && { err: err.slice(0, 300) }),
|
|
161
|
+
out: clip((e.stdout || "").toString()),
|
|
162
|
+
...(exit === 1 && !err && { note: "exit 1 with no stderr — a no-match, not a failure" }) };
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// ── the spec index ────────────────────────────────────────────────────────────
|
|
167
|
+
|
|
168
|
+
// Run a query over the API spec index. In scope: lightIndex (RESOURCES with
|
|
169
|
+
// .methods — operationId, summary, httpMethod, path [PARTIAL — never call it],
|
|
170
|
+
// publicUrl [callable], docsUrl) and getResourceSchemaByUrl(docsUrl). Arrive with
|
|
171
|
+
// a docsUrl and match by it — also the only proof an API does NOT exist.
|
|
172
|
+
// A big result is saved as JSON; grep it for the keys you saw in its head.
|
|
173
|
+
async function spec(code) {
|
|
174
|
+
if (!/^\s*async function/.test(code)) code = `async function(){ ${code} }`;
|
|
175
|
+
const { result } = await post("https://mcp.wix.com/api/code-mode/search", { code });
|
|
176
|
+
if (result == null || (Array.isArray(result) && !result.length))
|
|
177
|
+
return { result, note: "empty — the query missed the shape, not proof of absence; find the resource by docsUrl on lightIndex" };
|
|
178
|
+
const text = JSON.stringify(result, null, 1);
|
|
179
|
+
if (text.length <= BUDGET) return result;
|
|
180
|
+
return { ...save("spec.json", text),
|
|
181
|
+
shape: Array.isArray(result) ? `Array(${result.length})` : Object.keys(result || {}).slice(0, 15),
|
|
182
|
+
head: text.slice(0, 600) };
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// ── management recipes ────────────────────────────────────────────────────────
|
|
186
|
+
|
|
187
|
+
// ~100 curated multi-step admin flows. No arg → categories with counts; a category
|
|
188
|
+
// name → its recipes; any other term → search every recipe's name + gist for it.
|
|
189
|
+
// Read the chosen url with page(url), then grep/window/fields.
|
|
190
|
+
async function recipes(q) {
|
|
191
|
+
const { base, files } = await (await fetch("https://dev.wix.com/docs/skills/manage.manifest.json")).json();
|
|
192
|
+
const cat = f => (f.path.match(/^references\/([^/]+)\//) || [])[1];
|
|
193
|
+
const row = f => ({ name: f.name, cat: cat(f), gist: (f.description || "").slice(0, 120),
|
|
194
|
+
url: base + f.path, kb: Math.round(f.size / 1024) });
|
|
195
|
+
if (!q) {
|
|
196
|
+
const cats = {};
|
|
197
|
+
for (const f of files) { const c = cat(f); if (c) cats[c] = (cats[c] || 0) + 1; }
|
|
198
|
+
return cats;
|
|
199
|
+
}
|
|
200
|
+
const inCat = files.filter(f => cat(f) === q);
|
|
201
|
+
if (inCat.length) return clip(inCat.map(row));
|
|
202
|
+
const re = new RegExp(q, "i");
|
|
203
|
+
const m = files.filter(f => re.test(f.name + " " + (f.description || "")));
|
|
204
|
+
if (!m.length) {
|
|
205
|
+
const cats = {};
|
|
206
|
+
for (const f of files) { const c = cat(f); if (c) cats[c] = (cats[c] || 0) + 1; }
|
|
207
|
+
return { note: `nothing matches "${q}" — the categories:`, categories: cats };
|
|
208
|
+
}
|
|
209
|
+
return clip(m.map(row));
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
module.exports = { post, clip, context, browse, search, page, bash, spec, recipes };
|
|
@@ -95,27 +95,27 @@ Don't read these files fully. Grep for keywords, then read specific sections wit
|
|
|
95
95
|
|
|
96
96
|
## Quick Component Mapping (Design to WDS)
|
|
97
97
|
|
|
98
|
-
| Design Element
|
|
99
|
-
|
|
|
100
|
-
| Rectangle/container | `<Box>`
|
|
101
|
-
| Text button
|
|
102
|
-
| Input with label
|
|
103
|
-
| Toggle
|
|
104
|
-
| Modal
|
|
105
|
-
| Grid
|
|
98
|
+
| Design Element | WDS Component | Notes |
|
|
99
|
+
| ------------------- | --------------------------------- | ----------------- |
|
|
100
|
+
| Rectangle/container | `<Box>` | Layout wrapper |
|
|
101
|
+
| Text button | `<TextButton>` | Secondary actions |
|
|
102
|
+
| Input with label | `<FormField>` + `<Input>` | Wrap inputs |
|
|
103
|
+
| Toggle | `<ToggleSwitch>` | On/off settings |
|
|
104
|
+
| Modal | `<Modal>` + `<CustomModalLayout>` | Use together |
|
|
105
|
+
| Grid | `<Layout>` + `<Cell>` | Responsive |
|
|
106
106
|
|
|
107
107
|
## Spacing (px to SP conversion)
|
|
108
108
|
|
|
109
109
|
When designer specifies pixels, convert to the nearest SP token:
|
|
110
110
|
|
|
111
111
|
| Token | Classic | Studio |
|
|
112
|
-
|
|
|
113
|
-
| `SP1` | 6px
|
|
114
|
-
| `SP2` | 12px
|
|
115
|
-
| `SP3` | 18px
|
|
116
|
-
| `SP4` | 24px
|
|
117
|
-
| `SP5` | 30px
|
|
118
|
-
| `SP6` | 36px
|
|
112
|
+
| ----- | ------- | ------ |
|
|
113
|
+
| `SP1` | 6px | 4px |
|
|
114
|
+
| `SP2` | 12px | 8px |
|
|
115
|
+
| `SP3` | 18px | 12px |
|
|
116
|
+
| `SP4` | 24px | 16px |
|
|
117
|
+
| `SP5` | 30px | 20px |
|
|
118
|
+
| `SP6` | 36px | 24px |
|
|
119
119
|
|
|
120
120
|
```tsx
|
|
121
121
|
<Box gap="SP2" padding="SP3">
|
|
@@ -130,6 +130,10 @@ import { Button, Card, Image } from "@wix/design-system";
|
|
|
130
130
|
import { Add, Edit, Delete } from "@wix/wix-ui-icons-common";
|
|
131
131
|
```
|
|
132
132
|
|
|
133
|
+
## GUIDELINES
|
|
134
|
+
|
|
135
|
+
1. Don't ever override WDS CSS tokens. Only if it's not possible otherwise, mention that very clearly to the prompter, that this is an anti-pattern and should be avoided at all costs.
|
|
136
|
+
|
|
133
137
|
### Troubleshooting
|
|
134
138
|
|
|
135
139
|
- **Components render unstyled** (plain HTML look, missing WDS spacing/typography): add `import "@wix/design-system/styles.global.css";` once to the root/main component (e.g. `page.tsx`, modal entry) — not child/tab/helper files.
|
package/skills/wix-docs/SKILL.md
CHANGED
|
@@ -7,7 +7,8 @@ description: "Look up the Wix API/SDK documentation to confirm an exact endpoint
|
|
|
7
7
|
|
|
8
8
|
Get the **exact** truth about a Wix API — endpoint, HTTP method, request/response body, a field, an
|
|
9
9
|
enum, or an error. **Never invent a Wix endpoint, path, body, or enum from memory** — confirm it
|
|
10
|
-
here first.
|
|
10
|
+
here first. That includes the example endpoints in this skill: they illustrate the mechanics and
|
|
11
|
+
go stale like any snapshot — discover the real contract before you rely on one.
|
|
11
12
|
|
|
12
13
|
A lookup is a short flow: **find the right page, then read it.** Do it with `curl` (default, below)
|
|
13
14
|
or the Wix MCP doc tools if your agent has them (Lane 2).
|
|
@@ -212,6 +213,79 @@ when present, fall back to Lane 1 when not. Optional — skip this lane if the t
|
|
|
212
213
|
Append `.md` only when `curl`-ing a page directly. The MCP tools and the search endpoint take the
|
|
213
214
|
plain docs URL **without** `.md` — never feed a `.md` URL to an MCP tool.
|
|
214
215
|
|
|
216
|
+
## From docs to calls
|
|
217
|
+
|
|
218
|
+
The contract you just read runs under one of two identities — and which one a call wants is part
|
|
219
|
+
of what you read:
|
|
220
|
+
|
|
221
|
+
| identity | token | for |
|
|
222
|
+
|---|---|---|
|
|
223
|
+
| **admin** | an admin token (API key, connector, or OAuth-app admin grant) | managing the site — ad hoc calls, or the same fetch inside an app's backend function |
|
|
224
|
+
| **visitor** | minted from the site's OAuth app, in frontend code | everything the site's end user does — storefront reads, cart, checkout |
|
|
225
|
+
|
|
226
|
+
**Admin** — any management or read call, straight from its docs contract:
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
curl -sS -X POST 'https://www.wixapis.com/contacts/v5/contacts/query' \
|
|
230
|
+
-H "Authorization: Bearer $ADMIN_TOKEN" -H 'Content-Type: application/json' \
|
|
231
|
+
--data-raw '{"query": {"cursorPaging": {"limit": 10}}}'
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
In a Wix CLI project, the CLI mints `$ADMIN_TOKEN` — at either scope:
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
TOKEN=$(npx @wix/cli@latest token --site "$SITE_ID") # site-scoped: this one site's APIs
|
|
238
|
+
TOKEN=$(npx @wix/cli@latest token) # account-scoped: account-level APIs (list sites, …)
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Mint once per run and cache it — within a run the CLI returns a byte-identical token, so re-minting
|
|
242
|
+
only spends startup time.
|
|
243
|
+
|
|
244
|
+
**Visitor — minted from the OAuth app's client id.** The client id is a public value, and it is
|
|
245
|
+
usually already on disk before it is in any API: in a managed headless project it is the `appId`
|
|
246
|
+
field of `wix.config.json` — **the OAuth app id and the client id are the same value** — so read it
|
|
247
|
+
from the project's config instead of querying the OAuth-apps API for it. The mint is one
|
|
248
|
+
unauthenticated call, so it belongs in the site's own frontend code:
|
|
249
|
+
|
|
250
|
+
```bash
|
|
251
|
+
curl -sS -X POST 'https://www.wixapis.com/oauth2/token' \
|
|
252
|
+
-H 'Content-Type: application/json' \
|
|
253
|
+
--data-raw '{"clientId": "<oauth app client id>", "grantType": "anonymous"}'
|
|
254
|
+
# → { "access_token": "OauthNG.JWS.…", … } — bearer for products, cart, checkout
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
The cart and checkout APIs act on the *caller's* identity, so they want the visitor token — the
|
|
258
|
+
admin token is for managing the site, the visitor token is for being on it.
|
|
259
|
+
|
|
260
|
+
The authentication docs (append `.md` to read):
|
|
261
|
+
|
|
262
|
+
- [`about-identities`](https://dev.wix.com/docs/api-reference/articles/authentication/about-identities) — the identity model
|
|
263
|
+
- [`rest-api-authentication`](https://dev.wix.com/docs/api-reference/articles/authentication/rest-api-authentication) — headers, token kinds
|
|
264
|
+
- [`retrieve-tokens`](https://dev.wix.com/docs/api-reference/business-management/headless/authentication/retrieve-tokens) — the `/oauth2/token` contract, all grant types
|
|
265
|
+
- [`about-authentication`](https://dev.wix.com/docs/go-headless/authentication/about-authentication) — visitor vs member sessions
|
|
266
|
+
- [`create-an-oauth-app-for-visitors-and-members`](https://dev.wix.com/docs/go-headless/getting-started/setup/authentication/create-an-oauth-app-for-visitors-and-members) — where the client id comes from
|
|
267
|
+
- [`set-up-a-headless-client`](https://dev.wix.com/docs/go-headless/authentication/setup/set-up-a-headless-client) — wiring the client
|
|
268
|
+
|
|
269
|
+
## Special APIs worth knowing
|
|
270
|
+
|
|
271
|
+
**Dynamic Site Context — "what IS this site?"** One admin call returns a markdown report of the
|
|
272
|
+
whole site — installed apps, status, URL, locale, CMS collections — the same output the Wix MCP's
|
|
273
|
+
site-context tool renders:
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
curl -sS -X POST 'https://www.wixapis.com/_api/dynamic-context/v1/dynamic-context/markdown' \
|
|
277
|
+
-H "Authorization: Bearer $ADMIN_TOKEN" -H 'Content-Type: application/json' \
|
|
278
|
+
--data-raw '{"siteId": "<metasite id>"}' | jq -r '.markdown'
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
A `200` with `"markdown": ""` means the token or `siteId` is wrong — the endpoint reports an empty
|
|
282
|
+
context instead of an auth error, so treat empty as "check auth", never as "empty site".
|
|
283
|
+
|
|
284
|
+
For site management, the **`wix-manage`** skill carries per-area recipes. It may already be
|
|
285
|
+
installed at
|
|
286
|
+
`.agents/skills/wix-manage/`; install it with `npx -y skills add wix/skills/skills/wix-manage`,
|
|
287
|
+
or read it straight off the registry: `https://www.wix.com/skills/wix-manage`.
|
|
288
|
+
|
|
215
289
|
## Before you write the code
|
|
216
290
|
|
|
217
291
|
Confirm on the page — not from memory — the endpoint, the HTTP verb, the request body shape,
|
|
@@ -166,8 +166,8 @@ These recipes do NOT cover frontend development or SDK usage for displaying data
|
|
|
166
166
|
|
|
167
167
|
## Domains
|
|
168
168
|
|
|
169
|
-
### [Domain Search and
|
|
170
|
-
**Technical:**
|
|
169
|
+
### [Domain Search, Purchase and Connect](references/domains/domain-search-purchase-and-connect.md)
|
|
170
|
+
**Technical:** Purchase domains, connect domains to Wix sites, search for available domains and get domain suggestions. Covers availability checks, TLD filtering, purchase flow and connecting domains to Wix sites.
|
|
171
171
|
|
|
172
172
|
### [Domains Dashboard Navigation](references/domains/domains-dashboard-navigation.md)
|
|
173
173
|
**Technical:** Direct links to the site-level domain settings page and the account-level My Domains page on manage.wix.com, paired with the Domain Search read APIs.
|
|
@@ -230,10 +230,10 @@ These recipes do NOT cover frontend development or SDK usage for displaying data
|
|
|
230
230
|
## Events
|
|
231
231
|
|
|
232
232
|
### [Create Event](references/events/create-wix-event.md)
|
|
233
|
-
**Technical:** Creates an event with the Wix Events V3 API — required request body, ISO-8601 date and time settings, venue/online/TBD location and street addresses, RSVP vs ticketed registration, guest capacity,
|
|
233
|
+
**Technical:** Creates an event with the Wix Events V3 API — required request body, ISO-8601 date and time settings, venue/online/TBD location and street addresses, RSVP vs ticketed registration, guest capacity, short vs Ricos rich-text descriptions, ticket tiers and pricing, and recurring series from explicit occurrence dates. Distinguishes Wix Events from the Calendar, Marketing Calendar and Automations APIs that share the "events" name. Key endpoints: /events/v3/events, /events/v3/ticket-definitions.
|
|
234
234
|
|
|
235
235
|
### [Manage Events](references/events/manage-wix-events.md)
|
|
236
|
-
**Technical:**
|
|
236
|
+
**Technical:** Operates on events that already exist with the Wix Events V3 API — publishing a draft, cancelling, deleting, cloning, updating an event's date, and counting events, plus the draft-event permission that makes those calls fail with 403. Key endpoint: /events/v3/events.
|
|
237
237
|
|
|
238
238
|
---
|
|
239
239
|
|
|
@@ -367,9 +367,15 @@ These recipes do NOT cover frontend development or SDK usage for displaying data
|
|
|
367
367
|
### [Create Headless Site](references/sites/create-headless-site.md)
|
|
368
368
|
**Technical:** Creates a Wix Headless site (headless business) with one account-level API call — site, Wix Business Solution apps, and a configured OAuth client.
|
|
369
369
|
|
|
370
|
+
### [Manage OAuth Apps](references/sites/manage-oauth-apps.md)
|
|
371
|
+
**Technical:** Create, read, update, and query OAuth apps for a Wix headless site. Each OAuth app's `id` is the `client_id` for frontends connecting to the site's Wix APIs. Secret and rotation are dashboard-only.
|
|
372
|
+
|
|
370
373
|
### [Query Sites](references/sites/query-sites.md)
|
|
371
374
|
**Technical:** Lists and queries all sites associated with a Wix account using Sites API. Covers pagination with cursor-based navigation.
|
|
372
375
|
|
|
376
|
+
### [Read Account or Site Context](references/sites/read-site-context.md)
|
|
377
|
+
**Technical:** One call that returns a site's installed apps (by display name), locale, currency, status, and catalog version. Replaces separate query-sites + list-installed-apps + site-properties calls. Use this first on any unfamiliar site to decide which management recipes to follow.
|
|
378
|
+
|
|
373
379
|
### [Site Import](references/sites/site-import.md)
|
|
374
380
|
**Technical:** Drives the autonomous Wix Site Import agent over REST (`/site-import/v1/imports`) to migrate a store/site from another platform (Shopify, WooCommerce, Magento, or any URL) into Wix. Covers Start/Poll/Reply/Cancel, relaying agent questions and progress in plain language, handling `DEPLOYED`/`FAILED`/`AUTH_EXPIRED`/`SESSION_EXPIRED` states, and post-deploy follow-up changes. Use when the user wants to import, migrate, or clone an existing store/site into Wix.
|
|
375
381
|
|
|
@@ -383,18 +389,11 @@ These recipes do NOT cover frontend development or SDK usage for displaying data
|
|
|
383
389
|
### [Add Store Pages to Site](references/stores/add-store-pages-to-site.md)
|
|
384
390
|
**Technical:** Adds missing checkout and cart pages to a site when Stores app is installed. Used when store pages are missing after migration or setup issues.
|
|
385
391
|
|
|
386
|
-
### [Bulk Create Products with Options](references/stores/bulk-create-products-with-options.md)
|
|
387
|
-
**Technical:** Uses bulk products endpoint to create multiple products with inventory in a single request. Handles variant generation from options, media format requirements, and error handling for partial failures.
|
|
388
|
-
|
|
389
|
-
### [Create Product from Image](references/stores/create-product-from-image.md)
|
|
390
|
-
**Technical:** **MANDATORY entry point** for any "create product from image" or "create product from photo" request. STEP 1 auto-detects the site's catalog version (V1/V3) via the provision endpoint, then runs the matching flow inline — V3 supports up to 3 images, info sections, SEO, options/variants, and atomic creation; V1 supports a single image, simple product, and a separate media-attach call. Combines Media Upload + LLM analysis + Product Creation + (V1 only) Add Product Media in one self-contained recipe.
|
|
391
|
-
|
|
392
|
-
|
|
393
392
|
### [Create Product (Catalog V1)](references/stores/create-product-catalog-v1.md)
|
|
394
393
|
**Technical:** Create products using the Catalog V1 Products API. Use this recipe when the site's catalog version is CATALOG_V1. Covers simple product creation, product with options, and key V1 request structure differences from V3.
|
|
395
394
|
|
|
396
|
-
### [Create Product
|
|
397
|
-
**Technical:**
|
|
395
|
+
### [Create Product (Catalog V3)](references/stores/create-product-catalog-v3.md)
|
|
396
|
+
**Technical:** **Mandatory first read for every Catalog V3 create-product request, including vague requests.** Before any other documentation or API tool, load exactly `https://dev.wix.com/docs/api-reference/business-solutions/stores/skills/create-product-catalog-v3`. When no product is identified, that recipe read must be the final tool call; respond only: “What product would you like to create? You can upload up to 3 images and I’ll generate the product information from them, or describe the product in text.” Then stop. **Never replace this with a list or questions for name, price, description, type, images, inventory, SKU, options, SEO, or other fields.** If name or price is missing, ask for it or offer to suggest it, then stop. When name and price are present, create from supplied details without requiring optional enrichment. Never default price to `0`. The recipe owns single/bulk endpoint choice, inventory, physical/digital products, images, options, variants, prices, SKUs, limits, and validation.
|
|
398
397
|
|
|
399
398
|
### [Find Products (Query and Search, Catalog V3)](references/stores/find-products-query-and-search-catalog-v3.md)
|
|
400
399
|
**Technical:** Find, search, query, and list products from a Wix Store using Catalog V3 Search Products and Query Products endpoints. Explains when to use each endpoint, correct fields enum values, filtering, sorting, and paging.
|
|
@@ -402,9 +401,6 @@ These recipes do NOT cover frontend development or SDK usage for displaying data
|
|
|
402
401
|
### [Query Products (Catalog V1)](references/stores/query-products-catalog-v1.md)
|
|
403
402
|
**Technical:** Query and list products from a Wix Store using the Catalog V1 Query Products endpoint. Use this recipe when the site's catalog version is CATALOG_V1. Covers basic queries, filtering, sorting, and paging.
|
|
404
403
|
|
|
405
|
-
### [Setup Online Store (Catalog V3)](references/stores/setup-online-store-catalog-v3.md)
|
|
406
|
-
**Technical:** Initializes a Stores catalog with Catalog V3 Products API, bulk products endpoint, and Categories API. Covers product creation, option configuration, variant management, and category assignment.
|
|
407
|
-
|
|
408
404
|
### [Update Product Pre-Order](references/stores/update-product-pre-order.md)
|
|
409
405
|
**Technical:** Manages pre-order settings for product variants using V3 Inventory API. Covers enabling/disabling pre-orders, setting messages, configuring limits, and handling trackQuantity requirements.
|
|
410
406
|
|