@wix/agent-skills 1.12.0 → 1.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/package.json +1 -1
- package/skills/wix-app/references/data-collection/WIX_DATA.md +10 -0
- package/skills/wix-design-system/SKILL.md +3 -1
- package/skills/wix-headless/references/BUILD-astro.md +10 -1
- package/skills/wix-headless/references/shared/STYLING.md +0 -1
- package/skills/wix-headless/scripts/compose.mjs +19 -24
- package/skills/wix-headless/scripts/patch-decorative-slots.mjs +15 -9
- package/skills/wix-manage/SKILL.md +32 -54
- package/skills/wix-manage/references/ecommerce/api-recommendation-tracking.md +3 -2
- package/skills/wix-manage/references/ecommerce/ecom-load-context.md +144 -0
- package/skills/wix-manage/references/ecommerce/ecom-pricing.md +84 -0
- package/skills/wix-manage/references/ecommerce/ecom-shipping.md +64 -0
- package/skills/wix-manage/references/ecommerce/{setup-coupons.md → pricing-promotions/ecom-pricing-create-coupon.md} +20 -6
- package/skills/wix-manage/references/ecommerce/{setup-discount-rules.md → pricing-promotions/ecom-pricing-create-discount-rule.md} +31 -1
- package/skills/wix-manage/references/ecommerce/{flow-bundle-and-save.md → pricing-promotions/ecom-pricing-flow-bundle-and-save.md} +11 -52
- package/skills/wix-manage/references/ecommerce/{flow-seasonal-promotion.md → pricing-promotions/ecom-pricing-flow-seasonal-promotion.md} +17 -57
- package/skills/wix-manage/references/ecommerce/{flow-stock-mover.md → pricing-promotions/ecom-pricing-flow-stock-mover.md} +28 -70
- package/skills/wix-manage/references/ecommerce/{flow-upsell-boost.md → pricing-promotions/ecom-pricing-flow-upsell-boost.md} +15 -68
- package/skills/wix-manage/references/ecommerce/{goal-clear-inventory.md → pricing-promotions/ecom-pricing-goal-clear-inventory.md} +22 -13
- package/skills/wix-manage/references/ecommerce/{goal-drive-cross-sells.md → pricing-promotions/ecom-pricing-goal-drive-cross-sells.md} +26 -8
- package/skills/wix-manage/references/ecommerce/{goal-increase-aov.md → pricing-promotions/ecom-pricing-goal-increase-aov.md} +32 -25
- package/skills/wix-manage/references/ecommerce/{goal-seasonal-revenue.md → pricing-promotions/ecom-pricing-goal-seasonal-revenue.md} +21 -8
- package/skills/wix-manage/references/ecommerce/{troubleshoot-discount-not-applying.md → pricing-promotions/ecom-pricing-troubleshoot-not-applying.md} +1 -1
- package/skills/wix-manage/references/ecommerce/recommend-ecommerce-strategy.md +23 -47
- package/skills/wix-manage/references/ecommerce/{api-shipping.md → shipping/ecom-shipping-api.md} +4 -3
- package/skills/wix-manage/references/ecommerce/{flow-fix-coverage-gaps.md → shipping/ecom-shipping-fix-coverage.md} +23 -17
- package/skills/wix-manage/references/ecommerce/{flow-add-free-shipping.md → shipping/ecom-shipping-free-shipping.md} +23 -18
- package/skills/wix-manage/references/ecommerce/{flow-optimize-shipping-rates.md → shipping/ecom-shipping-optimize-rates.md} +19 -16
- package/skills/wix-manage/references/ecommerce/{setup-store-pickup-location.md → shipping/ecom-shipping-setup-pickup.md} +12 -10
- package/skills/wix-manage/references/ecommerce/{setup-shipping-rates.md → shipping/ecom-shipping-setup-rates.md} +1 -2
- package/skills/wix-manage/references/ecommerce/{setup-shipping-regions.md → shipping/ecom-shipping-setup-regions.md} +1 -2
- package/skills/wix-manage/references/sites/query-sites.md +104 -32
- package/skills/wix-headless/references/astro/templates/Footer.astro +0 -27
- package/skills/wix-headless/references/astro/templates/Navigation.astro +0 -38
- package/skills/wix-headless/references/astro/templates/index.astro +0 -56
- package/skills/wix-manage/references/ecommerce/goal-reduce-cart-abandonment.md +0 -147
- package/skills/wix-manage/references/ecommerce/guardrail-discount-conflicts.md +0 -118
- package/skills/wix-manage/references/ecommerce/guardrail-margin-protection.md +0 -88
- package/skills/wix-manage/references/ecommerce/guardrail-rate-pricing-sanity.md +0 -108
- package/skills/wix-manage/references/ecommerce/guardrail-shipping-health.md +0 -124
- package/skills/wix-manage/references/ecommerce/recipe-apply-shipping-recommendations.md +0 -298
- package/skills/wix-manage/references/ecommerce/skill-graph.md +0 -139
- package/skills/wix-manage/references/ecommerce/troubleshoot-checkout-delivery-dropoff.md +0 -124
package/README.md
CHANGED
|
@@ -92,6 +92,10 @@ Run the [`release-bump`](.github/workflows/release-bump.yml) workflow from the *
|
|
|
92
92
|
|
|
93
93
|
See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines on adding new skills.
|
|
94
94
|
|
|
95
|
+
### Eval Token Budgets
|
|
96
|
+
|
|
97
|
+
Eval scenarios under `yaml/wix-manage-evals/` may define a top-level `maxTokens` value. The GitHub Actions eval gate compares that budget against the PR run's total tokens for the scenario and fails the PR check when the budget is exceeded. This gate-owned field is separate from `llm_judge.maxTokens`, which only configures the judge assertion.
|
|
98
|
+
|
|
95
99
|
## License
|
|
96
100
|
|
|
97
101
|
MIT
|
package/package.json
CHANGED
|
@@ -261,6 +261,16 @@ const bulkResult = await items.bulkInsert("MyCollection", [
|
|
|
261
261
|
| `get`, `query`, `count`, `distinct` | `SCOPE.DC-DATA.READ` |
|
|
262
262
|
| `insert`, `update`, `save`, `remove`, `bulkInsert`, `bulkUpdate`, `bulkRemove` | `SCOPE.DC-DATA.WRITE` |
|
|
263
263
|
|
|
264
|
+
### Elevating permissions (backend only)
|
|
265
|
+
|
|
266
|
+
In backend code (service plugins, events, backend APIs), wrap the `items` method with `auth.elevate` from `@wix/essentials` to run with elevated permissions:
|
|
267
|
+
|
|
268
|
+
```typescript
|
|
269
|
+
import { auth } from '@wix/essentials';
|
|
270
|
+
const elevatedQuery = auth.elevate(items.query);
|
|
271
|
+
const configResult = await elevatedQuery('MyCollection').find();
|
|
272
|
+
```
|
|
273
|
+
|
|
264
274
|
## Date/Time Handling
|
|
265
275
|
|
|
266
276
|
- **Date (date-only)**: Store as a string in "YYYY-MM-DD" format (as returned by `<input type="date" />`).
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: wix-design-system
|
|
3
|
-
description: Wix Design System component reference. Use when building UI with @wix/design-system, choosing components, checking props and examples, or writing tests with component testkits. Triggers on "what component", "how do I make", "WDS", "show me props", "testkit", "driver", or component names like Button, Card, Box, Text.
|
|
3
|
+
description: Wix Design System component reference. Use when building UI with @wix/design-system, choosing components, checking props and examples, or writing tests with component testkits. Triggers on "what component", "how do I make", "WDS", "show me props", "testkit", "driver", or component names like Button, Card, Modal, Box, Text.
|
|
4
|
+
metadata:
|
|
5
|
+
verified: true
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# WDS Documentation Navigator
|
|
@@ -51,13 +51,22 @@ The whole Setup window is a single message of sibling `Bash` calls — **emit th
|
|
|
51
51
|
"navLinks": [ { "href": "/", "label": "Home" }, ... ],
|
|
52
52
|
"loadedPacks": ["stores", "cms", ...],
|
|
53
53
|
"packsWithComponents": ["stores", "ecom", ...],
|
|
54
|
-
"disabledPacks": ["gift-cards", ...]
|
|
54
|
+
"disabledPacks": ["gift-cards", ...],
|
|
55
|
+
"navPath": ".wix/nav.astro",
|
|
56
|
+
"footerPath": ".wix/footer.astro",
|
|
57
|
+
"homePath": ".wix/home.astro"
|
|
55
58
|
}
|
|
56
59
|
COMPOSE
|
|
57
60
|
```
|
|
58
61
|
|
|
59
62
|
The compose-input shape is documented in `scripts/compose.mjs`'s header.
|
|
60
63
|
|
|
64
|
+
**The entire visible page is LLM-generated.** `compose.mjs` still writes the plumbing — `global.css`, `astro.config.mjs`, and `Layout.astro` (the `<html>`/`<head>` shell that imports the fonts, `global.css`, ClientRouter, and the `<Navigation/>`+`<Footer/>` components) — but the **header, footer, and home page are authored by an LLM**, not from templates (there are no `Navigation.astro` / `Footer.astro` / `index.astro` templates anymore). Between `emit-design-tokens.mjs` and `compose.mjs`, dispatch a **Default-tier** generator that reads the token vocabulary at `.wix/design-tokens.css` and authors three files, then pass their paths:
|
|
65
|
+
- `.wix/nav.astro` → `Navigation.astro` (site header). Contract: one `<header class="site-nav" transition:persist="site-nav">` with brand mark + real nav links (`/`, `/about`, `/faq`), a `<!-- nav:links -->` + `<!-- nav:actions -->` marker and an empty `<div class="nav-actions">` for later vertical patches, and a no-JS mobile toggle.
|
|
66
|
+
- `.wix/footer.astro` → `Footer.astro`. Contract: one `<footer class="site-footer">` with brand, a short tagline, and the nav links.
|
|
67
|
+
- `.wix/home.astro` → `index.astro` (full home page). Contract: frontmatter importing `Layout` + a `<Layout>…</Layout>` wrapper; one `<!-- home:<pack> -->` marker per loaded home-contributing pack; and **two decorative-image slots** — `hero` + one section (e.g. `about`). **Each slot is a DEDICATED, EMPTY placeholder element that holds no copy** — e.g. `<div class="hero-image" data-decorative-slot="hero" style="aspect-ratio:4/5"></div>` sitting *beside* the hero text, NOT the `data-decorative-slot` attribute slapped on the content-bearing `<section>`. The image patcher injects an `<img>` only into an empty slot element; if the slot wraps real copy it is skipped (the image never lands). Any element type works (`<div>`/`<figure>`/…) as long as it is its own empty element.
|
|
68
|
+
- **All three:** compose tokens as utility classes so they match the theme; write real copy (no `{{…}}`); keep `transition:persist` + the `site-nav`/`site-footer` classes (the View-Transitions + `global.css` styling target them). `compose.mjs` writes each verbatim and **errors if any path is missing** (`NO_NAV`/`NO_FOOTER`/`NO_HOME`). Manifest records `nav`/`footer`/`home` = `"llm-generated"`.
|
|
69
|
+
|
|
61
70
|
**In the SAME message — the business Setup Step 4 batch** (frontend-blind; `SETUP.md` owns recipes/package set). These overlap the bridge's `compose.mjs` (~20 s) so it adds no serial wall:
|
|
62
71
|
|
|
63
72
|
3. `Bash` × N — app installs, one curl per `pack.apps[*]` → `SETUP.md` § Step 4a. Packs with no `apps[*]` (`cms`, `ecom`, `gift-cards`) install nothing — skip them.
|
|
@@ -46,7 +46,6 @@ These are layout/spacing/typography concerns that should always be utilities, ne
|
|
|
46
46
|
> **Never reintroduce a named `--spacing-*` scale.** In Tailwind v4 the `--spacing-*` namespace also generates the width/sizing families (`max-w-*`, `w-*`, `min-w-*`, …), so any `--spacing-<key>` token shadows the matching `max-w-<key>`. The current fix works because the skill's spacing steps happen to equal Tailwind's numeric defaults — but if a brand ever needs genuinely *custom* spacing **values**, put them under a different namespace (e.g. `--rhythm-*`) or use arbitrary values (`py-[5.5rem]`); do not revive `--spacing-*`.
|
|
47
47
|
|
|
48
48
|
**Width / reading columns:** `max-w-md`, `max-w-3xl`, `max-w-6xl`, `max-w-prose` now resolve correctly to the `--container-*` keys (no spacing collision), so use them freely; `container-reading` (the designer `@utility`) or an arbitrary `max-w-[48rem]` also work.
|
|
49
|
-
|
|
50
49
|
If a designer's `global.css` contains rules like `.featured-section { padding-block: 6rem; }` or `.product-card-body { display: flex; flex-direction: column; gap: 0.5rem; }`, those are misplaced — they belong in markup as utilities (`py-24`, `flex flex-col gap-2`). Inventing such classes ships broken layouts: every consumer needs the designer to have pre-declared the class, and Tailwind v4 silently drops the references when the rule is missing.
|
|
51
50
|
|
|
52
51
|
## Required tokens — the component-CSS template contract
|
|
@@ -212,6 +212,14 @@ const loadedPacks = Array.isArray(input.loadedPacks) ? input.loadedPacks : [];
|
|
|
212
212
|
const packsWithComponents = Array.isArray(input.packsWithComponents) ? input.packsWithComponents : [];
|
|
213
213
|
const disabledPacks = Array.isArray(input.disabledPacks) ? input.disabledPacks : [];
|
|
214
214
|
|
|
215
|
+
// Full-page LLM generation (this branch): the LLM authors the entire visible
|
|
216
|
+
// page — header (Navigation.astro), footer (Footer.astro), and home page
|
|
217
|
+
// (index.astro). compose writes each verbatim; there are no templates for them.
|
|
218
|
+
const resolveIn = (p) => { const s = typeof p === "string" ? p.trim() : ""; return s ? (isAbsolute(s) ? s : join(projectDir, s)) : null; };
|
|
219
|
+
const navPath = resolveIn(input.navPath);
|
|
220
|
+
const footerPath = resolveIn(input.footerPath);
|
|
221
|
+
const homePath = resolveIn(input.homePath);
|
|
222
|
+
|
|
215
223
|
const brandName = brand.name ?? "Brand";
|
|
216
224
|
|
|
217
225
|
// ── small color helper (derivation fail-safe only) ────────────────────────────
|
|
@@ -454,27 +462,16 @@ const navItems = navLinks
|
|
|
454
462
|
.filter((l) => l && l.href != null && l.label != null)
|
|
455
463
|
.map((l) => ({ href: String(l.href), label: String(l.label) }));
|
|
456
464
|
|
|
457
|
-
// ── 4. Navigation.astro
|
|
465
|
+
// ── 4. Navigation.astro (LLM-generated, verbatim) ─────────────────────────────
|
|
458
466
|
{
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
const links = navItems
|
|
462
|
-
.map((l) => ` <li class="site-nav-item"><a href="${escAttr(l.href)}">${l.label}</a></li>`)
|
|
463
|
-
.join("\n");
|
|
464
|
-
out = out.replace(/^\s*\{\{nav\.links\}\}\s*$/m, links);
|
|
465
|
-
writeProject("src/components/Navigation.astro", out);
|
|
467
|
+
if (!navPath || !existsSync(navPath)) die("NO_NAV", `LLM-generated header required via navPath (none at ${navPath ?? "<unset>"})`);
|
|
468
|
+
writeProject("src/components/Navigation.astro", readFileSync(navPath, "utf8"));
|
|
466
469
|
}
|
|
467
470
|
|
|
468
|
-
// ── 5. Footer.astro
|
|
471
|
+
// ── 5. Footer.astro (LLM-generated, verbatim) ─────────────────────────────────
|
|
469
472
|
{
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
out = out.replaceAll("{{shell.footerTagline}}", shell.footerTagline ?? "");
|
|
473
|
-
const links = navItems
|
|
474
|
-
.map((l) => ` <li><a href="${escAttr(l.href)}">${l.label}</a></li>`)
|
|
475
|
-
.join("\n");
|
|
476
|
-
out = out.replace(/^\s*\{\{nav\.links\}\}\s*$/m, links);
|
|
477
|
-
writeProject("src/components/Footer.astro", out);
|
|
473
|
+
if (!footerPath || !existsSync(footerPath)) die("NO_FOOTER", `LLM-generated footer required via footerPath (none at ${footerPath ?? "<unset>"})`);
|
|
474
|
+
writeProject("src/components/Footer.astro", readFileSync(footerPath, "utf8"));
|
|
478
475
|
}
|
|
479
476
|
|
|
480
477
|
// ── 6. index.astro ────────────────────────────────────────────────────────────────
|
|
@@ -485,13 +482,8 @@ const HOME_CONTRIBUTING = ["stores", "bookings", "gift-cards"]; // canonical ord
|
|
|
485
482
|
const homePool = new Set([...loadedPacks, ...disabledPacks]);
|
|
486
483
|
const homeMarkerPacks = HOME_CONTRIBUTING.filter((p) => homePool.has(p));
|
|
487
484
|
{
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
out = out.replaceAll("{{shell.heroSub}}", shell.heroSub ?? "");
|
|
491
|
-
out = out.replaceAll("{{brand.name}}", brandName);
|
|
492
|
-
const markers = homeMarkerPacks.map((p) => ` <!-- home:${p} -->`).join("\n");
|
|
493
|
-
out = out.replace(/^\s*\{\{home-markers\}\}\s*$/m, markers);
|
|
494
|
-
writeProject("src/pages/index.astro", out);
|
|
485
|
+
if (!homePath || !existsSync(homePath)) die("NO_HOME", `LLM-generated home page required via homePath (none at ${homePath ?? "<unset>"})`);
|
|
486
|
+
writeProject("src/pages/index.astro", readFileSync(homePath, "utf8"));
|
|
495
487
|
}
|
|
496
488
|
|
|
497
489
|
// ── manifest (the orchestrator parses this off stdout) ────────────────────────
|
|
@@ -508,6 +500,9 @@ const manifest = {
|
|
|
508
500
|
phase: "compose",
|
|
509
501
|
data: {
|
|
510
502
|
filesWritten,
|
|
503
|
+
nav: "llm-generated",
|
|
504
|
+
footer: "llm-generated",
|
|
505
|
+
home: "llm-generated",
|
|
511
506
|
componentCssImports: packsWithComponents,
|
|
512
507
|
homeMarkers: homeMarkerPacks.map((p) => `home:${p}`),
|
|
513
508
|
tokensApplied: {
|
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
// Inject Image-Phase-1 decorative URLs into the page shells.
|
|
3
3
|
//
|
|
4
4
|
// The design-system Composer (index.astro) and the Phase 4 page designers write
|
|
5
|
-
// `<
|
|
6
|
-
//
|
|
5
|
+
// `<el data-decorative-slot="<key>">…</el>` placeholders in src/pages/*.astro
|
|
6
|
+
// (any element — <div>, <section>, <figure>…). Image Phase 1 returns a slot→URL
|
|
7
|
+
// map in its JSON return; the orchestrator pipes that map (as JSON) into this
|
|
7
8
|
// script's stdin. This script reads the map + walks src/pages/*.astro,
|
|
8
|
-
// then injects an <img> as the first child of each matching slot
|
|
9
|
+
// then injects an <img> as the first child of each matching empty slot element —
|
|
9
10
|
// pure string substitution, no LLM, no file rewrites.
|
|
10
11
|
//
|
|
11
12
|
// Usage:
|
|
@@ -23,9 +24,9 @@
|
|
|
23
24
|
// blocks mode or Image Phase 1 had no URLs to publish).
|
|
24
25
|
// - src/pages missing at <scaffold-dir> and in any single subdir one
|
|
25
26
|
// level down → exit 2 status="error".
|
|
26
|
-
// - For each `data-decorative-slot="<key>"` in src/pages/*.astro:
|
|
27
|
-
// * Key has no URL in the input map → leave the
|
|
28
|
-
// *
|
|
27
|
+
// - For each `data-decorative-slot="<key>"` element in src/pages/*.astro:
|
|
28
|
+
// * Key has no URL in the input map → leave the element alone.
|
|
29
|
+
// * Element already has a non-comment child → skip with a warning.
|
|
29
30
|
// * Otherwise inject <img …> as the first child.
|
|
30
31
|
// - Output JSON summary of patches/skips/warnings to stdout.
|
|
31
32
|
|
|
@@ -99,14 +100,19 @@ const patched = [];
|
|
|
99
100
|
const skipped = [];
|
|
100
101
|
const warnings = [];
|
|
101
102
|
|
|
102
|
-
|
|
103
|
+
// Match ANY element carrying data-decorative-slot, not just <div>. Full-page
|
|
104
|
+
// LLM generation routinely puts the slot on a <section>/<figure>/<picture>;
|
|
105
|
+
// the closing tag is matched by backreference (\2) to the opening tag name.
|
|
106
|
+
// Slots are empty placeholders by contract, so the non-greedy body cannot
|
|
107
|
+
// straddle a sibling element of the same tag.
|
|
108
|
+
const SLOT_REGEX = /(<([a-zA-Z][\w-]*)[^>]*\bdata-decorative-slot="([^"]+)"[^>]*>)([\s\S]*?)(<\/\2>)/g;
|
|
103
109
|
|
|
104
110
|
for (const file of candidates) {
|
|
105
111
|
const original = readFileSync(file, "utf8");
|
|
106
112
|
let modified = original;
|
|
107
113
|
let fileChanged = false;
|
|
108
114
|
|
|
109
|
-
modified = modified.replace(
|
|
115
|
+
modified = modified.replace(SLOT_REGEX, (match, openTag, _tagName, slotKey, inner, closeTag) => {
|
|
110
116
|
const url = urlMap[slotKey];
|
|
111
117
|
if (!url) {
|
|
112
118
|
skipped.push({ file, slot: slotKey, reason: "no URL for this slot in input map" });
|
|
@@ -121,7 +127,7 @@ for (const file of candidates) {
|
|
|
121
127
|
}
|
|
122
128
|
|
|
123
129
|
if (stripped.length > 0) {
|
|
124
|
-
warnings.push({ file, slot: slotKey, reason: "
|
|
130
|
+
warnings.push({ file, slot: slotKey, reason: "slot element has existing non-image child content; not patching to avoid clobber" });
|
|
125
131
|
return match;
|
|
126
132
|
}
|
|
127
133
|
|
|
@@ -121,66 +121,44 @@ These recipes do NOT cover frontend development or SDK usage for displaying data
|
|
|
121
121
|
## eCommerce
|
|
122
122
|
|
|
123
123
|
**Routing — pick the right entry point:**
|
|
124
|
-
- **Any sales/business improvement request** (boost sales, promotions, help my business, holiday deals, improve revenue, discounts, shipping, coupons, clearance) → use [Recommend: eCommerce Strategy](references/ecommerce/recommend-ecommerce-strategy.md). This is the **default entry point** — it analyzes ALL domains (discounts, shipping
|
|
125
|
-
- **
|
|
126
|
-
- **
|
|
127
|
-
- **Discount not working at checkout** → use [Troubleshoot: Discount Not Applying](references/ecommerce/troubleshoot-discount-not-applying.md)
|
|
128
|
-
- **Checkout delivery step drop-off** → use [Troubleshoot: Checkout Delivery Drop-off](references/ecommerce/troubleshoot-checkout-delivery-dropoff.md)
|
|
124
|
+
- **Any sales/business improvement request** (boost sales, promotions, help my business, holiday deals, improve revenue, discounts, shipping, coupons, clearance) → use [Recommend: eCommerce Strategy](references/ecommerce/recommend-ecommerce-strategy.md). This is the **default entry point** — it analyzes ALL domains (discounts, shipping) and generates cross-domain recommendations. Do NOT ask clarifying questions.
|
|
125
|
+
- **Pricing & promotions** (coupons, discount rules, ribbons, sales) → use the [Pricing & Promotions](references/ecommerce/ecom-pricing.md) dispatcher.
|
|
126
|
+
- **Shipping setup** (rates, regions, pickup, free shipping, fix coverage) → use the [Shipping](references/ecommerce/ecom-shipping.md) dispatcher.
|
|
129
127
|
|
|
130
|
-
### [
|
|
131
|
-
**
|
|
132
|
-
|
|
133
|
-
### [Recipe: Apply Shipping Recommendations](references/ecommerce/recipe-apply-shipping-recommendations.md)
|
|
134
|
-
**Technical:** Applies AI-generated shipping recommendations. Creates or updates shipping options based on recommendation data.
|
|
128
|
+
### [eCommerce: Load Context](references/ecommerce/ecom-load-context.md)
|
|
129
|
+
**L1 loader** — loads general site data (siteId, country, currency, industry, catalog analytics) needed by every eCommerce category. Each category dispatcher loads this before tag-matching; runs once per session.
|
|
135
130
|
|
|
136
|
-
### [
|
|
137
|
-
**
|
|
131
|
+
### [Recommend: eCommerce Strategy](references/ecommerce/recommend-ecommerce-strategy.md)
|
|
132
|
+
**Entry point for all eCommerce recommendation requests.** Unified skill that analyzes site data across ALL domains (discounts + shipping), generates up to 5 cross-domain recommendations, and persists them to the tracking database. Covers discount strategies (seasonal, upsell, stock mover, bundling) AND shipping optimization (coverage gaps, free shipping, rate strategy, carrier backup). Use this for ANY business improvement request.
|
|
138
133
|
|
|
139
|
-
### [
|
|
140
|
-
**
|
|
134
|
+
### [Pricing & Promotions](references/ecommerce/ecom-pricing.md)
|
|
135
|
+
**Dispatcher** — routes coupon/discount/sale/ribbon/bundle requests to the right leaf recipe (create coupon, create discount rule, troubleshoot discount-not-applying), and routes strategic "run a sale / boost sales" requests to `recommend-ecommerce-strategy`.
|
|
141
136
|
|
|
142
|
-
### [
|
|
143
|
-
**
|
|
137
|
+
### [Shipping](references/ecommerce/ecom-shipping.md)
|
|
138
|
+
**Dispatcher** — routes shipping-setup requests (rates, regions, pickup, free shipping, fix coverage, optimize rates) to the right leaf recipe. The Shipping Options + Delivery Profiles APIs have no public docs page; `ecom-shipping-api.md` is the authoritative inline reference.
|
|
144
139
|
|
|
145
140
|
<details>
|
|
146
|
-
<summary>Internal skills (loaded automatically by the
|
|
147
|
-
|
|
148
|
-
####
|
|
149
|
-
- [
|
|
150
|
-
- [
|
|
151
|
-
- [
|
|
152
|
-
-
|
|
153
|
-
-
|
|
154
|
-
|
|
155
|
-
####
|
|
156
|
-
- [
|
|
157
|
-
- [
|
|
158
|
-
- [
|
|
159
|
-
- [
|
|
160
|
-
- [
|
|
161
|
-
- [
|
|
162
|
-
- [
|
|
163
|
-
|
|
164
|
-
####
|
|
165
|
-
- [
|
|
166
|
-
|
|
167
|
-
- [Guardrail: Shipping Health](references/ecommerce/guardrail-shipping-health.md)
|
|
168
|
-
- [Guardrail: Rate Pricing Sanity](references/ecommerce/guardrail-rate-pricing-sanity.md)
|
|
169
|
-
|
|
170
|
-
#### Config & API References
|
|
171
|
-
- [API: Recommendation Tracking](references/ecommerce/api-recommendation-tracking.md)
|
|
172
|
-
- [API: Shipping Delivery](references/ecommerce/api-shipping.md)
|
|
173
|
-
- [Setup: Discount Rules](references/ecommerce/setup-discount-rules.md)
|
|
174
|
-
- [Setup: Coupons](references/ecommerce/setup-coupons.md)
|
|
175
|
-
- [Setup: Shipping Regions](references/ecommerce/setup-shipping-regions.md)
|
|
176
|
-
- [Setup: Shipping Rates](references/ecommerce/setup-shipping-rates.md)
|
|
177
|
-
|
|
178
|
-
#### Tracking
|
|
179
|
-
- Tracking is built into [Recommend: eCommerce Strategy](references/ecommerce/recommend-ecommerce-strategy.md) (Steps 2 + 8) — no separate skill needed
|
|
180
|
-
- [API: Recommendation Tracking](references/ecommerce/api-recommendation-tracking.md) — CRUD API reference for the tracking service
|
|
181
|
-
|
|
182
|
-
#### Reference
|
|
183
|
-
- [Skill Graph](references/ecommerce/skill-graph.md)
|
|
141
|
+
<summary>Internal skills (loaded automatically by the dispatchers / orchestrator above — do NOT use directly)</summary>
|
|
142
|
+
|
|
143
|
+
#### Pricing & promotions leaves (loaded by the Pricing dispatcher or by the strategy orchestrator)
|
|
144
|
+
- [Pricing: Create Coupon](references/ecommerce/pricing-promotions/ecom-pricing-create-coupon.md)
|
|
145
|
+
- [Pricing: Create Discount Rule](references/ecommerce/pricing-promotions/ecom-pricing-create-discount-rule.md)
|
|
146
|
+
- [Pricing: Discount Not Applying](references/ecommerce/pricing-promotions/ecom-pricing-troubleshoot-not-applying.md)
|
|
147
|
+
- Goals: [Increase AOV](references/ecommerce/pricing-promotions/ecom-pricing-goal-increase-aov.md), [Clear Inventory](references/ecommerce/pricing-promotions/ecom-pricing-goal-clear-inventory.md), [Seasonal Revenue](references/ecommerce/pricing-promotions/ecom-pricing-goal-seasonal-revenue.md), [Drive Cross-Sells](references/ecommerce/pricing-promotions/ecom-pricing-goal-drive-cross-sells.md)
|
|
148
|
+
- Flows: [Upsell Boost](references/ecommerce/pricing-promotions/ecom-pricing-flow-upsell-boost.md), [Bundle and Save](references/ecommerce/pricing-promotions/ecom-pricing-flow-bundle-and-save.md), [Stock Mover](references/ecommerce/pricing-promotions/ecom-pricing-flow-stock-mover.md), [Seasonal Promotion](references/ecommerce/pricing-promotions/ecom-pricing-flow-seasonal-promotion.md)
|
|
149
|
+
|
|
150
|
+
#### Shipping leaves (loaded by the Shipping dispatcher)
|
|
151
|
+
- [Set Up Rates](references/ecommerce/shipping/ecom-shipping-setup-rates.md)
|
|
152
|
+
- [Set Up Regions](references/ecommerce/shipping/ecom-shipping-setup-regions.md)
|
|
153
|
+
- [Set Up Pickup / Local Delivery](references/ecommerce/shipping/ecom-shipping-setup-pickup.md)
|
|
154
|
+
- [Add Free Shipping](references/ecommerce/shipping/ecom-shipping-free-shipping.md)
|
|
155
|
+
- [Optimize Rates](references/ecommerce/shipping/ecom-shipping-optimize-rates.md)
|
|
156
|
+
- [Fix Coverage Gaps](references/ecommerce/shipping/ecom-shipping-fix-coverage.md)
|
|
157
|
+
- [API Reference](references/ecommerce/shipping/ecom-shipping-api.md) — inline spec for Shipping Options + Delivery Profiles
|
|
158
|
+
|
|
159
|
+
#### Cross-cutting tracking
|
|
160
|
+
- [API: Recommendation Tracking](references/ecommerce/api-recommendation-tracking.md) — load BEFORE generating any recommendation; persists PROPOSED state and tracks MarkExecuting → MarkDone/MarkFailed.
|
|
161
|
+
|
|
184
162
|
|
|
185
163
|
</details>
|
|
186
164
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: "API: Recommendation Tracking"
|
|
3
|
-
description:
|
|
4
|
-
layer: config
|
|
3
|
+
description: Cross-cutting tracking API for AI-generated recommendations across eCommerce categories (checkout, shipping, pricing). ALWAYS LOAD BEFORE generating a "give me N recommendations / concrete actions" response, in addition to the category recipe.
|
|
5
4
|
---
|
|
6
5
|
# API: Recommendation Tracking Service
|
|
7
6
|
|
|
@@ -11,6 +10,8 @@ This service persists recommendations in a database and tracks their lifecycle s
|
|
|
11
10
|
|
|
12
11
|
**Base URL**: `https://manage.wix.com/_api/agentic-recommendations/v1/agentic-recommendations`
|
|
13
12
|
|
|
13
|
+
> **Internal-but-callable API.** This is a Wix-internal service with NO public `dev.wix.com` docs page. It **IS callable via `CallWixSiteAPI`** in the authenticated editor/dashboard context the MCP runs in (verified: the endpoints return auth/validation errors, not 404). This file is the authoritative spec — do not try to `ReadFullDocsArticle` an external doc for it.
|
|
14
|
+
|
|
14
15
|
## How to call these APIs
|
|
15
16
|
|
|
16
17
|
Use `CallWixSiteAPI` to invoke each endpoint:
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "eCommerce: Load Context"
|
|
3
|
+
description: "eCommerce L1 context loader — calls wix-profile-client/v4/profile/metasite (NOT site-properties) to load siteId, country, currency, industry, last-30-day visitors/orders/GPV. Skip if already loaded."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# eCommerce: Load Context
|
|
7
|
+
|
|
8
|
+
> **L1 loader pattern.** Each L1 domain (eCommerce, Stores, Get-paid, Contacts, …) owns its own context loader. This file is the **eCommerce** L1 loader. Other L1s have their own (e.g. `stores-load-context.md` will detect Catalog V1/V3 for Stores categories). The boilerplate (Step 1 + 2) is small; the **field list and runtime detections differ by L1**.
|
|
9
|
+
|
|
10
|
+
> **When to run.** Called from the dispatch block of any eCommerce category's `default.md` (Tax, Pricing & promotions, …) before tag-matching. Run **once per session**. If `siteData.country` is already in your conversation context, skip the API calls below and return immediately — every subsequent eCommerce category entry reuses the loaded data.
|
|
11
|
+
|
|
12
|
+
This is the canonical extract of Steps 1 + 3 from today's `recommend-ecommerce-strategy.md`, scoped to the fields eCommerce categories actually need.
|
|
13
|
+
|
|
14
|
+
## Step 1 — Resolve siteId
|
|
15
|
+
|
|
16
|
+
If a `siteId` is not already known, call `ListWixSites`:
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
ListWixSites()
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
- If the merchant referenced a site by name, match it.
|
|
23
|
+
- If exactly one site exists, auto-select it.
|
|
24
|
+
- Otherwise, ask the merchant which site to use.
|
|
25
|
+
|
|
26
|
+
**Do not proceed without a `siteId`.**
|
|
27
|
+
|
|
28
|
+
## Step 2 — Load business profile (the canonical endpoint)
|
|
29
|
+
|
|
30
|
+
Same call today's `recommend-ecommerce-strategy.md` Step 3 makes. The field list below is the **eCommerce** subset — orchestrator-needed metrics (visitors / orders / GPV → AOV) plus locale/currency/industry used for dispatch tags and recommendations.
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
CallWixSiteAPI(
|
|
34
|
+
url: "https://www.wix.com/wix-profile-client/v4/profile/metasite",
|
|
35
|
+
method: "POST",
|
|
36
|
+
body: {
|
|
37
|
+
"fields": [
|
|
38
|
+
"language",
|
|
39
|
+
"merchant_business_country",
|
|
40
|
+
"suggested_main_industry",
|
|
41
|
+
"suggested_sub_industry",
|
|
42
|
+
"last_30_days_distinct_visitors",
|
|
43
|
+
"last_30_days_orders_count",
|
|
44
|
+
"online_gpv_last_30_days",
|
|
45
|
+
"payment_currency"
|
|
46
|
+
]
|
|
47
|
+
}
|
|
48
|
+
)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Extract each field into conversation context as `siteData`:
|
|
52
|
+
|
|
53
|
+
| Field in response | Maps to | Notes |
|
|
54
|
+
|---|---|---|
|
|
55
|
+
| `fields.language.aSingleValue.aString` | `siteData.language` | Locale code (e.g. `en-US`) |
|
|
56
|
+
| `fields.merchant_business_country.aSingleValue.aString` | `siteData.country` | ISO-3166-1 alpha-2 |
|
|
57
|
+
| `fields.suggested_main_industry.aSingleValue.aString` | `siteData.industry` | Used by Pricing orchestrator's goal classification |
|
|
58
|
+
| `fields.suggested_sub_industry.aSingleValue.aString` | `siteData.subIndustry` | Optional |
|
|
59
|
+
| `fields.last_30_days_distinct_visitors.aSingleValue.aLong` | `siteData.visitors30d` | **Returned as JSON string** — `parseInt` before arithmetic |
|
|
60
|
+
| `fields.last_30_days_orders_count.aSingleValue.aLong` | `siteData.orders30d` | parseInt |
|
|
61
|
+
| `fields.online_gpv_last_30_days.aSingleValue.aLong` | `siteData.gpv30d` | parseInt |
|
|
62
|
+
| `fields.payment_currency.aSingleValue.aString` | `siteData.currency` | ISO-4217 |
|
|
63
|
+
|
|
64
|
+
Missing fields ⇒ no data for that field (don't fabricate). If `merchant_business_country`, `suggested_main_industry`, or `online_gpv_last_30_days` are missing or null, surface to the merchant: "Cannot resolve required site data: <fields>." and stop.
|
|
65
|
+
|
|
66
|
+
**Derived value:** `siteData.aov = parseInt(gpv30d) / parseInt(orders30d)` — in `siteData.currency` units.
|
|
67
|
+
|
|
68
|
+
## Step 2b — Detect catalog presence and load analytics
|
|
69
|
+
|
|
70
|
+
Call `GetCatalogAnalytics` once here so all downstream pricing/promotions flows can reference `siteData.catalogAnalytics` without re-fetching.
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
CallWixSiteAPI(
|
|
74
|
+
url: "https://manage.wix.com/recommendations/v1/recommendations/get-catalog-analytics-tool",
|
|
75
|
+
method: "POST",
|
|
76
|
+
body: {
|
|
77
|
+
"aggregates": [
|
|
78
|
+
{"op":"count","field":"price"},
|
|
79
|
+
{"op":"min","field":"price"},
|
|
80
|
+
{"op":"max","field":"price"},
|
|
81
|
+
{"op":"avg","field":"profitMargin"},
|
|
82
|
+
{"op":"quantiles","field":"price","q":[0.5,0.75,0.9]},
|
|
83
|
+
{"op":"sum","field":"quantity"},
|
|
84
|
+
{"op":"sum","field":"ordersCount"}
|
|
85
|
+
],
|
|
86
|
+
"minMarginPct": 0.15
|
|
87
|
+
}
|
|
88
|
+
)
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Save the full `categoryGroups` array as `siteData.catalogAnalytics`. From the "All Products" group extract:
|
|
92
|
+
- `siteData.catalogProductCount` = `count()` value (0 if missing or call fails)
|
|
93
|
+
- `siteData.hasCatalog` = `siteData.catalogProductCount > 0`
|
|
94
|
+
|
|
95
|
+
If the call fails, set `siteData.hasCatalog = true` (assume catalog exists; let downstream fail naturally).
|
|
96
|
+
|
|
97
|
+
**This data is used by all pricing & promotions discount flows.** Flows that require a product catalog (Bundle & Save, Upsell Boost, Stock Mover, Seasonal) MUST check `siteData.hasCatalog` before proceeding — if `false`, stop with: "This site has no products. Set up your product catalog first before running promotions."
|
|
98
|
+
|
|
99
|
+
## Step 3 — Derive region (used by dispatch context tags)
|
|
100
|
+
|
|
101
|
+
From `siteData.country`, set `siteData.region`:
|
|
102
|
+
- `BR | AR | MX | CL | CO | PE` → `LATAM`
|
|
103
|
+
- EU member states (`DE | FR | IT | ES | NL | BE | PL | SE | IE | AT | PT | FI | DK | CZ | HU | GR | RO | BG | HR | SK | SI | LT | LV | EE | CY | MT | LU`) → `EU`
|
|
104
|
+
- `JP | CN | KR | SG | AU | NZ | IN | TH | ID | MY | PH | VN | HK | TW` → `APAC`
|
|
105
|
+
- otherwise → `null`
|
|
106
|
+
|
|
107
|
+
(UK is **not** in `region:EU`. AU/NZ are in `region:APAC` but Tax inclusive-pricing rules differ — handled inside Tax promotions.)
|
|
108
|
+
|
|
109
|
+
## Step 4 — Return
|
|
110
|
+
|
|
111
|
+
Return immediately. Subsequent eCommerce category dispatches read `siteData.*` from conversation context without re-fetching. If the agent crosses into a different L1 (e.g. Stores) within the same session, that L1's loader will see `siteData.country` already loaded, skip its Steps 1-3, and only fire its own general derivations.
|
|
112
|
+
|
|
113
|
+
## Architectural rule — general site data only
|
|
114
|
+
|
|
115
|
+
**This file must contain only general / cross-cutting site data** — fields that **every** category in this L1 needs. It must **not** include L3-category-specific runtime detection (e.g. Tax calculator, Catalog V1/V3, payment-provider state, shipping-coverage state).
|
|
116
|
+
|
|
117
|
+
Reasoning:
|
|
118
|
+
- Per-category detect calls accumulate cost on every session entry, even when the agent never visits that category.
|
|
119
|
+
- L3-specific state can use APIs that aren't TPA-public (e.g. the Wix Tax FQDNs are `exposure: INTERNAL`); if the L1 loader depends on them, the entire L1 fails to load. Keeping the loader general-only contains the blast radius.
|
|
120
|
+
- Per-category state can change independently of the merchant; loading it eagerly invites stale-data bugs.
|
|
121
|
+
|
|
122
|
+
**Where category-specific runtime data is detected instead:** inside the category's `default.md` (Step before dispatch) or inside the specific promotion that needs it. The L1 loader does **not** prime per-category fields; the category does its own detection lazily, only when its own intent dispatch fires.
|
|
123
|
+
|
|
124
|
+
Concretely for the categories we know about:
|
|
125
|
+
- **Tax** — calculator detection (Manual vs Avalara) belongs in `ecom-tax.md` (the merged category-doc + dispatcher) or in each Tax promotion when it runs. Not here.
|
|
126
|
+
- **Catalog V1/V3 version detection** — belongs in the Stores category loader when Stores migrates. `getCatalogAnalytics` (product count/margin/price) is already loaded here as a cross-cutting concern; V1/V3 detection is a separate, Stores-specific signal.
|
|
127
|
+
- **Payments & finance** (when Get-paid migrates) — payment-provider state belongs in `finance-and-payments/get-paid-finance-default.md`.
|
|
128
|
+
|
|
129
|
+
## What this file does NOT do
|
|
130
|
+
|
|
131
|
+
- **Does not detect per-category runtime state** (see architectural rule above).
|
|
132
|
+
- **Does not load tracking history.** But: if any recipe in this session generates a recommendation to present to the merchant — regardless of which eCommerce category — it MUST load [API: Recommendation Tracking](https://dev.wix.com/docs/api-reference/business-solutions/e-commerce/skills/api-recommendation-tracking) and follow the lifecycle: load history before generating (Query), persist as PROPOSED via BatchCreate before presenting, and track execution via MarkExecuting / MarkDone / MarkFailed. This obligation applies to ALL eCommerce domains.
|
|
133
|
+
- **Does not load non-eCommerce L1 fields** (catalog V1/V3 version detection, payment provider, …). Those belong inside the owning L1's category-level files (per the architectural rule). Note: `getCatalogAnalytics` (product count, margin, price distribution) IS loaded here as a cross-cutting concern; Catalog V1/V3 version detection is separate and belongs in the Stores category's own loader.
|
|
134
|
+
- **Does not enforce dispatch.** The category's `default.md` is what scores tags and picks a promotion — this file only fills general site context.
|
|
135
|
+
|
|
136
|
+
## Pattern for future L1 loaders
|
|
137
|
+
|
|
138
|
+
When a new L1 domain is migrated to the routing tree, author a `<l1>-load-context.md` at its root:
|
|
139
|
+
|
|
140
|
+
- `references/stores/stores-load-context.md` — Stores L1 loader. Steps 1-3 same boilerplate, Step 4 runtime-detects Catalog version (V1/V3) and any other Stores-specific fields.
|
|
141
|
+
- `references/get-paid/get-paid-load-context.md` — Get-paid L1 loader. Step 4 inspects payment provider state, enabled methods.
|
|
142
|
+
- `references/contacts/contacts-load-context.md` — Contacts L1 loader. Possibly minimal — most CRM ops don't need runtime detection.
|
|
143
|
+
|
|
144
|
+
Each lives sibling to its L1's category-docs. Each is referenced from every category's `default.md` within its L1. Skip-if-loaded check across L1s makes cross-L1 sessions cost-free.
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "Pricing & Promotions"
|
|
3
|
+
description: Pricing & Promotions boundary owner — discounts, coupons, sales, ribbons, bundles. **Always load this dispatcher first when a question touches both discount work and refunds, payments, product-price edits, or shipping rates** — the rules for which side owns each topic live in this file, not in this README line.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Pricing & Promotions
|
|
7
|
+
|
|
8
|
+
Discount rules, coupon codes, sales, ribbons, bundles, tiered pricing, and the strategic side of "run a promotion to grow revenue".
|
|
9
|
+
|
|
10
|
+
> **Routing rule (READ FIRST).** Any merchant query that mentions BOTH a Pricing-side topic (discount, coupon, sale, ribbon, bundle, promotion strategy) AND a NON-pricing-side topic (refunding a past order, processing a payment, editing the product's base price, shipping rates) MUST be answered by loading this dispatcher first AND the relevant other category (refunds → Get Paid / Dashboard; price → Catalog; shipping rates → Shipping). Do NOT route mixed queries from the WixREADME index alone; the binding decision lives here.
|
|
11
|
+
|
|
12
|
+
**Pricing & promotions is NOT:**
|
|
13
|
+
- The product price itself or its description/image → see **Catalog** (those are product fields).
|
|
14
|
+
- A standing $0 shipping option/region rate → see **Shipping & fulfillment**.
|
|
15
|
+
- Refunding a previous discounted order → route to verified Get Paid/payment docs or Dashboard guidance.
|
|
16
|
+
|
|
17
|
+
> **Before dispatching** — 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
|
+
>
|
|
19
|
+
> **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
|
+
>
|
|
21
|
+
> **Do not fall back to legacy `setup-*` or `flow-*` pricing slugs.** The skills below replaced earlier `…/skills/setup-coupons` and `…/skills/flow-<name>` articles during the routing-tree migration. If a slug below returns a transient 404 (rawdocs ingestion delay), **retry the same URL after a brief pause** — do NOT load any `setup-coupons` or `flow-*` legacy version even if it appears in the WixREADME index; that content is stale pre-migration material that contradicts this dispatcher.
|
|
22
|
+
|
|
23
|
+
### Actions — concrete operations
|
|
24
|
+
|
|
25
|
+
> - [Create coupon](https://dev.wix.com/docs/api-reference/business-solutions/e-commerce/skills/pricing-create-coupon) — tags: `[intent:create-coupon]` · priority 0
|
|
26
|
+
> - [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
|
+
> - [Add sale ribbon / new ribbon](https://dev.wix.com/docs/api-reference/business-solutions/e-commerce/skills/pricing-create-discount-rule) — tags: `[intent:add-ribbon]` · priority 0 · *ribbons are configured via Discount Rules; same recipe*
|
|
28
|
+
> - [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
|
+
|
|
30
|
+
### Business flows — the orchestrator
|
|
31
|
+
|
|
32
|
+
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.
|
|
33
|
+
|
|
34
|
+
> - [Run a sale / promotion strategy](https://dev.wix.com/docs/api-reference/business-solutions/e-commerce/skills/recommend-e-commerce-strategy) — tags: `[intent:run-a-sale]` · priority 0
|
|
35
|
+
> - [Boost my business / increase sales](https://dev.wix.com/docs/api-reference/business-solutions/e-commerce/skills/recommend-e-commerce-strategy) — tags: `[intent:boost-business]` · priority 0
|
|
36
|
+
> - [Seasonal / holiday promotion](https://dev.wix.com/docs/api-reference/business-solutions/e-commerce/skills/recommend-e-commerce-strategy) — tags: `[intent:seasonal-promo]` · priority 0
|
|
37
|
+
> - [Clearance / move slow stock](https://dev.wix.com/docs/api-reference/business-solutions/e-commerce/skills/recommend-e-commerce-strategy) — tags: `[intent:clearance]` · priority 0
|
|
38
|
+
> - [Increase AOV (bundle / upsell)](https://dev.wix.com/docs/api-reference/business-solutions/e-commerce/skills/recommend-e-commerce-strategy) — tags: `[intent:increase-aov]` · priority 0
|
|
39
|
+
>
|
|
40
|
+
> **If the orchestrator above returns a 404** — do not stop. Classify the merchant intent directly and load the matching goal skill via `ReadFullDocsArticle`, then follow its routing chain into the flow skill:
|
|
41
|
+
> - Holiday / event / date mentioned (SEASONAL — takes priority over all other signals) → [Goal: Seasonal Revenue](https://dev.wix.com/docs/api-reference/business-solutions/e-commerce/skills/goal-seasonal-revenue)
|
|
42
|
+
> - "Boost sales", "increase AOV", "upsell", "spend more" (UPSELL_BOOST) → [Goal: Increase AOV](https://dev.wix.com/docs/api-reference/business-solutions/e-commerce/skills/goal-increase-aov)
|
|
43
|
+
> - "Clearance", "slow stock", "overstock", "move inventory" (STOCK_MOVER) → [Goal: Clear Inventory](https://dev.wix.com/docs/api-reference/business-solutions/e-commerce/skills/goal-clear-inventory)
|
|
44
|
+
> - "Bundle", "cross-sell", "buy together", "more items per order" (BUNDLE_AND_SAVE) → [Goal: Drive Cross-Sells](https://dev.wix.com/docs/api-reference/business-solutions/e-commerce/skills/goal-drive-cross-sells)
|
|
45
|
+
|
|
46
|
+
### Info / troubleshoot / recommendation
|
|
47
|
+
|
|
48
|
+
> - [Discount not applying — diagnose](https://dev.wix.com/docs/api-reference/business-solutions/e-commerce/skills/pricing-discount-not-applying) — tags: `[intent:troubleshoot]` · priority 0
|
|
49
|
+
> - [View active discounts (Coupons API)](https://dev.wix.com/docs/api-reference/business-solutions/coupons/coupons/query-coupons) — tags: `[intent:view-active-discounts]` · priority 0 · **API doc, no skill** (per §7.5)
|
|
50
|
+
> - [View active discounts (Discount Rules API)](https://dev.wix.com/docs/api-reference/business-solutions/e-commerce/discount-rules/query-discount-rules) — tags: `[intent:view-active-rules]` · priority 0 · **API doc, no skill**
|
|
51
|
+
> - [Coupon usage stats](https://dev.wix.com/docs/api-reference/business-solutions/coupons/coupons/get-coupon-usage) — tags: `[intent:coupon-usage-stats]` · priority 0 · **API doc, no skill**
|
|
52
|
+
> - Competitive pricing check (how do my prices compare?) — tags: `[intent:competitive-pricing]` · *no Wix API for competitor data — advise the merchant to benchmark externally (Google Shopping / market research); Wix only exposes their own catalog prices via Catalog API*
|
|
53
|
+
|
|
54
|
+
### Cross-category routes (handled in another category)
|
|
55
|
+
|
|
56
|
+
> - [Change product price](https://dev.wix.com/docs/api-reference/business-solutions/stores/products-v3/update-product) — tags: `[intent:change-price]` · *price is a product field — Catalog API*
|
|
57
|
+
> - [Set compare-at price](https://dev.wix.com/docs/api-reference/business-solutions/stores/products-v3/update-product) — tags: `[intent:set-compare-at]` · *Catalog*
|
|
58
|
+
> - [Free shipping over $X (promo rule)](https://dev.wix.com/docs/api-reference/business-solutions/e-commerce/skills/pricing-create-discount-rule) — tags: `[intent:free-shipping-promo]` · *belongs here as a promo rule; a $0 shipping rate is Shipping*
|
|
59
|
+
|
|
60
|
+
## Tag matching
|
|
61
|
+
|
|
62
|
+
The agent matches the merchant's natural-language query to an `intent:*` tag (cues are in each promotion file's `description`), AND matches MerchantContext to any context tags. A promotion's tags must ALL be satisfied for it to be eligible. Among eligible promotions, the one with the highest tag-count wins; ties broken by `priority`.
|
|
63
|
+
|
|
64
|
+
### Worked examples
|
|
65
|
+
|
|
66
|
+
| Merchant query | MerchantContext | Match |
|
|
67
|
+
|---|---|---|
|
|
68
|
+
| "Create a 20% off coupon" | any | `ecom-pricing-create-coupon` via `[intent:create-coupon]` |
|
|
69
|
+
| "Run a Black Friday sale" | any | `recommend-ecommerce-strategy` via `[intent:run-a-sale]` (orchestrator classifies as SEASONAL internally) |
|
|
70
|
+
| "Help me boost my sales" | any | `recommend-ecommerce-strategy` via `[intent:boost-business]` |
|
|
71
|
+
| "My coupon code XMAS isn't working" | any | `ecom-pricing-troubleshoot-not-applying` |
|
|
72
|
+
| "Show me my active discounts" | any | `query-coupons` API doc (no skill — per §7.5) |
|
|
73
|
+
| "Change the price of product Y" | any | Catalog cross-route (re-dispatch to Catalog when that category exists) |
|
|
74
|
+
|
|
75
|
+
## Base recipe (fallback)
|
|
76
|
+
|
|
77
|
+
If nothing matches, the merchant query is too vague. Ask **one** clarifying question:
|
|
78
|
+
|
|
79
|
+
> "Do you want to (a) **create** a specific discount/coupon now, (b) **strategize** a sale or promotion campaign, or (c) **fix** a discount that isn't applying?"
|
|
80
|
+
|
|
81
|
+
Map the answer → re-dispatch:
|
|
82
|
+
- (a) → `ecom-pricing-create-coupon` (default for "create a discount")
|
|
83
|
+
- (b) → `recommend-ecommerce-strategy`
|
|
84
|
+
- (c) → `ecom-pricing-troubleshoot-not-applying`
|