@wix/agent-skills 1.23.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.
Files changed (37) hide show
  1. package/package.json +1 -1
  2. package/skills/wix-app/references/EDITOR_REACT_COMPONENT.md +64 -50
  3. package/skills/wix-app/references/editor-react-component/ACCESSIBILITY.md +4 -3
  4. package/skills/wix-app/references/editor-react-component/ANIMATED-COMPONENTS.md +28 -25
  5. package/skills/wix-app/references/editor-react-component/BRANDED-COMPONENTS.md +8 -2
  6. package/skills/wix-app/references/editor-react-component/COMPONENT-CONTRACT.md +12 -14
  7. package/skills/wix-app/references/editor-react-component/CSS-GUIDELINES.md +4 -3
  8. package/skills/wix-app/references/editor-react-component/DESIGN-STATES.md +66 -9
  9. package/skills/wix-app/references/editor-react-component/EDITOR-EXTENSION-CONFIGURATION.md +25 -0
  10. package/skills/wix-app/references/editor-react-component/OVERFLOW.md +146 -0
  11. package/skills/wix-app/references/editor-react-component/PARTS.md +6 -0
  12. package/skills/wix-app/scripts/scan-a11y-eslint.cjs +25 -1
  13. package/skills/{wix-headless-fast → wix-headless-kit}/SKILL.md +79 -60
  14. package/skills/{wix-headless-fast → wix-headless-kit}/cold-start/bootstrap.mjs +2 -2
  15. package/skills/{wix-headless-fast → wix-headless-kit}/cold-start/cold-start.md +26 -35
  16. package/skills/wix-headless-kit/guides/capabilities.md +76 -0
  17. package/skills/wix-headless-kit/guides/feedback.md +98 -0
  18. package/skills/{wix-headless-fast → wix-headless-kit}/guides/migration.md +20 -9
  19. package/skills/{wix-headless-fast → wix-headless-kit}/install/AGENTS.md +3 -0
  20. package/skills/{wix-headless-fast → wix-headless-kit}/install/attach.mjs +5 -2
  21. package/skills/{wix-headless-fast → wix-headless-kit}/install/check.mjs +1 -1
  22. package/skills/wix-headless-kit/install/context.mjs +169 -0
  23. package/skills/{wix-headless-fast → wix-headless-kit}/install/deploy.mjs +17 -4
  24. package/skills/{wix-headless-fast → wix-headless-kit}/install/setup.mjs +89 -55
  25. package/skills/{wix-headless-fast → wix-headless-kit}/install/templates.mjs +1 -1
  26. package/skills/wix-manage/references/cms/cms-dashboard-navigation.md +2 -2
  27. package/skills/wix-manage/references/cms/cms-data-items-crud.md +16 -16
  28. package/skills/wix-manage/references/cms/cms-publishing-flow.md +15 -15
  29. package/skills/wix-manage/references/cms/cms-schema-management.md +6 -6
  30. package/skills/wix-manage/references/sites/query-sites.md +1 -8
  31. package/skills/wix-auth/SKILL.md +0 -12
  32. package/skills/wix-auth/references/device-flow.md +0 -140
  33. package/skills/wix-headless-fast/install/context.mjs +0 -126
  34. /package/skills/{wix-headless-fast → wix-headless-kit}/guides/existing-site.md +0 -0
  35. /package/skills/{wix-headless-fast → wix-headless-kit}/guides/reference-mode.md +0 -0
  36. /package/skills/{wix-headless-fast → wix-headless-kit}/install/agents-md.mjs +0 -0
  37. /package/skills/{wix-headless-fast → wix-headless-kit}/install/lock.mjs +0 -0
@@ -1,27 +1,30 @@
1
1
  // Set up the project in the current folder — one deterministic call from "the folder and the
2
- // brief" to "brand layer can start", for a folder that is NOT yet a Wix project:
2
+ // brief" to "brand layer can start". The folder decides (install/context.mjs folderShape, five file
3
+ // facts: wix.config.json, its site.outputDirectory, the migration variables in .env.local,
4
+ // package.json, index.html):
3
5
  //
4
- // node <SKILL_ROOT>/install/setup.mjs --vertical <storefront|bookings|…> \
6
+ // node <SKILL_ROOT>/install/setup.mjs --vertical <storefront|bookings|…>[,<vertical>…] \
5
7
  // [--plan plan.json] [--business-name "<Brand>"] [--stack astro|react|lib|static] \
6
8
  // [--subfolder [--folder-name <npm-safe-name>]]
7
9
  //
8
- // - `wix.config.json` present → refuses. The folder is already a Wix project; deploy.mjs adds
9
- // this skill's code or a solution to it, then one install, then the seed if there is content.
10
- // One exception: a config and NO project whose `.env.local` (`wix env pull`, run here) declares a
11
- // MIGRATION PREVIEW — the config names a site created only to host the deployment, the env names
12
- // the site being migrated. Then → MIGRATE: the composed template is copied in around the config,
13
- // the code deploys with the parent's app as its client, the install starts, and NO seed runs: the
14
- // parent owns its content. Release still goes where the config says (install/context.mjs).
15
- // - a project but no `wix.config.json` (a package.json, or an index.html at the root) → CONNECT:
16
- // `npm create @wix/new@latest init` in place creates the site and the config, then deploy.
17
- // - otherwise (empty, or loose files such as a CSV or a brief) → CREATE: `wix create` with the
18
- // vertical's composed template (templates/<vertical>/project: the CLI's blank scaffold with the
19
- // vertical deployed and a lockfile), placed in the current directory (`--business-name` required).
10
+ // empty (or loose files: a CSV, a brief) → CREATE: `wix create` with the vertical's composed template
11
+ // (templates/<vertical>/project), placed in the current directory (`--business-name` required).
12
+ // a frontend, no wix.config.json (a package.json, or an index.html at the root) → ADOPT: `init` in
13
+ // place gives the project a new, empty site, then deploy. `--stack` required.
14
+ // CREATE and ADOPT are the two cases that seed: the run made the site, it is empty by construction,
15
+ // and the plan's content goes in (with --plan; without one the agent drafts a plan and seeds it, SKILL.md step 2).
16
+ // a config and no frontend, .env.local declaring a MIGRATION PREVIEW → MIGRATE: the composed template
17
+ // is copied in around the config, the code deploys with the parent's app as its client, the install
18
+ // starts. Nothing seeded: the parent owns its content.
19
+ // a config, index.html at the root, no package.json → PUBLISHED STATIC (a site published through the
20
+ // drop flow and downloaded): the config's site, no init; site/ becomes the upload, the REST layer
21
+ // deploys there, the pages move in (the agent's step). Nothing seeded.
22
+ // a config and a frontend (package.json, or index.html in the output folder) → refuses: iterate.
23
+ // a config and nothing else → refuses: attach.mjs's case.
20
24
  //
21
- // The script reads file markers only (wix.config.json, a package.json or index.html); everything
22
- // else is the agent's call: when connecting, `--stack` is required and comes from SKILL.md step 1,
23
- // and what the project needs for that stack on Wix hosting is prose there, not detection here. The
24
- // seed runs only when `--plan` is given: a brief that has not supplied any content gets no seed.
25
+ // Setup seeds only a site it created in this run. A site that existed before the run is never seeded
26
+ // by setup: the agent reads what the site holds (the vertical's read-site.mjs) and runs the seed module
27
+ // deliberately when the brief supplies or describes content. Seeds are additive and idempotent by name.
25
28
  //
26
29
  // Composes pieces that also remain individually runnable (deploy.mjs, the vertical's seed module)
27
30
  // to recover one failed step. Emits ONE JSON event per line and exits in ~35s with the two long
@@ -33,7 +36,7 @@ import { basename, dirname, join, resolve } from "node:path";
33
36
  import { fileURLToPath } from "node:url";
34
37
  import { AGENT_CONFIG_FILES, writeAgentsMd } from "./agents-md.mjs";
35
38
  import { listVerticals, templatesDir } from "./templates.mjs";
36
- import { siteContext } from "./context.mjs";
39
+ import { folderShape, siteContext } from "./context.mjs";
37
40
 
38
41
  const SKILL_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..");
39
42
 
@@ -51,7 +54,12 @@ const flag = (name) => {
51
54
  };
52
55
  const businessName = flag("business-name");
53
56
  const planPath = flag("plan");
54
- const vertical = flag("vertical");
57
+ // Every vertical the brief needs, comma-separated. The first one's composed template scaffolds the
58
+ // project and its seed runs from --plan; the others deploy in the same call so the ONE install covers
59
+ // them (adding a vertical after the install has started costs a second install). Their seeds run
60
+ // afterwards, each with its own plan, when the brief gives them content.
61
+ const verticals = (flag("vertical") ?? "").split(",").map((v) => v.trim()).filter(Boolean);
62
+ const vertical = verticals[0] ?? null;
55
63
  const stackFlag = flag("stack");
56
64
  // Opt-in: keep a CREATE's project in a subfolder instead of the current directory.
57
65
  const subfolder = argv.includes("--subfolder");
@@ -59,11 +67,11 @@ const subfolder = argv.includes("--subfolder");
59
67
  let TEMPLATES;
60
68
  try { TEMPLATES = templatesDir(); } catch (e) { fail("templates", e.message); }
61
69
  const knownVerticals = listVerticals(TEMPLATES);
62
- const usage = `usage: setup.mjs --vertical <${knownVerticals.join("|")}> [--plan plan.json] [--business-name "<Brand>"] [--stack astro|react|lib|static] [--subfolder]`;
70
+ const usage = `usage: setup.mjs --vertical <${knownVerticals.join("|")}>[,<vertical>…] [--plan plan.json] [--business-name "<Brand>"] [--stack astro|react|lib|static] [--subfolder]`;
63
71
  // --vertical is REQUIRED: a defaulted vertical deploys the wrong code and runs the wrong seed.
64
72
  if (!vertical) fail("args", usage);
65
- if (!knownVerticals.includes(vertical)) {
66
- fail("args", `unknown vertical "${vertical}" — shipped verticals: ${knownVerticals.join(", ")}`);
73
+ for (const v of verticals) {
74
+ if (!knownVerticals.includes(v)) fail("args", `unknown vertical "${v}" — shipped verticals: ${knownVerticals.join(", ")}`);
67
75
  }
68
76
  if (stackFlag && !["astro", "react", "lib", "static"].includes(stackFlag)) {
69
77
  fail("args", `unknown --stack "${stackFlag}" — astro, react, lib or static`);
@@ -74,22 +82,27 @@ if (planPath && !existsSync(planPath)) fail("args", `plan file not found: ${plan
74
82
  const cwd = process.cwd();
75
83
  const has = (p) => existsSync(join(cwd, p));
76
84
  const pkg = has("package.json") ? JSON.parse(readFileSync(join(cwd, "package.json"), "utf8")) : null;
77
- const hasProject = !!pkg || has("index.html");
78
- // A config here: refuse, unless it is a migration preview with no project yet (the site context
79
- // pulls .env.local when missing — that is where the migration is declared).
80
85
  let ctx = null;
86
+ let shape = folderShape(cwd).shape;
81
87
  if (has("wix.config.json")) {
82
- ctx = siteContext({ cwd });
83
- if (hasProject || !ctx.migration.active) {
84
- fail("place", "this folder is already a Wix project (wix.config.json): nothing to set up. deploy.mjs <vertical> adds this skill's code or a solution to it; then ONE npm install; then the vertical's seed module if there is content to create. A config with no project is attach.mjs's case (SKILL.md step 3)" + (ctx.pullError ? ` — note: env pull failed here (${ctx.pullError.slice(0, 120)})` : ""));
88
+ ctx = siteContext({ cwd }); // pulls .env.local when missing — where a migration is declared
89
+ shape = ctx.folder.shape;
90
+ if (shape !== "migration" && shape !== "published-static") {
91
+ fail("place", `this folder is already a Wix project (wix.config.json), shape "${shape}": nothing to set up. ${ctx.folder.next} (SKILL.md step 3)` + (ctx.pullError ? ` — note: env pull failed here (${ctx.pullError.slice(0, 120)})` : ""));
92
+ }
93
+ if (shape === "published-static" && stackFlag && stackFlag !== "static") {
94
+ fail("args", `a published static site (index.html beside wix.config.json, no package.json) is the static stack; --stack ${stackFlag} does not apply`);
85
95
  }
86
96
  }
87
- const mode = ctx ? "migrate" : hasProject ? "connect" : "create";
88
- if (mode === "connect" && !stackFlag) {
89
- fail("args", "connecting a project on disk needs --stack astro|react|lib|static — the stack you resolved in SKILL.md step 1 for this project");
97
+ const mode = { migration: "migrate", "published-static": "published-static", project: "adopt", empty: "create" }[shape];
98
+ const migrating = mode === "migrate";
99
+ const publishedStatic = mode === "published-static";
100
+ const hasProject = shape === "project";
101
+ if (mode === "adopt" && !stackFlag) {
102
+ fail("args", "adopting a project on disk needs --stack astro|react|lib|static — the stack you resolved in SKILL.md step 1 for this project");
90
103
  }
91
- const stack = stackFlag ?? "astro";
92
- emit("folder", { mode, stack, project: hasProject ? (pkg?.name ?? basename(cwd)) : null, ...(ctx ? { migration: ctx.migration, deploySiteId: ctx.deploy.siteId, warnings: ctx.warnings } : {}) });
104
+ const stack = publishedStatic ? "static" : (stackFlag ?? "astro");
105
+ emit("folder", { mode, shape, stack, project: hasProject ? (pkg?.name ?? basename(cwd)) : null, ...(ctx ? { deploySiteId: ctx.deploy.siteId, warnings: ctx.warnings } : {}), ...(migrating ? { migration: ctx.migration } : {}) });
93
106
 
94
107
  let projectDir = cwd;
95
108
  let folderName = null;
@@ -134,11 +147,13 @@ if (mode === "create") {
134
147
  } else if (mode === "migrate") {
135
148
  // ---- 1 · a migration preview: the config and credentials came with the folder -------------------
136
149
  // No site is created and nothing is provisioned: `wix.config.json` already names the deploy site
137
- // and its app, `.env.local` the parent's. Managed Astro gets the vertical's composed template copied
138
- // in around them (what `wix create` would have copied; the config and env are never overwritten);
139
- // any other stack is code-only and deploy below adds it.
140
- if (planPath) emit("seed_skipped", { reason: `migration preview of site ${ctx.migration.parentSiteId}: the site owns its content and nothing is seeded — the plan is ignored` });
141
- if (stack === "astro") {
150
+ // and its app, `.env.local` the parent's. The download usually carries the CLI's blank Astro
151
+ // starter beside the config: then the project is kept and deploy below adds the vertical's code and
152
+ // dependencies into it, as for an adopted project. A bare config (no package.json) gets the
153
+ // vertical's composed template copied in around it on managed Astro; any other stack is code-only.
154
+ if (stack === "astro" && has("package.json")) {
155
+ emit("migration_project_kept", { folder: cwd, project: pkg?.name ?? basename(cwd) });
156
+ } else if (stack === "astro") {
142
157
  const template = join(templatesDir({ need: `${vertical}/project` }), vertical, "project");
143
158
  emit("scaffolding", { folder: cwd, template, from: "migration preview" });
144
159
  cpSync(template, cwd, { recursive: true, force: false, errorOnExist: false });
@@ -150,12 +165,18 @@ if (mode === "create") {
150
165
  const gi = join(cwd, ".gitignore");
151
166
  const cur = existsSync(gi) ? readFileSync(gi, "utf8") : "";
152
167
  if (!/\.env/.test(cur)) writeFileSync(gi, cur + "\n# local env (pulled from Wix)\n.env.local\n.env\n");
168
+ } else if (publishedStatic) {
169
+ // ---- 1 · a published static site: the config came with the folder, the site exists -------------
170
+ // No init: `wix.config.json` already names the site the pages are published on (and its app). The
171
+ // pages stay where they are; the static handling below points the upload at site/ and the `next`
172
+ // says to move them in.
173
+ emit("preparing", { folder: cwd, siteId: ctx.deploy.siteId, from: "published static site" });
153
174
  } else {
154
175
  // ---- 1 · init in place --------------------------------------------------------------------------
155
176
  // The CLI's `init` links the folder to a NEW site: creates the site and its OAuth app, writes
156
177
  // wix.config.json and .env.local, touches nothing else. Non-interactive under CI=1; the site is
157
178
  // named after the folder (rename it in the dashboard).
158
- emit("initializing", { folder: cwd });
179
+ emit("adopting", { folder: cwd });
159
180
  const init = spawnSync("npm", ["create", "@wix/new@latest", "--", "init"],
160
181
  { cwd, env: { ...process.env, CI: "1" }, encoding: "utf8", timeout: 300_000 });
161
182
  if (init.status !== 0 || !has("wix.config.json")) {
@@ -172,17 +193,17 @@ if (stack === "static") {
172
193
  wixConfig.site = { ...(wixConfig.site ?? {}), outputDirectory: `./${STATIC_OUT}` };
173
194
  writeFileSync(join(projectDir, "wix.config.json"), JSON.stringify(wixConfig, null, 2) + "\n");
174
195
  }
175
- emit(mode === "create" ? "scaffolded" : mode === "migrate" ? "migration_preview" : "connected", {
196
+ emit({ create: "scaffolded", migrate: "migration_preview", adopt: "adopted", "published-static": "prepared" }[mode], {
176
197
  folder: folderName ?? cwd, stack,
177
- ...(ctx ? { deploySiteId: ctx.deploy.siteId, contentSiteId: ctx.content.siteId } : { siteId }),
198
+ ...(migrating ? { deploySiteId: ctx.deploy.siteId, contentSiteId: ctx.content.siteId } : { siteId }),
178
199
  });
179
200
 
180
201
  // ---- 2 · deploy shipped code + deps ---------------------------------------------------------------
181
202
  // A CREATE from the composed template already holds the code and the lock: deploy adds nothing and
182
- // reports the project; a CONNECT gets the code and its dependencies here.
203
+ // reports the project; an ADOPT gets the code and its dependencies here.
183
204
  const deploy = spawnSync(
184
205
  "node",
185
- [join(SKILL_ROOT, "install", "deploy.mjs"), vertical, "--stack", stack, ...(stack === "static" ? ["--out", STATIC_OUT] : []), ...(planPath ? ["--plan", resolve(planPath)] : [])],
206
+ [join(SKILL_ROOT, "install", "deploy.mjs"), ...verticals, "--stack", stack, ...(stack === "static" ? ["--out", STATIC_OUT] : []), ...(planPath ? ["--plan", resolve(planPath)] : [])],
186
207
  { cwd: projectDir, encoding: "utf8", timeout: 60_000 },
187
208
  );
188
209
  if (deploy.status !== 0) fail("deploy", deploy.stderr || deploy.stdout);
@@ -223,7 +244,7 @@ if (mode === "create" && !subfolder && projectDir !== cwd) {
223
244
  // ---- 2d · the agent config files `wix create` would have written --------------------------------
224
245
  // Skipped by the CLI because of --skip-install. Fill-only: a project that has its own AGENTS.md
225
246
  // keeps it (the event says `kept`).
226
- emit("agent_configs", writeAgentsMd(projectDir, { skill: basename(SKILL_ROOT), stack, ...(ctx ? { migration: { parentSiteId: ctx.migration.parentSiteId, deploySiteId: ctx.deploy.siteId } } : {}) }));
247
+ emit("agent_configs", writeAgentsMd(projectDir, { skill: basename(SKILL_ROOT), stack, ...(migrating ? { migration: { parentSiteId: ctx.migration.parentSiteId, deploySiteId: ctx.deploy.siteId } } : {}) }));
227
248
 
228
249
  // ---- 3 · start the dependency install, detached --------------------------------------------------
229
250
  // ONE install, here, for any project with a package.json (deploy patched it). The static stack has
@@ -243,13 +264,19 @@ if (stack !== "static" && existsSync(join(projectDir, "package.json"))) {
243
264
  emit("install_started", install);
244
265
  }
245
266
 
246
- // ---- 4 · start the seed, detached (only with a plan) ---------------------------------------------
267
+ // ---- 4 · start the seed, detached (a site this run created, with a plan) ---------------------------
247
268
  // The seed includes a Wix-side provisioning wait of unpredictable length (10-80s); running it in
248
269
  // the caller's foreground would idle the agent for exactly that long. Detach it like the install:
249
- // result JSON + exit-code marker land as files the caller syncs on before release. Seeding is
250
- // additive: it never deletes or overwrites what the site holds.
270
+ // result JSON + exit-code marker land as files the caller syncs on before release. Only a site this
271
+ // run created is seeded here; every other site existed before the run and is read first, then the
272
+ // agent runs the seed module itself when the brief supplies content. Seeds are additive and
273
+ // idempotent by name.
274
+ const madeTheSite = mode === "create" || mode === "adopt";
251
275
  let seed = null;
252
- if (planPath && mode !== "migrate") {
276
+ if (planPath && !madeTheSite) {
277
+ emit("seed_skipped", { reason: `${mode}: the site existed before this run; setup seeds only a site it created. Read what the site holds (templates/${vertical}/seed/read-site.mjs), then run templates/${vertical}/seed/seed-*.mjs ${planPath} yourself when the brief supplies or describes content` });
278
+ }
279
+ if (planPath && madeTheSite) {
253
280
  const seedDir = join(TEMPLATES, vertical, "seed");
254
281
  const seedName = existsSync(seedDir)
255
282
  ? readdirSync(seedDir).find((f) => f.startsWith("seed-") && f.endsWith(".mjs"))
@@ -264,7 +291,7 @@ if (planPath && mode !== "migrate") {
264
291
  );
265
292
  seedChild.unref();
266
293
  seed = { resultFile: "seed-result.json", log: "seed.log", doneMarker: ".seed-exit", success: "file contains 0" };
267
- emit("seeding_started", { vertical, ...seed });
294
+ emit("seeding_started", { vertical, ...seed, ...(verticals.length > 1 ? { note: `the plan seeds ${vertical}; the other verticals' seeds run afterwards, each with its own plan` } : {}) });
268
295
  }
269
296
 
270
297
  // ---- done ----------------------------------------------------------------------------------------
@@ -276,23 +303,30 @@ const release = {
276
303
  }[stack];
277
304
  // On a migration preview the links and `siteId` are the PARENT's — the site whose content the pages
278
305
  // show and whose dashboard manages it; `deploySiteId` is where `wix release` goes.
306
+ const others = verticals.slice(1);
279
307
  emit("ready_for_brand_layer", {
280
308
  mode,
309
+ shape,
281
310
  stack,
311
+ verticals,
282
312
  projectDir,
283
- siteId: ctx ? ctx.content.siteId : siteId,
284
- ...(ctx ? { deploySiteId: ctx.deploy.siteId, migration: { parentSiteId: ctx.migration.parentSiteId } } : {}),
313
+ siteId: migrating ? ctx.content.siteId : siteId,
314
+ ...(migrating ? { deploySiteId: ctx.deploy.siteId, migration: { parentSiteId: ctx.migration.parentSiteId } } : {}),
285
315
  dashboardUrl: deployResult.dashboardUrl,
286
316
  productsUrl: deployResult.productsUrl,
287
317
  categoriesUrl: deployResult.categoriesUrl,
288
318
  install,
289
319
  seed,
290
320
  next:
321
+ (publishedStatic ? "a published static site: its pages are live on this site already and keep their URL; move index.html, the other pages, styles and assets into site/ (the root keeps the config, the plan, the seed output and the skills) and wire the solution into the page that needs it; " : "") +
291
322
  (mode === "migrate"
292
323
  ? "a migration preview: the site being migrated owns its content (read it with the vertical's read-site.mjs when the brief allows probing; never seed it); theme + write the home page; "
293
- : planPath
294
- ? "theme + write the home page; "
295
- : "the site is new and empty — seed it (a plan per step 2, the vertical's seed module) or say so; theme + write the home page; ") +
324
+ : madeTheSite
325
+ ? (planPath ? "theme + write the home page; " : "the site is new and empty and no plan was given, so nothing was seeded yet: seed it now (a plan per step 2 — the brief's content, or one drafted per the vertical's SEED.md — then the vertical's seed module), and name the placeholder content in the closing message; theme + write the home page; ")
326
+ : `nothing was seeded (setup seeds only a site it created): read what the site holds with templates/${vertical}/seed/read-site.mjs, then run templates/${vertical}/seed/seed-*.mjs <plan> when the brief supplies or describes content; theme + write the home page; `) +
327
+ (others.length && mode !== "migrate"
328
+ ? `${others.join(", ")} deployed too, no further install needed: run each one's seed module (templates/<vertical>/seed/) with its own plan when the brief gives it content (the members seed installs the Members Area app and needs no plan); `
329
+ : "") +
296
330
  (install || seed ? "then wait for the done markers" + (seed ? ", verify .seed-exit is 0 (else read seed.log and re-run the seed module)" : "") + "; " : "") +
297
331
  `then ${release}` +
298
332
  (mode === "migrate" ? "; the release is the PREVIEW on the deploy site — close with its URL and the parent's dashboard, say the original site is unchanged and that completing the migration is the user's next step in the Wix CLI once they approve" : ""),
@@ -142,7 +142,7 @@ function fetchTemplates(cache) {
142
142
 
143
143
  // A sparse, shallow clone of templates/ at a ref (branch, tag, or commit id) into a temp dir.
144
144
  function cloneSparse(repo, ref) {
145
- const tmp = mkdtempSync(join(tmpdir(), "wix-headless-fast-templates-"));
145
+ const tmp = mkdtempSync(join(tmpdir(), "wix-headless-kit-templates-"));
146
146
  let r;
147
147
  if (ref && /^[0-9a-f]{40}$/i.test(ref)) {
148
148
  // a commit: shallow-fetch just it (GitHub serves any reachable commit by id)
@@ -28,8 +28,8 @@ Fetch the entity via REST, then link the matching dashboard page. All calls use
28
28
 
29
29
  | Entity | Read API | Dashboard link |
30
30
  |---|---|---|
31
- | Collection (schema) | `GET /wix-data/v2/collections/{collectionId}` · `GET /wix-data/v2/collections` (list) | `wix-cms/data/{collectionId}` |
32
- | Data item | `POST /wix-data/v2/items/query` (body includes `dataCollectionId`) · `GET /wix-data/v2/items/{itemId}?dataCollectionId=...` | `wix-cms/data/{collectionId}` (the collection's items table) |
31
+ | Collection (schema) | `GET https://www.wixapis.com/wix-data/v2/collections/{collectionId}` · `GET https://www.wixapis.com/wix-data/v2/collections` (list) | `wix-cms/data/{collectionId}` |
32
+ | Data item | `POST https://www.wixapis.com/wix-data/v2/items/query` (body includes `dataCollectionId`) · `GET https://www.wixapis.com/wix-data/v2/items/{itemId}?dataCollectionId=...` | `wix-cms/data/{collectionId}` (the collection's items table) |
33
33
 
34
34
  Example — after creating a collection and inserting items:
35
35
 
@@ -25,8 +25,8 @@ This recipe covers basic Create, Read, Update, Delete (CRUD) operations for Wix
25
25
  Before inserting or updating items, you need to know the collection's field names and types. If you don't already know the schema:
26
26
 
27
27
  1. **Query existing items** - Fetch a few items to infer field names from the data
28
- 2. **Get collection schema** - Use `GET /collections/{dataCollectionId}` for full field definitions, **including `plugins`** — don't omit the `plugins` field when fetching or listing schemas
29
- 3. **List collections** - Use `GET /collections?fields=displayName,plugins` to see what collections exist (see [Schema Management](cms-schema-management.md))
28
+ 2. **Get collection schema** - Use `GET https://www.wixapis.com/wix-data/v2/collections/{dataCollectionId}` for full field definitions, **including `plugins`** — don't omit the `plugins` field when fetching or listing schemas
29
+ 3. **List collections** - Use `GET https://www.wixapis.com/wix-data/v2/collections?fields=displayName,plugins` to see what collections exist (see [Schema Management](cms-schema-management.md))
30
30
 
31
31
  It may be, that user refers to schema by its `displayName` rather than `id`, if collection is not found list all collections to find the right `id` (`dataCollectionId`) to use.
32
32
 
@@ -36,7 +36,7 @@ It may be, that user refers to schema by its `displayName` rather than `id`, if
36
36
 
37
37
  ## Insert Data Item
38
38
 
39
- **Endpoint**: `POST /wix-data/v2/items`
39
+ **Endpoint**: `POST https://www.wixapis.com/wix-data/v2/items`
40
40
 
41
41
  **Request Body**:
42
42
  ```json
@@ -73,7 +73,7 @@ It may be, that user refers to schema by its `displayName` rather than `id`, if
73
73
 
74
74
  ## Bulk Insert Items
75
75
 
76
- **Endpoint**: `POST /wix-data/v2/bulk/items/insert`
76
+ **Endpoint**: `POST https://www.wixapis.com/wix-data/v2/bulk/items/insert`
77
77
 
78
78
  **Request Body**:
79
79
  ```json
@@ -108,7 +108,7 @@ It may be, that user refers to schema by its `displayName` rather than `id`, if
108
108
 
109
109
  ## Query Data Items
110
110
 
111
- **Endpoint**: `POST /wix-data/v2/items/query`
111
+ **Endpoint**: `POST https://www.wixapis.com/wix-data/v2/items/query`
112
112
 
113
113
  **Basic Query**:
114
114
  ```json
@@ -163,7 +163,7 @@ It may be, that user refers to schema by its `displayName` rather than `id`, if
163
163
 
164
164
  ## Get Single Item
165
165
 
166
- **Endpoint**: `GET /wix-data/v2/items/{itemId}?dataCollectionId={collectionId}`
166
+ **Endpoint**: `GET https://www.wixapis.com/wix-data/v2/items/{itemId}?dataCollectionId={collectionId}`
167
167
 
168
168
  ```bash
169
169
  curl -X GET \
@@ -173,7 +173,7 @@ curl -X GET \
173
173
 
174
174
  ## Update Data Item
175
175
 
176
- **Endpoint**: `PUT /wix-data/v2/items/{itemId}`
176
+ **Endpoint**: `PUT https://www.wixapis.com/wix-data/v2/items/{itemId}`
177
177
 
178
178
  **Request Body**:
179
179
  ```json
@@ -192,7 +192,7 @@ curl -X GET \
192
192
 
193
193
  ## Patch Data Item (Partial Update - Single Item)
194
194
 
195
- **Endpoint**: `PATCH /wix-data/v2/items/{dataItemId}`
195
+ **Endpoint**: `PATCH https://www.wixapis.com/wix-data/v2/items/{dataItemId}`
196
196
 
197
197
  Unlike Update, this only modifies the specified fields — all other fields remain unchanged.
198
198
 
@@ -229,7 +229,7 @@ Unlike Update, this only modifies the specified fields — all other fields rema
229
229
 
230
230
  ## Bulk Update Items
231
231
 
232
- **Endpoint**: `POST /wix-data/v2/bulk/items/update`
232
+ **Endpoint**: `POST https://www.wixapis.com/wix-data/v2/bulk/items/update`
233
233
 
234
234
  > **Important**: Use `id` (not `_id`) at the element level. The `data` object should NOT contain `_id`.
235
235
 
@@ -259,7 +259,7 @@ Unlike Update, this only modifies the specified fields — all other fields rema
259
259
 
260
260
  ## Bulk Patch Items (Partial Update)
261
261
 
262
- **Endpoint**: `POST /wix-data/v2/bulk/items/patch`
262
+ **Endpoint**: `POST https://www.wixapis.com/wix-data/v2/bulk/items/patch`
263
263
 
264
264
  Unlike bulk update, this only modifies the specified fields - other fields remain unchanged. **Use this for partial updates.**
265
265
 
@@ -330,15 +330,15 @@ Unlike bulk update, this only modifies the specified fields - other fields remai
330
330
  >
331
331
  > **For MULTI_REFERENCE operations (add speakers, assign tags, link categories, etc.):**
332
332
  > **READ [CMS References & Relationships](cms-references-and-relationships.md)** for the exact endpoints and request bodies:
333
- > - `POST /wix-data/v2/bulk/items/insert-references` - add references
334
- > - `POST /wix-data/v2/items/replace-references` - replace all references
335
- > - `POST /wix-data/v2/bulk/items/remove-references` - remove references
333
+ > - `POST https://www.wixapis.com/wix-data/v2/bulk/items/insert-references` - add references
334
+ > - `POST https://www.wixapis.com/wix-data/v2/items/replace-references` - replace all references
335
+ > - `POST https://www.wixapis.com/wix-data/v2/bulk/items/remove-references` - remove references
336
336
  >
337
337
  > Error `WDE0303` occurs when attempting to set multi-reference fields via data operations.
338
338
 
339
339
  ## Delete Data Item
340
340
 
341
- **Endpoint**: `DELETE /wix-data/v2/items/{itemId}?dataCollectionId={collectionId}`
341
+ **Endpoint**: `DELETE https://www.wixapis.com/wix-data/v2/items/{itemId}?dataCollectionId={collectionId}`
342
342
 
343
343
  ```bash
344
344
  curl -X DELETE \
@@ -348,7 +348,7 @@ curl -X DELETE \
348
348
 
349
349
  ## Bulk Delete Items
350
350
 
351
- **Endpoint**: `POST /wix-data/v2/bulk/items/remove`
351
+ **Endpoint**: `POST https://www.wixapis.com/wix-data/v2/bulk/items/remove`
352
352
 
353
353
  ```json
354
354
  {
@@ -452,7 +452,7 @@ POST https://www.wixapis.com/apps-installer-service/v1/app-instance/install
452
452
  }
453
453
  ```
454
454
 
455
- After the installation succeeds, retry the original `POST /wix-data/v2/items` request. If the
455
+ After the installation succeeds, retry the original `POST https://www.wixapis.com/wix-data/v2/items` request. If the
456
456
  user only asks what the error means or how to fix it, explain this installation step and ask for
457
457
  confirmation before performing the install.
458
458
 
@@ -68,7 +68,7 @@ Reads target a specific surface — there is no merged view:
68
68
  - **Published items**: query the published collection (`articles`).
69
69
  - **Drafts**: query the drafts collection resolved from `draftItemsPluginOptions.draftsCollectionId` (e.g. `articles__drafts`).
70
70
 
71
- **Endpoint**: `POST /wix-data/v2/items/query`
71
+ **Endpoint**: `POST https://www.wixapis.com/wix-data/v2/items/query`
72
72
 
73
73
  ```json
74
74
  {
@@ -92,7 +92,7 @@ Reads target a specific surface — there is no merged view:
92
92
 
93
93
  Insert into the **drafts** collection. The item starts as **DRAFT**.
94
94
 
95
- **Endpoint**: `POST /wix-data/v2/items`
95
+ **Endpoint**: `POST https://www.wixapis.com/wix-data/v2/items`
96
96
 
97
97
  ```json
98
98
  {
@@ -117,7 +117,7 @@ Editing a live item does **not** overwrite the live copy — it stages a **pendi
117
117
 
118
118
  Replaces the published item's data with the draft's content; the draft is then deleted. Pass the **published** collection id.
119
119
 
120
- **Endpoint**: `POST /wix-data/v2/items/publish-draft`
120
+ **Endpoint**: `POST https://www.wixapis.com/wix-data/v2/items/publish-draft`
121
121
 
122
122
  ```bash
123
123
  curl -X POST \
@@ -147,7 +147,7 @@ curl -X POST \
147
147
 
148
148
  Retracts a published item back to draft state. Pass the **published** collection id.
149
149
 
150
- **Endpoint**: `POST /wix-data/v2/items/unpublish`
150
+ **Endpoint**: `POST https://www.wixapis.com/wix-data/v2/items/unpublish`
151
151
 
152
152
  ```bash
153
153
  curl -X POST \
@@ -198,7 +198,7 @@ curl -X DELETE 'https://www.wixapis.com/wix-data/v2/items/<id>?dataCollectionId=
198
198
 
199
199
  **Enable** — add the Draft Items plugin (requires collection-management permission). Use the dedicated endpoint; the Draft Items plugin cannot be added through the generic add-plugin call.
200
200
 
201
- **Endpoint**: `POST /wix-data/v2/collections/add-draft-items-plugin`
201
+ **Endpoint**: `POST https://www.wixapis.com/wix-data/v2/collections/add-draft-items-plugin`
202
202
 
203
203
  ```bash
204
204
  curl -X POST 'https://www.wixapis.com/wix-data/v2/collections/add-draft-items-plugin' \
@@ -219,7 +219,7 @@ curl -X POST 'https://www.wixapis.com/wix-data/v2/collections/add-draft-items-pl
219
219
 
220
220
  **Disable** — remove the plugin:
221
221
 
222
- **Endpoint**: `POST /wix-data/v2/collections/delete-draft-items-plugin`
222
+ **Endpoint**: `POST https://www.wixapis.com/wix-data/v2/collections/delete-draft-items-plugin`
223
223
 
224
224
  ```bash
225
225
  curl -X POST 'https://www.wixapis.com/wix-data/v2/collections/delete-draft-items-plugin' \
@@ -252,17 +252,17 @@ At the REST level, every read/author/publish/unpublish call here goes through th
252
252
  | Collection state | Desired action | API call | Permission needed |
253
253
  |------------------|----------------|----------|-------------------|
254
254
  | Draft Items plugin absent | Any write | Normal insert/update — writes go live immediately | Write Data Items |
255
- | Draft Items enabled | Detect workflow | `GET /collections/{id}` → inspect plugins for the Draft Items plugin; read `draftItemsPluginOptions.draftsCollectionId` | (read) |
256
- | Draft Items enabled | Read published items | `POST /items/query` on the published id | read |
257
- | Draft Items enabled | Read drafts | `POST /items/query` on the drafts collection id | read |
255
+ | Draft Items enabled | Detect workflow | `GET https://www.wixapis.com/wix-data/v2/collections/{id}` → inspect plugins for the Draft Items plugin; read `draftItemsPluginOptions.draftsCollectionId` | (read) |
256
+ | Draft Items enabled | Read published items | `POST https://www.wixapis.com/wix-data/v2/items/query` on the published id | read |
257
+ | Draft Items enabled | Read drafts | `POST https://www.wixapis.com/wix-data/v2/items/query` on the drafts collection id | read |
258
258
  | PUBLISHED | Edit into a pending draft (→ CHANGED) | Create the draft (`createDataItemDraft`), then edit it on the drafts collection | Write Data Items |
259
- | — | Create new draft (→ DRAFT) | `POST /items` on the drafts collection | Write Data Items |
260
- | DRAFT / CHANGED | Publish (→ PUBLISHED) | `POST /items/publish-draft` (published id) | Write Data Items |
261
- | PUBLISHED / CHANGED | Unpublish, keep as draft (→ DRAFT) | `POST /items/unpublish` `copyToDraft:true` | Write Data Items |
262
- | PUBLISHED / CHANGED | Unpublish, discard | `POST /items/unpublish` `copyToDraft:false` | Write Data Items |
263
- | CHANGED | Revert to live version (discard edit) | `DELETE /items/{id}?dataCollectionId=<drafts id>` | Write Data Items |
259
+ | — | Create new draft (→ DRAFT) | `POST https://www.wixapis.com/wix-data/v2/items` on the drafts collection | Write Data Items |
260
+ | DRAFT / CHANGED | Publish (→ PUBLISHED) | `POST https://www.wixapis.com/wix-data/v2/items/publish-draft` (published id) | Write Data Items |
261
+ | PUBLISHED / CHANGED | Unpublish, keep as draft (→ DRAFT) | `POST https://www.wixapis.com/wix-data/v2/items/unpublish` `copyToDraft:true` | Write Data Items |
262
+ | PUBLISHED / CHANGED | Unpublish, discard | `POST https://www.wixapis.com/wix-data/v2/items/unpublish` `copyToDraft:false` | Write Data Items |
263
+ | CHANGED | Revert to live version (discard edit) | `DELETE https://www.wixapis.com/wix-data/v2/items/{id}?dataCollectionId=<drafts id>` | Write Data Items |
264
264
  | any | Delete entirely (both versions) | Delete on the published id (+ drafts id if a draft exists) | Write Data Items |
265
- | plain, no plugin | Enable workflow | `POST /collections/add-draft-items-plugin` | Manage Data Collections |
265
+ | plain, no plugin | Enable workflow | `POST https://www.wixapis.com/wix-data/v2/collections/add-draft-items-plugin` | Manage Data Collections |
266
266
 
267
267
  ---
268
268
 
@@ -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
  {
@@ -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). `wix token` prints one.
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,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).