@wix/agent-skills 1.31.2 → 1.32.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 (40) hide show
  1. package/README.md +4 -12
  2. package/package.json +1 -1
  3. package/skills/wix-app/SKILL.md +39 -15
  4. package/skills/wix-app/references/BACKEND_API.md +1 -1
  5. package/skills/wix-app/references/EDITOR_REACT_COMPONENT.md +11 -8
  6. package/skills/wix-app/references/SDK_MODULE_MAP.md +1 -1
  7. package/skills/wix-app/references/STORES_VERSIONING.md +24 -2
  8. package/skills/wix-app/references/dashboard-page/DATA_SOURCES.md +9 -13
  9. package/skills/wix-app/references/dashboard-page/IMAGE_RENDERING.md +61 -0
  10. package/skills/wix-app/references/editor-react-component/ACCESSIBILITY.md +54 -64
  11. package/skills/wix-app/references/editor-react-component/ANIMATED-COMPONENTS.md +14 -21
  12. package/skills/wix-app/references/editor-react-component/COMPONENT-CONTRACT.md +37 -30
  13. package/skills/wix-app/references/editor-react-component/CSS-GUIDELINES.md +43 -29
  14. package/skills/wix-app/references/editor-react-component/DESIGN-STATES.md +40 -39
  15. package/skills/wix-app/references/editor-react-component/PARTS.md +8 -6
  16. package/skills/wix-app/references/editor-react-component/PROPS-VS-CSS.md +22 -2
  17. package/skills/wix-app/scripts/scan-a11y-eslint.cjs +39 -16
  18. package/skills/wix-app/scripts/sdk-curated.json +45 -0
  19. package/skills/wix-app/scripts/sdk-lookup.cjs +1180 -0
  20. package/skills/wix-base44-connector/SKILL.md +4 -2
  21. package/skills/wix-base44-connector/scripts/utils.cjs +5 -2
  22. package/skills/wix-headless-kit/SKILL.md +4 -1
  23. package/skills/wix-headless-kit/guides/api-run.md +14 -20
  24. package/skills/wix-headless-kit/install/pins.json +1 -1
  25. package/skills/wix-manage/SKILL.md +30 -8
  26. package/skills/wix-manage/references/automations/actions.md +134 -0
  27. package/skills/wix-manage/references/automations/activation-status.md +64 -48
  28. package/skills/wix-manage/references/automations/api-catalog.md +213 -77
  29. package/skills/wix-manage/references/automations/automation-model.md +199 -0
  30. package/skills/wix-manage/references/automations/bracket-expressions.md +132 -0
  31. package/skills/wix-manage/references/automations/build-and-manage-automations.md +305 -26
  32. package/skills/wix-manage/references/automations/triggers.md +190 -0
  33. package/skills/wix-manage/references/collaborators/manage-site-collaborators.md +128 -0
  34. package/skills/wix-manage/references/forms/forms-dashboard-navigation.md +3 -1
  35. package/skills/wix-manage/references/forms/read-forms-and-submissions.md +277 -0
  36. package/skills/wix-manage/references/forms/update-form.md +5 -0
  37. package/skills/wix-manage/references/seo/manage-url-redirects.md +33 -4
  38. package/skills/wix-manage/references/sites/create-headless-site.md +14 -5
  39. package/skills/wix-manage/references/sites/upload-static-site.md +373 -302
  40. package/skills/wix-vibe-headless/references/shared/app/components/WixManageBanner.jsx +3 -3
@@ -0,0 +1,132 @@
1
+ ---
2
+ name: "Automations Mapping Expressions"
3
+ description: "Write builder-compatible automation mapping expressions, literals and data references."
4
+ ---
5
+
6
+ > **Stage scope:** this stage covers only what [Build and Manage Wix Automations](https://dev.wix.com/docs/api-reference/business-management/automations/skills/build-and-manage-wix-automations) lists; do not perform any workflow that needs a guide marked "not yet published". "Stage" and "not yet published" describe how this skill is being rolled out; never mention them to the user. Explain a limit in product terms: what can't be done through the API here and where the user can do it instead (for example, in the automations builder).
7
+
8
+ # Bracket Expressions (Formulas) — `{{…}}`
9
+
10
+ **TL;DR**
11
+
12
+ - `{{expression}}`; fields via `var("dotted.path")` (double quotes, one argument); arguments separated by `;`; string literals in double quotes and URI-encoded.
13
+ - In formula fields (action inputs, set-variable values, delay due dates) use ONLY the builder function list in §2. Conditions and trigger filters have their own, stricter vocabularies — Automations Conditions (not yet published), [Automations Trigger Configuration](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-trigger-configuration) §4.2.
14
+ - The builder type-checks every argument and the arity (§2): `eq`/`gt`/`gte`/`lt`/`lte` take NUMBERS only (strings → `stringEq`, dates → `date*`); `if()`'s first argument is boolean. There are no operators.
15
+ - No array element access in any form. Project with `arrayMap(array;"path")`, aggregate with `array*`. A single-value field can never be filled from an array — ask the user which item.
16
+ - Only data from the step's aggregated schema (trigger + ancestors) is in scope ([Automations Graph and Data Model](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-graph-and-data-model) §4).
17
+
18
+ ---
19
+
20
+ ## 1. Syntax
21
+
22
+ | Form | Example |
23
+ | --------------------------------------------------- | ---------------------------------------------------------------------------- |
24
+ | Literal | `{{"text"}}`, `{{10}}`, `{{true}}`, `{{["a","b"]}}` |
25
+ | Variable | `{{var("contact.name.first")}}` |
26
+ | Function | `{{concat(var("a");" - ";var("b"))}}` |
27
+ | Text with embedded expressions (string fields only) | `Hi {{var("contact.name.first")}}, your total is {{toString(var("total"))}}` |
28
+
29
+ MUST:
30
+
31
+ - Every field access is `var("path")` with ONE argument — `{{fieldName}}` is not supported.
32
+ - Double quotes only (`var('x')` is an unknown variable to the builder). In JSON escape them: `"{{var(\"contact.email\")}}"`.
33
+ - `;` between arguments, no leading/trailing/double `;`, balanced parentheses. No whitespace outside string literals — `{{ concat(…` or `sum( 1;2)` is unreadable to the builder.
34
+ - Numbers: plain decimal literals (`5`, `-3`, `12.5`). Never `0.5`, `.5`, `-0.25`, `05` or `1e3` — the builder's parser rejects them (conditions, filters, delays and rate limits stop loading). Write `divide(1;2)` instead. Percentages follow the same rule: 10% of `x` is `divide(x;10)` and 15% is `divide(multiply(x;15);100)`, never `multiply(x;0.1)`.
35
+ - Path segments may contain hyphens (`var("triggered-emails-1.messageId")`); a space inside a segment is invalid.
36
+ - **URI-encode every string literal inside `{{…}}`** exactly as `encodeURIComponent` does — this is how the builder's panels and the platform store them: `"a@b.com"` → `"a%40b.com"`, `"50%"` → `"50%25"`, `"New York"` → `"New%20York"`, `"&"` → `"%26"`. Letters, digits and `- _ . ! ~ * ' ( )` stay as they are, so uuids and `arrayMap` paths are unchanged. Do NOT encode `var("…")` paths (except in trigger filters, where the filter panel encodes the path too — [Automations Trigger Configuration](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-trigger-configuration)) or text outside `{{…}}`, nor a date-time literal in a formula field (§2). Decode literals when you read an existing automation. Action formula fields display literals as stored, so in string fields keep fixed text outside `{{…}}` (`Hi {{var("contact.name.first")}}, welcome!`) rather than in `concat("…")`.
37
+
38
+ Prefix rules: trigger fields have no prefix; action outputs `"<namespace>.<field>"` (namespace = the step's `namespace`, e.g. `createTask-1`); set variables `"setVariable.<key>"`; identity enrichment `"contact.…"` / `"member.…"`. `siteInfo.*` is not available — don't reference it.
39
+
40
+ ## 2. Functions the builder renders in formula fields (complete list)
41
+
42
+ - **Math**: `sum(n;n;…)` · `subtract(n;n)` · `multiply(n;n;…)` · `divide(n;n)` · `average(n;…)` · `min(n;…)` · `max(n;…)` · `median(n;…)` · `mod(n;n)` · `round(n;decimals)` · `abs(n)` → number · `eq(n;n)` · `gt(n;n)` · `gte(n;n)` · `lt(n;n)` · `lte(n;n)` → boolean (numbers only)
43
+ - **Array**: `arraySize(a)` · `arraySum(a)` · `arrayMultiply(a)` · `arrayAverage(a)` · `arrayMin(a)` · `arrayMax(a)` · `arrayMedian(a)` → number · `arrayMap(a;"item.path")` → array
44
+ - **Text**: `concat(s;s;…)` · `substring(s;start;length)` (0-based) · `lower(s)` · `upper(s)` → string · `stringLen(s)` → number · `stringEq(a;b)` · `stringHasSubString(s;sub)` · `startsWith(s;prefix)` · `endsWith(s;suffix)` · `isEmptyString(s)` → boolean
45
+ - **Date**: `hour(dt)` · `minute(dt)` · `year(d)` · `month(d)` · `day(d)` → number · `weekDay(d)` → lowercase day name · `dateEq/dateBefore/dateAfter(d;d)` (calendar date) · `dateTimeEq/dateTimeBefore/dateTimeAfter(dt;dt)` → boolean · `addToDate(d;years;months;days)` · `subtractFromDate(d;years;months;days)` → date-time · `now()` → date-time string
46
+ - **Format**: `toString(v)` → string · `toNumber(v)` → number
47
+ - **Logic**: `if(bool;then;else)` · `and(b;b;…)` · `or(b;b;…)` · `not(b)` · `isEmpty(v)` (any value, incl. arrays) → boolean (`if` → its branches' value)
48
+
49
+ Arity (write exactly these counts; the builder flags missing and extra arguments for fixed-arity functions): `var`, `not`, `toString`, `toNumber`, `upper`, `lower`, `stringLen`, `abs`, `isEmptyString`, `isEmpty`, every `array*` aggregate = 1 · comparisons, `round`, `subtract`/`divide`/`mod`, `arrayMap` = 2 · `if`, `substring` = 3 (always pass the length) · `addToDate`/`subtractFromDate` = 4 · `now` = 0 · `and`/`or`/`concat`/`sum`/`multiply` ≥ 2 · `min`/`max`/`average`/`median` ≥ 1.
50
+
51
+ Argument types the builder enforces (convert with `toString()`/`toNumber()`):
52
+
53
+ | Parameter | Accepts |
54
+ | ----------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
55
+ | number (math, comparisons, `substring` offsets, date offsets) | number literal, number/integer var, number-returning function; wrap a string `format: number` var (money `value`s) in `toNumber()` — the platform rejects it bare |
56
+ | string (text functions, `concat`) | string literal/var/function — never a number or boolean (wrap in `toString()`) |
57
+ | boolean (`if` arg 1, `and`, `or`, `not`) | comparison, boolean var, `isEmpty`/`isEmptyString`/`startsWith`/… |
58
+ | date (`year`, `month`, `day`, `weekDay`, `dateEq/Before/After`, `addToDate`…) | a var whose schema has `format: date` or `date-time`, a `"YYYY-MM-DD"` literal, or a function (`now()`, `addToDate(…)`) |
59
+ | date-time (`hour`, `minute`, `dateTimeEq/Before/After`) | a var with `format: date-time`, a function, or an ISO date-time literal — a `format: date` var or plain-string var is rejected |
60
+ | array (`array*` functions, `isEmpty`) | array var or `arrayMap(…)`; no other function takes an array argument |
61
+
62
+ An encoded date-time literal (`"2026-12-25T10%3A00%3A00Z"`) is not recognized as a date in a formula field — pass a `"YYYY-MM-DD"` literal or a function, or make the whole field a plain ISO value (§4). This exception is for formula fields only: in a CONDITION the panel itself writes date-time literals encoded and reads both forms (§2 of Automations Conditions (not yet published)).
63
+
64
+ Semantics: `stringEq` and `stringHasSubString` are case-insensitive (normalize with `lower()` if it matters). Booleans: use the value directly (`if(var("isVip");…)`, `not(var("isVip"))`), never `eq(var("isVip");true)`.
65
+
66
+ **Never use in a formula field** (the builder flags them as unknown functions):
67
+ `toEpoch`, `arrayFilter`, `hasSubstring`, `textWithExpressions`, `contains`, `arraySome`, `arrayEvery`, `arrayIncludesAnyOf/AllOf/Only`, `stringContains`, `numberContains`, `boolEq`, `numberEq/numberGt/numberGte/numberLt/numberLte`. (Several of these ARE the condition vocabulary — §2 of Automations Conditions (not yet published) — and `contains`/`arraySome` the trigger-filter vocabulary.)
68
+
69
+ **Do not exist** (never guess): `replace`, `replaceAll`, `trim`, `split`, `join`, `indexOf`, regex/`match`, `ceil`, `floor`, `parseInt`, `parseFloat`, `random`, `filter`, `reduce`, `sort`, `switch`, loops, `try/catch`, `coalesce`, `formatDate`, `formatNumber`, `formatCurrency`, `titleCase`, `add`, `addDays`, `equals`.
70
+
71
+ ## 3. `if()` needs a boolean first argument
72
+
73
+ Valid first arguments: a comparison (`eq`, `gt`, `stringEq`, `dateBefore`, `startsWith`, …), a genuinely boolean field, or `and`/`or`/`not`/`isEmptyString`/`isEmpty`.
74
+
75
+ In number and boolean target fields BOTH branches must return exactly the field's type — a number literal/var/function for a number field. A nested `if` as a branch counts as "any" and is flagged there: wrap it (`toNumber(if(…))`) or, for booleans, use `and`/`or`. Nested `if` is fine in string fields.
76
+
77
+ - ✅ `{{if(stringEq(var("status");"active");"Active";"Inactive")}}`
78
+ - ✅ fallback when the value is missing or empty: `{{if(or(isEmpty(var("contact.name.first"));isEmptyString(var("contact.name.first")));"there";var("contact.name.first"))}}`
79
+ - ❌ `{{if(var("status");…)}}` when `status` is a string · ❌ `{{if("active";…)}}`
80
+
81
+ ## 4. Field-type rules (what the builder accepts per target field)
82
+
83
+ - **string** — Plain text, one expression, or text mixed with any number of `{{…}}`; no expression may return an array.
84
+ - **number / integer (incl. string `format: number`)** — Exactly ONE `{{…}}` covering the whole value, returning a number — or a plain number literal. No surrounding text.
85
+ - **boolean** — Exactly ONE `{{…}}` returning boolean — or `true`/`false`.
86
+ - **date / date-time** — A plain ISO literal without `{{}}` (`2026-12-25T16:00:00Z`), or ONE expression: a function (`now()`, `addToDate(…)`) or a var. For a `date-time` field the var must be `format: date-time` — wrap a `format: date` var as `addToDate(var("d");0;0;0)`.
87
+ - **array / object** — A literal array/object built field by field, or one `{{var("…")}}` of the same shape.
88
+ - **field without `dynamicValuesOptions.enabled` in the UI schema** — Literal only — no `{{…}}` ([Automations Action Configuration](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-action-configuration) §3).
89
+
90
+ A `strict` dynamic field requires the exact return type/format. `skipActionExpression` is `"{{true}}"` or absent.
91
+
92
+ ## 5. Arrays — hard limits
93
+
94
+ - **No element access**: `var("items[0]")`, `var("items.0.name")`, `var("items[0].name")` are all invalid. Don't invent `firstItem`/`items.id` helper paths either.
95
+ - **Projection**: `{{arrayMap(var("order.items");"product.name")}}` — second argument is a quoted literal path (never `$_` or an expression).
96
+ - **Aggregates**: `{{arraySize(var("lineItems"))}}`, `{{arraySum(arrayMap(var("lineItems");"totalPrice.value"))}}`. Never `arraySum(var("items.price"))` — a path cannot cross an array boundary.
97
+ - **No per-element arithmetic** (price × quantity): sum a per-line total field if one exists, else say it is not derivable.
98
+ - **No lists as text**: no `join`; an `arrayMap` result can't go into `concat` or a string field.
99
+ - **Single-value field from an array → impossible.** Ask the user which item or use a user-given value; don't retry array-shaped variants.
100
+ - Empty arrays make `arraySum/arrayMin/arrayMax/arrayMedian/arrayMultiply` fail at runtime.
101
+ - Membership tests (`does the order contain X`) belong in a condition (§3 of Automations Conditions (not yet published)) or, for complex logic, a code condition.
102
+
103
+ ## 6. Dates
104
+
105
+ - `date*` compare calendar dates, `dateTime*` instants (argument formats: §2). `addToDate`/`subtractFromDate` offset by whole years/months/days.
106
+ - "Within N days before X": `{{dateAfter(var("d");subtractFromDate(var("x");0;0;7))}}`. Day differences can't be computed renderably (no `toEpoch`) — use a DELAY, such a comparison, or a code condition.
107
+ - **Annual dates (birthdays)**: never `dateEq(var("birthdate");now())`. Compare month and day: `{{and(eq(month(var("contact.birthdate"));month(now()));eq(day(var("contact.birthdate"));day(now())))}}` — in a formula field; as a condition use code or a boolean set-variable (§4 of Automations Conditions (not yet published)).
108
+ - **Never hardcode a year**; derive it: `{{dateAfter(var("order_date");concat(toString(year(var("order_date")));"-10-31"))}}`. Use `year(now())` only when the rule is about the current calendar year.
109
+ - Windows crossing New Year (Dec 26 – Jan 4): `{{or(and(eq(month(var("d"));12);gt(day(var("d"));25));and(eq(month(var("d"));1);lt(day(var("d"));5)))}}`; pick `gt`/`gte` from the user's wording.
110
+ - Formatting: `{{toString(month(var("d")))}}/{{toString(day(var("d")))}}/{{toString(year(var("d")))}}` in a string field.
111
+
112
+ ## 7. Conversions
113
+
114
+ `toString()` numbers/booleans before text functions; `toNumber()` string `format: number` fields before math; neither converts arrays.
115
+
116
+ ## 8. Workarounds that stay renderable
117
+
118
+ - Strip a known prefix: `{{if(startsWith(var("price");"%24");substring(var("price");1;subtract(stringLen(var("price"));1));var("price"))}}` (`"%24"` is the encoded `"$"`).
119
+ - Title case: `{{upper(substring(var("t");0;1))}}{{lower(substring(var("t");1;subtract(stringLen(var("t"));1)))}}`.
120
+ - Anything needing replace/split/regex/loops → a code condition (for branching) or tell the user it cannot be computed.
121
+
122
+ ## 9. Self-validation checklist (run on every expression)
123
+
124
+ 1. Parses: balanced `{{}}` and parentheses, `;` separators, double-quoted strings, no whitespace outside strings, no `0.x`/`.x`/exponent numbers.
125
+ 2. Every function is in §2 (formula fields), the condition table (conditions) or the filter shapes (filters).
126
+ 3. Arity matches §2 exactly (`substring` 3, `round` 2).
127
+ 4. Argument types match the §2 table: numbers to math/`eq`/`gt`…, strings to text functions (`toString` numbers), dates with the right `format`, arrays only to `array*`/`isEmpty`; `if` arg 1 boolean and, in number/boolean fields, both branches of the field's type; `arrayMap` arg 2 a literal path.
128
+ 5. Every `var()` path exists in the aggregated schema of THIS step (ancestors only). If the unknown path has an array prefix (`items.id` where `items` is an array), element access is inexpressible — stop, don't respell.
129
+ 6. `$_` appears only inside `arraySome`/`arrayEvery` predicates (conditions/filters), bare (never `var($_)` or `$_.x`).
130
+ 7. Result type fits the target field (§4); no array into a single-value field.
131
+ 8. String literals URI-encoded; no single quotes.
132
+ 9. Final gate: Validate Automation returns no mapping errors — it misses some paths and every builder-only rule above, so steps 1–8 are yours.
@@ -1,34 +1,313 @@
1
1
  ---
2
2
  name: "Build and Manage Wix Automations"
3
- description: "Discover installed automation triggers and actions and inspect an automation’s current active status without changing site data."
3
+ description: "Inspect Wix automations and their on/off status, create linear automations from the site’s installed triggers and actions, and turn automations on or off on request."
4
4
  ---
5
5
 
6
+ **Topic guides not yet published:** Automations Feasibility and Planning; Automations Entity and Provider Configuration; Automations Item Selection; Automations Email Actions; Automations Conditions; Automations Delays Variables and Branches; Automations Schemas and Scheduling. References marked “not yet published” refer to procedures that are not in this stage; the general API reference does not contain them. Do not attempt a workflow that requires one of them.
7
+
8
+ This stage supports read-only inspection, creation of immediate, linear APP_DEFINED automations with schema-defined inputs, and turning an automation on or off when the user asks ([Automations Activation Status](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-activation-status)). Configuration updates of saved automations, deletion, execution tests, email/opaque widgets, entity pickers, schedules, conditions and special steps are outside this stage. Do not perform those workflows with this skill. Validation and its numbered checklist are included in this guide. “Stage” and “not yet published” describe how this skill is being rolled out; never mention them to the user. Explain a limit in product terms: what can’t be done through the API here and where the user can do it instead (for example, in the automations builder).
9
+
6
10
  # Build and Manage Wix Automations
7
11
 
8
- Use this guide to discover installed automation capabilities and inspect whether an
9
- automation is active. These are read-only workflows. Creation, configuration edits,
10
- activation and test execution are outside what this skill covers.
11
- Do not perform a write when the user asks only to inspect.
12
+ If a request needs a workflow outside the scope above, explain the limit; do not substitute a
13
+ different business operation. A conditional formula in a schema-enabled input is supported by
14
+ the expression guide; it is not a condition node.
12
15
 
13
- | Request | Load |
16
+ ## Required guides
17
+
18
+ | Task | Guide |
14
19
  | --- | --- |
15
- | Check which triggers/actions are available and what inputs they need | [Automations API Catalog](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-api-catalog) |
16
- | Is an automation turned on? What does its status mean? | [Automations Activation Status](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-activation-status) |
17
-
18
- For a capability check, resolve the site's catalogs, retain the returned app/key identities,
19
- and inspect the selected schemas. A remembered action key is a search hint, not evidence that
20
- the action is installed. State missing prerequisites without offering an unverified substitute.
21
- If a requested action isn't found, report it exactly as the "Bounded fallback" section of
22
- [Automations API Catalog](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-api-catalog) says (scan evidence, "not found" vs "not installed", closest
23
- related actions).
24
- Resolve the trigger once and scan the action catalog once; answer from those results instead
25
- of repeating either call.
26
-
27
- For current status, find the exact automation, Get its returned ID, and report the status
28
- from that response. Every status answer names the automation and its returned ID. Current ACTIVE/INACTIVE status is separate from historical run results.
29
-
30
- Status questions need only Query and Get Automation: don't call the trigger or action catalogs
31
- for them. Query by the exact name with one bounded page before paging further.
32
-
33
- Keep the requested site context fixed. Do not expose tokens or credentials. Tie every claim
34
- to the returned data, and distinguish a missing record from proof of nonexistence.
20
+ | Resolve installed trigger/action identities and API requests | [Automations API Catalog](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-api-catalog) |
21
+ | Construct a single-parent graph, IDs and namespaces | [Automations Graph and Data Model](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-graph-and-data-model) |
22
+ | Configure trigger payload and filters | [Automations Trigger Configuration](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-trigger-configuration) |
23
+ | Check action semantics and effective schemas | [Automations Action Configuration](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-action-configuration) |
24
+ | Type-safe input formulas, literal escaping and ancestor variables | [Automations Mapping Expressions](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-mapping-expressions) |
25
+ | Check status, or turn an automation on or off | [Automations Activation Status](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-activation-status) |
26
+
27
+ ## Check what the site supports (read-only)
28
+
29
+ For "does my site support X / what would I need", resolve the trigger once and scan the action
30
+ catalog once ([Automations API Catalog](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-api-catalog) §6), inspect the chosen schemas, and report the pair
31
+ and the inputs the user would supply. If something isn't found, report it as that section says
32
+ (scan evidence, "not found in the installed catalog", closest related entries). Don't build,
33
+ validate or save a candidate to answer this.
34
+
35
+ ## Create and verify
36
+
37
+ 1. Keep the requested site fixed. Discover the installed catalogs and inspect the exact
38
+ trigger/action schemas. Resolve semantic capability first: an action that retrieves a
39
+ task is not one that creates it. If no suitable installed action exists, report the gap.
40
+ 2. Map the user's values and compatible payload fields. Ask for missing required values;
41
+ never invent IDs or use a display name where an ID is required. An ID or key the user
42
+ supplies (for example a label key for a trigger filter) may be used as given; never call a
43
+ create or find-or-create endpoint (such as Find or Create Label) to check or replace it,
44
+ and if Validate warns that it doesn't exist, keep it and say so in your answer. If Validate
45
+ returns a CRITICAL error for it instead, don't save: tell the user it wasn't found and ask
46
+ them to confirm it. If an action
47
+ is an opaque widget (a `WIDGET_COMPONENT` action whose `inputSchema` does not fully describe
48
+ the request; [Automations Action Configuration](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-action-configuration) §3), or a field needs an entity looked up by name, stop
49
+ at the scope limit above. A `WIDGET_COMPONENT` action whose schema does describe the
50
+ request is hand-authored as that guide's §5.2 explains.
51
+ 3. Construct a linear graph using the model and expression guides. Keep actions within
52
+ 45 nodes. Set `origin: "USER"`, no `settings`, and `configuration.status: "INACTIVE"`.
53
+ 4. Follow **Validation and Verification below**: its §4 checklist is the actual hard gate,
54
+ followed by full Validate, Create and Get read-back (§§2–3). Its numbered items are
55
+ included here so references from other guides can be followed without an unpublished page.
56
+ Items for out-of-scope node types are not permission to create those types.
57
+ 5. Save only with the user's authorization. Report the returned ID, inactive status and
58
+ verified content. If the user asked to turn it on, activate it after the read-back as
59
+ [Automations Activation Status](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-activation-status) describes, then report it active. Do not run a test.
60
+
61
+ The included procedure keeps only the headings of its update and execution-test sections;
62
+ those workflows are published in a later stage, and the stage limits above take precedence.
63
+
64
+
65
+ # Validation and Verification
66
+
67
+ How to prove an automation is correct, saved, and editable in the builder before you tell the
68
+ user it exists. This file owns the create procedure. API shapes: [Automations API Catalog](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-api-catalog).
69
+
70
+ **TL;DR**
71
+
72
+ - Climb the ladder in order: **§4 renderability checklist → Validate Automation → Create →
73
+ Get Automation read-back.**
74
+ - **§4 gates Create and activation.** `VALID` alone does not prove the
75
+ builder can draw, edit and re-save the automation. Status-only deactivation follows §3 and
76
+ must not be blocked by unrelated configuration errors.
77
+ - Create and Update do not validate; an unvalidated or unsaved automation is **not created**.
78
+ - **Later stages only — not in stage 2:** Test Automation executes actions for real.
79
+
80
+ ## 1. Local checks and semantic review
81
+
82
+ Run the §4 checklist on the complete automation object before **every** Validate call. Items
83
+ tagged **[code]** are deterministic — a small script beats reasoning (ids, graph, namespaces,
84
+ `var()` inventory, field limits). The rest need you to read schemas.
85
+
86
+ Semantic review (you, not code) — required for every action before acceptance; full rules in
87
+ [Automations Action Configuration](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-action-configuration) §6:
88
+
89
+ - **Side-effect contract:** the action does what the user's verb says to the affected entity —
90
+ retrieval is not assignment; a message about a change is not the change.
91
+ - **Recipient lineage** (email, chat, SMS, push): prove the recipient path — the trigger contact and
92
+ an upstream-created contact differ even when both are `contactId`; copy never proves who receives
93
+ it; for emails (later stages only — email is outside stage 2) the audience fields decide (§3 of Automations Email Actions (not yet published)).
94
+ - **No fabricated content:** every user-specific value (recipient, subject, entity, amount) comes
95
+ from the user, the site, or the payload.
96
+
97
+ ## 2. Validate Automation
98
+
99
+ Request: `{automation: <full object>, validationSettings?}`. Validate the complete candidate
100
+ you intend to save; an unsaved object doesn't need an id. For creation, set `origin: "USER"`,
101
+ a real `name`, and `configuration.status: "INACTIVE"`. For activation, validate the candidate with
102
+ `configuration.status: "ACTIVE"`. Never rewrite an installed automation's origin or deactivate a live
103
+ automation merely to validate it.
104
+
105
+ `validationSettings.actionIds` validates just the listed actions — useful while configuring node
106
+ by node. `skipProviderValidations: true` skips app-specific checks — acceptable for intermediate
107
+ checks only. **The final gate is always a full validation with no settings.**
108
+
109
+ Response: `status` is `VALID`, `VALID_WITH_WARNINGS` (only `errorSeverity: WARNING`), or
110
+ `INVALID` (at least one `CRITICAL`). Target `VALID`. Accept `VALID_WITH_WARNINGS` only when you
111
+ understand each warning and tell the user about it.
112
+
113
+ **What the builder does with it.** When the user opens the automation, the builder runs the same
114
+ full Validate and pins **every** returned error to its node (trigger or action) — mapping errors
115
+ included. A `CRITICAL` shows as a node error and **blocks Activate / Publish** until fixed; a
116
+ `WARNING` shows as a node warning. Mapping errors show on the step until the user opens it, then
117
+ its form replaces them with field-level marks; other configuration errors show as error/warning
118
+ text; a provider error shows as "title: message". So an automation you save with errors opens
119
+ broken.
120
+
121
+ Each `triggerValidationErrors[]` / `actionValidationErrors[]` item has `errorType`
122
+ (`CONFIGURATION_ERROR` | `PROVIDER_ERROR`), `errorSeverity`, and one of:
123
+
124
+ - `configurationError{errorType, filterFieldKey | fieldKey}` — a platform check (tables below);
125
+ - `providerConfigurationError{title, message, ctaLabel, ctaUrl}` — the owning app's own check
126
+ (`validateConfiguration`; often a missing connection or entity).
127
+ Action errors also carry `actionId`, `appId`, `actionKey`.
128
+
129
+ ### Error types → fix
130
+
131
+ Trigger (`configurationError.errorType`):
132
+
133
+ - `NOT_FOUND`, `INVALID_TRIGGER_KEY` — not in this site's catalog → re-resolve; never guess keys.
134
+ - `APP_NOT_INSTALLED`, `MODERATION_MISMATCH` — not available on this site → tell the user; don't
135
+ substitute silently.
136
+ - `DEPRECATED` — being retired → prefer its replacement, or tell the user.
137
+ - `INVALID_FILTER_FIELD_KEY` — not a filter the trigger defines → use only its `filters[]`.
138
+ - `INVALID_FILTER_EXPRESSION` → rebuild with the filter shapes in [Automations Trigger Configuration](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-trigger-configuration) §4.
139
+ - `MISSING_REQUIRED_FILTER` → add it (ask the user for its value if needed).
140
+
141
+ Action (`configurationError.errorType`, with `fieldKey` — fix the field it names; never delete a
142
+ field to silence an error):
143
+
144
+ - `NOT_FOUND`, `INVALID_ACTION_KEY`, `APP_NOT_INSTALLED`, `MODERATION_MISMATCH` — not available
145
+ on this site → re-resolve; pick another action or tell the user.
146
+ - `DEPRECATED` — the builder shows "Action will be removed soon" → use its replacement
147
+ (§2 of Automations Feasibility and Planning (not yet published)).
148
+ - `INVALID_MAPPING` → remove keys not in the effective schema; re-fetch the dynamic input schema.
149
+ - `MAPPING_TYPE_MISMATCH` → convert (`toString`, `toNumber`), map another field, or build the
150
+ object shape (e.g. MONEY).
151
+ - `MAPPING_MISSING_REQUIRED_FIELD` → map it from the payload or ask the user; never a dummy value.
152
+ - `MAPPING_SCHEMA_MISMATCH` (enum, uuid, email format…) → a legal enum value / real id.
153
+ - `MAPPING_VARIABLE_MISSING_FROM_SCHEMA` → fix the path against the aggregated schema, or reorder
154
+ so the source is an ancestor.
155
+ - `SAMPLE_CODE_RUN_FAILED` → fix the code step (guard missing fields — §5 of Automations Conditions (not yet published)).
156
+ - `POST_ACTION_NOT_FOUND` → a successor id doesn't exist; fix the graph.
157
+
158
+ Create/Update can also fail with `ON_BEFORE_SAVE_ACTION_EXCEPTION`: the owning app's save hook (e.g. for Send an email) rejected the step. Treat it like a provider error — read the message, fix the mapping or tell the user; don't retry the same write blindly.
159
+ `PROVIDER_ERROR` usually needs something only the user can do (connect an account, pick a
160
+ resource, finish setup). Report its `title`/`message` and the `ctaUrl`, and don't loop on it.
161
+
162
+ ### Fix loop
163
+
164
+ 1. Group errors by class (type + node). Fix all independent errors in one pass.
165
+ 2. Re-run the §4 checklist, then re-validate.
166
+ 3. At most 2–3 attempts per class. If an error comes back unchanged, re-read the reference that
167
+ owns that construct rather than trying variations.
168
+ 4. Still failing → stop. Tell the user exactly which node and why, and what you need from them.
169
+ Don't save an INVALID configuration or activate it. Status-only deactivation is still
170
+ allowed under §3; stopping future runs does not require repairing the automation first.
171
+
172
+ ## 3. Persistence, read-back and honest reporting
173
+
174
+ ### Create
175
+
176
+ 1. §4 checklist passes and the final full Validate is `VALID` (or understood warnings).
177
+ 2. Create Automation with `origin: "USER"`, `configuration.status: "INACTIVE"`, no `settings`.
178
+ Capture `id`. Send Create as its own call, after a separate full Validate call has returned
179
+ `VALID` (or understood warnings) — never in the same script as that Validate or as discovery.
180
+ Send it once per candidate: if a Create's outcome is unknown, Query Automations before
181
+ resending it (Reporting rules below). A Create that was never sent is not an attempt.
182
+ 3. **Read back** with Get Automation on the same site. Confirm the trigger, the root id, and the
183
+ set of action ids/types match what you sent (string literals come back URI-encoded, as sent).
184
+ If you used an override schema, Get with `fields: ["OVERRIDE_SCHEMA"]` ([Automations API Catalog](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-api-catalog) §2).
185
+ Run the Get as a separate call once Create has returned (not batched into the same script),
186
+ and keep its response body as returned: the returned `automation` is the evidence, so don't
187
+ replace it with a summary you assemble from selected fields.
188
+ 4. Hand off, leading with the outcome. Make the first line of your answer the saved state, for
189
+ example: "Saved **<name>** as inactive (ID `<automationId>`). Click **Activate** in the
190
+ builder to turn it on: `https://manage.wix.com/dashboard/<metaSiteId>/triggers/edit/<automationId>`".
191
+ That first line MUST name the automation, its status and its ID together; don't move the ID
192
+ to a later line, because a reader may see only the first line.
193
+ Then say what it does, and ask the user to review it in the builder. If the user asked to
194
+ turn it on, activate it first (step 5) and make the first line the active state instead:
195
+ "Saved **<name>** and turned it on (ID `<automationId>`): <edit link>".
196
+ 5. Activate only on request — see "Activation status, activate, deactivate" below.
197
+
198
+ ### Update
199
+
200
+ > **Later stages only:** not available in stage 2; this section is published in stage 3.
201
+
202
+ ### What happens when the user opens it in the builder
203
+
204
+ - The builder edits a **hidden draft copy** and autosaves the user's changes into it. The
205
+ published object (what Get returns) changes only when they click **Activate** (inactive
206
+ automation) or **Publish Changes** (active one) — both publish, and Activate also turns it on.
207
+ - On load it re-resolves every trigger/action from the site catalog ("not found" on a miss), runs
208
+ Validate (§2) plus its own checks (required filters, empty filters, the create-contact rule in
209
+ §4), and pins the results to nodes.
210
+ - On load/save it silently rewrites some shapes: RATE_LIMIT `{{1440}} MINUTES` → `{{24}} HOURS`;
211
+ a webhook trigger filter that is missing or has another id is rebuilt from `webhookId`; unreachable actions and root ids that
212
+ point nowhere are **deleted**; an empty name becomes "Untitled …". The §4 checklist avoids all of
213
+ these, so the user's first save doesn't change your automation.
214
+ - Before you Update an automation the user has been editing in the builder, ask them to publish
215
+ or discard there and close the tab, then Get — else their publish can overwrite your change.
216
+
217
+ ### Activation status, activate, deactivate
218
+
219
+ Read or change status only as [Automations Activation Status](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-activation-status) describes; this guide adds no status
220
+ procedure of its own. Deactivation does not require repairing the configuration.
221
+
222
+ ### Reporting rules
223
+
224
+ - Report separate counts: **attempted**, **acknowledged**, **verified** by read-back, **active**.
225
+ Only verified automations "exist".
226
+ - An id without a successful read-back is **unverified** — say so; don't blindly retry the create
227
+ (Query Automations first to see whether it landed).
228
+ - A validated-but-unsaved object is a proposal, not an automation.
229
+ - Never describe runtime behavior ("it will send…") as verified — only validated.
230
+
231
+ ## 4. Builder-renderability checklist — the single pre-save gate
232
+
233
+ Use this gate before Create and activation, not status-only deactivation.
234
+ Creation restrictions ("never add", conservative feature support) do not require rewriting
235
+ existing builder-supported nodes during an unrelated update. Preserve those nodes and their
236
+ metadata; use the owning reference's preservation rules and full Validate. A failing item is a
237
+ blocker, not a warning: some make the canvas spin forever or crash, others are silently
238
+ rewritten or deleted on the user's first save. Each owning reference has a detailed checklist —
239
+ this list is the union; run those too for the node types you used.
240
+
241
+ **Graph and ids** — [Automations Graph and Data Model](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-graph-and-data-model)
242
+
243
+ 1. [code] Exactly one `rootActionIds` entry, and it exists in `actions`. RATE_LIMIT, if present, is
244
+ that root and the only one.
245
+ 2. [code] Single-parent tree: every successor list (`postActionIds`, `truePostActionIds`,
246
+ `falsePostActionIds`, SPLIT `postActionId`) has ≤ 1 id and points to an existing action; every
247
+ non-root action has exactly one parent and is reachable from the root; no cycles; no MERGE /
248
+ `mergeActionId`. Converging branches = duplicated downstream steps.
249
+ 3. [code] `actions[k].id === k`; ids are fresh uuid v4, unique across actions, SPLIT path ids and
250
+ the trigger key, and never collide with `<id>true`, `<id>false`, `<id>-end`.
251
+ 4. [code] Each action has a known `type`, only its own type's `*Info`, `[]` (not omitted) for an
252
+ ending successor list, and a builder-format `namespace`. Namespaces are unique except that
253
+ SET_VARIABLES steps share `setVariable`; their output keys must be unique across steps.
254
+ For every action type, `skipActionExpression` is `"{{true}}"` or absent.
255
+
256
+ **Trigger** — [Automations Trigger Configuration](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-trigger-configuration) §7
257
+
258
+ 5. `appId`+`triggerKey` came from Resolve Triggers on this site.
259
+ 6. Filters: catalog filter `id`, verbatim `fieldKey`, Shape A/B expression whose literal value array
260
+ holds the form its filter type allows ([Automations Trigger Configuration](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-trigger-configuration) §4.1: quoted entity ids, quoted static
261
+ values, or exactly one bare number/boolean); **no filter with an empty `filterExpression`**; ≤ 5 filters; every required
262
+ filter present, plus required follow-ups of every set parent. Webhook trigger: exactly its
263
+ `webhookId` shape.
264
+ 7. Scheduled / future-date configuration and `scheduledEventOffset` match
265
+ Automations Schemas and Scheduling (not yet published).
266
+
267
+ **Actions** — [Automations Action Configuration](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-action-configuration), Automations Entity and Provider Configuration (not yet published), §2 of Automations Feasibility and Planning (not yet published)
268
+
269
+ 8. Every APP_DEFINED `appId`+`actionKey` came from Resolve Actions on this site; no unsupported
270
+ action added — including no new code-variable step (the public Create refuses it).
271
+ **Later stages only — email is outside stage 2:** New email steps have a provider-generated mapping used once and persisted before content edits; no fabricated opaque-widget mapping; unrelated existing ones unchanged
272
+ (except the documented site-owner audience replacement).
273
+ 9. `inputMapping`: only schema keys (an existing email/widget step's mapping passes through unchanged), types and
274
+ enums match, every required field mapped (optional ones per [Automations Action Configuration](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-action-configuration) §5.2), entity-selector fields hold ids, formulas
275
+ only in `dynamicValuesOptions.enabled` fields.
276
+ 10. No "Create a contact" action (`contacts-create_contact`) when the trigger payload already has
277
+ an `identityType: "contact"` field — the builder marks it "can't create a contact" and blocks
278
+ activation.
279
+
280
+ **Expressions and conditions** — [Automations Mapping Expressions](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-mapping-expressions) §9, §6 of Automations Conditions (not yet published)
281
+
282
+ 11. [code] Every `var()` path exists in that node's aggregated schema
283
+ — trigger + ancestor outputs only — with a compatible type.
284
+ 12. Builder-renderable functions only; `;` separators; double-quoted, URI-encoded string literals;
285
+ number/boolean fields hold exactly one expression of that type.
286
+ 13. CONDITION: exactly one expression group with `AND`/`OR` and 1–20 panel-renderable expressions;
287
+ not both branches empty; otherwise a CODE_CONDITION.
288
+
289
+ **Special steps** — Automations Delays Variables and Branches (not yet published)
290
+
291
+ 14. DELAY: exactly one mode — relative (`offsetExpression` a `{{N}}` literal + unit) or absolute
292
+ (`dueDateExpression`). RATE_LIMIT: `{{1}}`, a trigger identifier allowed by
293
+ §2 of Automations Delays Variables and Branches (not yet published) (preserve existing supported member/user/UUID identifiers), and a
294
+ duration (`{{24}} HOURS`, never `{{1440}} MINUTES`) unless the user explicitly wants
295
+ "only ever once" (no duration).
296
+ SET_VARIABLES: matching keys, every property has a `title`, keys unique across all variable
297
+ steps; preserve existing image-variable metadata per §3 of Automations Delays Variables and Branches (not yet published).
298
+ SPLIT: 2–10 paths.
299
+
300
+ **Object and limits**
301
+
302
+ 15. [code] Text limits: `name` 1–100 chars (API allows 500; the builder's name field holds 100),
303
+ `description` ≤ 2000, action `displayName` 1–60, `namespace` ≤ 100, SPLIT path `name` ≤ 100.
304
+ Expression limits: condition expression ≤ 5000 chars (a longer one fails the builder's save),
305
+ code ≤ 1000, filter expression ≤ 5000, `skipActionExpression`/delay/rate-limit expressions ≤ 1000.
306
+ Step count: ≤ 45 actions of any type — at 45 the builder blocks adding or duplicating steps.
307
+ Count before duplicating downstream steps into each branch.
308
+ 16. On create: `origin: "USER"`, no `settings` (never `hidden` or `readonly`).
309
+ 17. Full Validate Automation returns no `CRITICAL` errors, and you can explain every `WARNING`.
310
+
311
+ ## 5. Test Automation — only with explicit authorization
312
+
313
+ > **Later stages only:** not available in stage 2; this section is published in stage 3.