@wix/agent-skills 1.7.0 → 1.9.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 (126) hide show
  1. package/README.md +3 -7
  2. package/package.json +1 -1
  3. package/skills/wix-app/SKILL.md +2 -0
  4. package/skills/wix-app/references/EDITOR_REACT_COMPONENT.md +2 -1
  5. package/skills/wix-app/references/STORES_VERSIONING.md +1 -0
  6. package/skills/wix-app/references/editor-react-component/ACCESSIBILITY.md +14 -0
  7. package/skills/wix-app/references/editor-react-component/REACT-GUIDELINES.md +11 -6
  8. package/skills/wix-app/references/editor-react-component/REACT-PATTERNS.md +3 -17
  9. package/skills/wix-app/references/editor-react-component/SSR.md +119 -0
  10. package/skills/wix-design-system/SKILL.md +5 -1
  11. package/skills/wix-headless/SKILL.md +55 -32
  12. package/skills/wix-headless/references/BUILD-astro.md +244 -0
  13. package/skills/wix-headless/references/BUILD-own-build.md +167 -0
  14. package/skills/wix-headless/references/BUILD.md +50 -252
  15. package/skills/wix-headless/references/DESIGN_SYSTEM.md +94 -34
  16. package/skills/wix-headless/references/DISCOVERY-connect.md +55 -0
  17. package/skills/wix-headless/references/DISCOVERY-create.md +238 -0
  18. package/skills/wix-headless/references/DISCOVERY.md +41 -422
  19. package/skills/wix-headless/references/PLAN-connect.md +19 -0
  20. package/skills/wix-headless/references/PLAN-create.md +17 -0
  21. package/skills/wix-headless/references/PLAN.md +37 -27
  22. package/skills/wix-headless/references/SEED.md +27 -18
  23. package/skills/wix-headless/references/SETUP.md +32 -213
  24. package/skills/wix-headless/references/astro/blog/BLOG_PAGES.md +5 -4
  25. package/skills/wix-headless/references/astro/bookings/COMPONENTS.md +45 -0
  26. package/skills/wix-headless/references/astro/bookings/SERVICES_PAGES.md +58 -0
  27. package/skills/wix-headless/references/astro/cms/CMS_FOUNDATIONS.md +5 -5
  28. package/skills/wix-headless/references/astro/cms/FAQ_KNOWLEDGE_BASE.md +10 -10
  29. package/skills/wix-headless/references/astro/cms/PORTFOLIO.md +12 -13
  30. package/skills/wix-headless/references/astro/cms/RESOURCE_LIBRARY.md +10 -12
  31. package/skills/wix-headless/references/astro/cms/TEAM_DIRECTORY.md +8 -8
  32. package/skills/wix-headless/references/astro/designer/INSTRUCTIONS.md +47 -27
  33. package/skills/wix-headless/references/astro/ecom/CART_PAGES.md +7 -8
  34. package/skills/wix-headless/references/astro/ecom/CART_WIRING.md +5 -5
  35. package/skills/wix-headless/references/astro/ecom/COMPONENTS_CSS.md +3 -3
  36. package/skills/wix-headless/references/astro/forms/CONTACT_FORM.md +5 -19
  37. package/skills/wix-headless/references/astro/gift-cards/COMPONENTS.md +2 -2
  38. package/skills/wix-headless/references/astro/gift-cards/PAGES.md +1 -1
  39. package/skills/wix-headless/references/astro/stores/BACK_IN_STOCK.md +6 -6
  40. package/skills/wix-headless/references/astro/stores/CATEGORY_PAGES.md +4 -4
  41. package/skills/wix-headless/references/astro/stores/COMPONENTS_CSS.md +3 -3
  42. package/skills/wix-headless/references/astro/stores/HOME_AND_NAV.md +3 -3
  43. package/skills/wix-headless/references/astro/stores/PRODUCT_PAGES.md +9 -9
  44. package/skills/wix-headless/references/astro/stores/SHARED_WIRING.md +5 -4
  45. package/skills/wix-headless/references/astro/templates/Footer.astro +1 -1
  46. package/skills/wix-headless/references/astro/templates/Layout.astro +1 -1
  47. package/skills/wix-headless/references/astro/templates/Navigation.astro +1 -1
  48. package/skills/wix-headless/references/astro/templates/astro.config.mjs +1 -1
  49. package/skills/wix-headless/references/astro/templates/bookings/AvailabilityCalendar.tsx +233 -0
  50. package/skills/wix-headless/references/astro/templates/bookings/BookingForm.tsx +136 -0
  51. package/skills/wix-headless/references/astro/templates/bookings/SeoTags.astro +25 -0
  52. package/skills/wix-headless/references/astro/templates/bookings/ServiceBookingFlow.tsx +54 -0
  53. package/skills/wix-headless/references/astro/templates/bookings/ServiceCard.astro +45 -0
  54. package/skills/wix-headless/references/astro/templates/bookings/booking-confirmation.astro +49 -0
  55. package/skills/wix-headless/references/astro/templates/bookings/bookingDriver.ts +245 -0
  56. package/skills/wix-headless/references/astro/templates/bookings/components-bookings.css +356 -0
  57. package/skills/wix-headless/references/astro/templates/bookings/services/[slug].astro +133 -0
  58. package/skills/wix-headless/references/astro/templates/bookings/services/index.astro +73 -0
  59. package/skills/wix-headless/references/astro/templates/global.css +2 -2
  60. package/skills/wix-headless/references/astro/templates/index.astro +1 -1
  61. package/skills/wix-headless/references/blog/BLOG_CONTENT.md +19 -9
  62. package/skills/wix-headless/references/blog/INSTRUCTIONS.md +3 -3
  63. package/skills/wix-headless/references/bookings/FLOW.md +185 -0
  64. package/skills/wix-headless/references/bookings/INSTRUCTIONS.md +90 -0
  65. package/skills/wix-headless/references/bookings/SERVICES_DATA.md +295 -0
  66. package/skills/wix-headless/references/cms/CMS_FOUNDATIONS.md +4 -2
  67. package/skills/wix-headless/references/cms/INSTRUCTIONS.md +27 -1
  68. package/skills/wix-headless/references/commands/known-apps.json +2 -1
  69. package/skills/wix-headless/references/custom/CONNECTION_PLAN.md +142 -0
  70. package/skills/wix-headless/references/custom/INSTRUCTIONS.md +71 -21
  71. package/skills/wix-headless/references/custom/blog/WIRING.md +52 -0
  72. package/skills/wix-headless/references/custom/bookings/WIRING.md +146 -0
  73. package/skills/wix-headless/references/custom/cms/WIRING.md +97 -0
  74. package/skills/wix-headless/references/custom/ecom/WIRING.md +67 -0
  75. package/skills/wix-headless/references/custom/forms/WIRING.md +101 -0
  76. package/skills/wix-headless/references/custom/stores/WIRING.md +80 -0
  77. package/skills/wix-headless/references/ecom/INSTRUCTIONS.md +5 -5
  78. package/skills/wix-headless/references/forms/INSTRUCTIONS.md +2 -2
  79. package/skills/wix-headless/references/gift-cards/INSTRUCTIONS.md +3 -3
  80. package/skills/wix-headless/references/images/INSTRUCTIONS.md +16 -15
  81. package/skills/wix-headless/references/seed-recipes.md +2 -2
  82. package/skills/wix-headless/references/shared/AGENTS_MD.md +47 -0
  83. package/skills/wix-headless/references/shared/AUTHENTICATION.md +3 -5
  84. package/skills/wix-headless/references/shared/DESIGN_MD.md +85 -0
  85. package/skills/wix-headless/references/shared/IMAGE_GENERATION.md +29 -28
  86. package/skills/wix-headless/references/shared/IMPLEMENTER.md +87 -27
  87. package/skills/wix-headless/references/shared/PRODUCTION_SHARP_EDGES.md +2 -2
  88. package/skills/wix-headless/references/shared/RETURN_CONTRACT.md +24 -313
  89. package/skills/wix-headless/references/shared/STYLING.md +8 -18
  90. package/skills/wix-headless/references/stores/INSTRUCTIONS.md +39 -9
  91. package/skills/wix-headless/references/stores/PRODUCT_CATALOG_DATA.md +17 -14
  92. package/skills/wix-headless/references/verticals/_schema.json +1 -1
  93. package/skills/wix-headless/references/verticals/_schema.md +3 -3
  94. package/skills/wix-headless/references/verticals/blog.md +1 -1
  95. package/skills/wix-headless/references/verticals/bookings.md +39 -0
  96. package/skills/wix-headless/references/verticals/cms.md +1 -1
  97. package/skills/wix-headless/references/verticals/ecom.md +2 -2
  98. package/skills/wix-headless/references/verticals/gift-cards.md +1 -1
  99. package/skills/wix-headless/references/verticals/stores.md +1 -1
  100. package/skills/wix-headless/scripts/check-manifest.mjs +143 -6
  101. package/skills/wix-headless/scripts/compose.mjs +540 -0
  102. package/skills/wix-headless/scripts/emit-design-tokens.mjs +128 -51
  103. package/skills/wix-headless/scripts/flatten.sh +61 -0
  104. package/skills/wix-headless/scripts/generate-images.mjs +242 -0
  105. package/skills/wix-headless/scripts/scaffold.sh +47 -16
  106. package/skills/wix-headless/scripts/write-decorative-json.mjs +62 -0
  107. package/skills/wix-manage/SKILL.md +13 -1
  108. package/skills/wix-manage/references/app-installation/install-wix-apps.md +3 -27
  109. package/skills/wix-manage/references/blog/how-to-create-blog-posts.md +1 -1
  110. package/skills/wix-manage/references/bookings/create-appointment-service.md +266 -0
  111. package/skills/wix-manage/references/bookings/create-booking-service-from-prompt.md +37 -0
  112. package/skills/wix-manage/references/bookings/create-class-service.md +245 -0
  113. package/skills/wix-manage/references/bookings/create-course-service.md +249 -0
  114. package/skills/wix-manage/references/cms/cms-data-items-crud.md +3 -2
  115. package/skills/wix-manage/references/cms/cms-references-and-relationships.md +1 -1
  116. package/skills/wix-manage/references/cms/cms-schema-management.md +2 -2
  117. package/skills/wix-manage/references/domains/domain-search-and-purchase.md +10 -7
  118. package/skills/wix-manage/references/forms/create-form.md +49 -1
  119. package/skills/wix-manage/references/stores/bulk-create-products-with-options.md +1 -1
  120. package/skills/wix-manage/references/stores/create-product-from-image.md +154 -2
  121. package/skills/wix-manage/references/stores/setup-online-store-catalog-v3.md +1 -1
  122. package/skills/wix-headless/references/astro/COMPOSE.md +0 -142
  123. package/skills/wix-headless/scripts/finalize-run-json.mjs +0 -141
  124. package/skills/wix-headless/scripts/init-site-json.mjs +0 -101
  125. package/skills/wix-headless/scripts/preview.sh +0 -45
  126. package/skills/wix-headless/scripts/release.sh +0 -73
@@ -0,0 +1,244 @@
1
+ # Build — astro framework class (`frontendBuild === "wix"`)
2
+
3
+ The post-approval conductor for the **astro-native** class (`create × astro` — the skill scaffolds and writes the site). Opened from `BUILD.md` when the run routes on `frontendBuild === "wix"`. Owns the astro flow: Setup → design-system bridge → Seed → build wave → Build → Release. Read top to bottom from approval.
4
+
5
+ This file hosts the astro-create **bootstrap cell** (run-step 0: `scaffold.sh` → `npm create @wix/new@latest headless`) and **wiring cell** (the build wave). Shared with the own-build class via `BUILD.md`: **Subagent rate / credit limits**, the **parallel-batch diagnostic**, the **Final Message** (summary + `AGENTS.md`), and the **Shared release tail**. Pre-approval flow + the **Two tracks** / **Batching discipline** / **User-facing output** rules live in `PLAN.md`.
6
+
7
+ ## Phase axis
8
+
9
+ Each phase is one of the two tracks (`PLAN.md` § "Two tracks"); all are background.
10
+
11
+ | Phase | Track | Tier | What | When |
12
+ |---|---|---|---|---|
13
+ | **1 — Seed** | business | Fast | Per-pack seeders → orchestrator collects `seeded` map in scratch | Seed wave |
14
+ | **2 — Design System** | frontend | Default (Designer) | **Designer** returns tokens + brand-voice JSON (authors `DESIGN.md`, no other files); **`compose.mjs`** (script, no subagent) writes the 6 files from it | Designer: run-step 0 · compose.mjs: Setup-window bridge |
15
+ | **Image 1 — Decorative** | frontend | Fast | Hero/about/page-header decoratives | Seed wave (imagery-gated) |
16
+ | **3 + 4 — Components + Pages (merged)** | frontend | Default | One merged "build" agent per vertical writes its islands **then** the routes that mount them | Build wave (§ "Step 4.5") |
17
+ | **Image 2 — Entity** | business | Fast | Product/blog/CMS images PATCHed onto Wix entities | Build wave (imagery-gated) |
18
+
19
+ > **Set the model tier on every dispatch** (`SKILL.md` § "Subagent model tier", by table lookup). Tier is the dispatch primitive's model parameter, not the prompt — omit it and Default-tier roles silently run under-powered.
20
+
21
+ ## The run from approval (Setup → Release)
22
+
23
+ The contract lives in scratch — no disk snapshot. Nothing is dispatched yet (the funnel presented the plan fast).
24
+
25
+ ### 0. Dispatch scaffold + Designer (background, one concurrent batch on entry)
26
+
27
+ Independent — fire together (`PLAN.md` § "Batching discipline"):
28
+ - **Scaffold** — `scaffold.sh <folder-name> "<brand>" --frontend <value>` (background; capture `scaffold_handle` + its stderr tempfile). Folder-name + command shape: `DISCOVERY-create.md` § "After Q1". It **flattens the project into CWD** — one folder, one `.wix/`, no subdir to `cd` into (`SKILL.md` § "Path resolution"). `npm install` is **not** chained here (Setup Step 4c). The stderr tempfile is for post-hoc error inspection only — not a progress file to poll.
29
+ - **Designer** — background; capture `designer_handle`. Instruction file = `<SKILL_ROOT>/references/DESIGN_SYSTEM.md` (the subagent opens it — do **not** Read it in the orchestrator). Inline Discovery's aesthetic craft from scratch (brand, aesthetic direction, palette, type, mood, page color strategy). Pass `designMdPath` = `<cwd>/DESIGN.md`. The Designer **authors `DESIGN.md`** (frontmatter = the tokens) and returns only `data.shell` + `designMdPath` — tokens never round-trip through your output. Judgment-only (~10–15 s). Do **not** pass application inputs (packs, nav links) — those go to `compose.mjs`.
30
+
31
+ ### 1. Setup Step 1 (foreground)
32
+
33
+ `SETUP.md` Step 1 only: wait `scaffold_handle` (load `wix-manage` in the same batch), then hold `siteId`/`appId` (from `wix.config.json`) in scratch. Do **not** run Setup Step 4 yet — it goes in run-step 2. **Wait = await the harness completion notification; never sleep-poll a handle**.
34
+
35
+ ### 2. Setup window — bridge + platform batch as ONE concurrent message
36
+
37
+ The whole Setup window is a single message of sibling `Bash` calls — **emit them, don't plan them.** It is order-free; the only failure mode is spending a turn deciding an order it doesn't have. The moment Setup Step 1 returns and the Designer has returned, fire the bridge **and** the platform batch together. `designer_handle` authored `DESIGN.md`; the bridge scripts read it directly — never re-emit tokens in your output.
38
+
39
+ **Frontend bridge — one `Bash` call, two deterministic scripts (both read `DESIGN.md`):**
40
+
41
+ 1. `emit-design-tokens.mjs <project-dir>` — projects `.wix/design-tokens.css` + `.wix/site.d.ts` from `DESIGN.md` frontmatter (format: `references/shared/DESIGN_MD.md`). Does not write `DESIGN.md`.
42
+ 2. `compose.mjs` — app inputs on **stdin**, project dir as `argv[2]`. Reads `DESIGN.md` frontmatter (the single token source; roles map to the wix `--color-*` vocabulary) and substitutes into the six pinned skeletons — `global.css`, `astro.config.mjs` (anchored **merge**, not clobber), `Layout.astro`, `Navigation.astro`, `Footer.astro`, `index.astro`. Prints a `{status, phase:"compose", data, files}` manifest to **stdout** — parse it there. **astro-only** (defensive — non-astro classes never reach here); else record `{phase:"compose", status:"skipped"}`. Idempotent; derives any role the Designer omitted as a fail-safe.
43
+
44
+ ```bash
45
+ node <SKILL_ROOT>/scripts/emit-design-tokens.mjs "<project-dir>"
46
+
47
+ node <SKILL_ROOT>/scripts/compose.mjs "<project-dir>" <<'COMPOSE'
48
+ {
49
+ "shell": { ...the Designer's data.shell... },
50
+ "brand": { "name": "<brand>", "description": "<one-line context>" },
51
+ "navLinks": [ { "href": "/", "label": "Home" }, ... ],
52
+ "loadedPacks": ["stores", "cms", ...],
53
+ "packsWithComponents": ["stores", "ecom", ...],
54
+ "disabledPacks": ["gift-cards", ...]
55
+ }
56
+ COMPOSE
57
+ ```
58
+
59
+ The compose-input shape is documented in `scripts/compose.mjs`'s header.
60
+
61
+ **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
+
63
+ 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.
64
+ 4. `Bash` — `npx @wix/cli@latest env pull --json` → `SETUP.md` § Step 4b (`--json` suppresses the spinner that bloats context).
65
+ 5. `Bash` (background) — `npm install …`, capture `npm_handle` + stderr tempfile → package set in `SETUP.md` § Step 4c. Trust the exit code at the seed gate — do not probe `node_modules`.
66
+
67
+ ### 3. Seed wave + 4. Seed gate
68
+
69
+ See § "Wave 3" below for the dispatch. The **seed gate**: wait on the seeders + `npm_handle`; aggregate seeder returns into the `seeded` scratch map. Run `patch-decorative-slots.mjs` only when `imagery === "ai-generated"` and Image Phase 1 returned; else skip + record `{phase:"decorative-slot-patch", status:"skipped"}`.
70
+
71
+ **Write `.wix/seeded.json` here — once, at the gate, before any reader dispatches** (one `Write`, conductor is sole writer). It is the producer→consumer handoff the build-wave readers pull from (§ "The `.wix/seeded.json` handoff"). The gate barriers all seeders before this write and the build wave dispatches only after it, so no reader sees a missing/partial file. Skipped packs → `{"<pack>": {"status":"skipped"}}` so a reader can tell "seeded nothing" from "not written yet" (the latter must never happen).
72
+
73
+ ### 5. Continue → the build wave (§ "Step 4.5") → Build & Release → Final message.
74
+
75
+ ## Imagery gates
76
+
77
+ `imagery` (`"ai-generated"` | `"themed-blocks"`, captured `DISCOVERY.md` Q2.5, default `"themed-blocks"`) gates **both** image phases. The conductor owns the gate.
78
+
79
+ - **Image Phase 1 — Decorative** (Wave-3 batch): dispatch the `image-phase-1-decorative` subagent (`<SKILL_ROOT>/references/images/INSTRUCTIONS.md`) **only on `ai-generated`**. On `themed-blocks`: don't dispatch (slots render as tokenised color blocks via compose-emitted CSS), record `{phase:"image-phase-1-decorative", status:"skipped", notes:"themed-blocks mode"}`, and skip `patch-decorative-slots.mjs`. Dispatching regardless wastes ~140–175 s + ~0.3–0.5 Wix AI credits.
80
+ - **Image Phase 2 — Entity** (build-wave batch): same gate — dispatch only on `ai-generated`; on `themed-blocks` skip + record `{phase:"image-phase-2-entity", status:"skipped"}`. Dispatch + build gate: § "Step 4.5" and § "Wait: build wave → Build".
81
+
82
+ ---
83
+
84
+ ## Wave 3 — Seed + frontend prep + Image Phase 1
85
+
86
+ One concurrent batch (`PLAN.md` § "Batching discipline"). No design-system work here — `compose.mjs` already wrote the six files in the bridge.
87
+
88
+ - `seed-utilities.sh --template astro` — frontend project prep (idempotent), from the project dir. `SEED.md` § "Pre-batch".
89
+ - Per-pack seed subagents (background) — `SEED.md` recipe map + seeder prompt template.
90
+ - Image Phase 1 Decorative (background) — only on `ai-generated` (§ "Imagery gates").
91
+
92
+ ### Subagent dispatch
93
+
94
+ Base prompt fields: `SEED.md` § "Subagent prompt template". Each merged build agent is dispatched with *"read your `<vertical>` slice from `.wix/seeded.json`"* — the page side reads its slice itself (§ "The `.wix/seeded.json` handoff") — and *"read `.wix/design-tokens.css` for the token vocabulary"*; the orchestrator does **not** inline the token block (§ "Styling contract coordination"). (Image Phase 2's single slice stays inlined.) Subagents read no shared state except their own `.wix/seeded.json` slice and the on-disk design-token artifacts (read-only).
95
+
96
+ **`Instruction file` per loaded vertical** (one merged build agent each, writes components then pages in one dispatch):
97
+ - `stores/INSTRUCTIONS.md` — components + pages (private pages merge; `pages-home-and-nav` is the serialized shell agent)
98
+ - `ecom/INSTRUCTIONS.md` — components + cart/thank-you pages + CartBadge nav mount (shell chain; passive, required by stores)
99
+ - `cms/INSTRUCTIONS.md` — CMS pages (no components scope)
100
+ - `blog/INSTRUCTIONS.md` — components + pages (private — own `src/pages/blog/*`)
101
+ - `forms/INSTRUCTIONS.md` — components + pages (private)
102
+ - `bookings/INSTRUCTIONS.md` — components + pages (shell chain — patches `Navigation.astro` `<!-- nav:links -->` + `index.astro` `<!-- home:bookings -->`)
103
+ - `gift-cards/INSTRUCTIONS.md` — components + pages (shell chain; passive/dashboard-gated)
104
+ - `images/INSTRUCTIONS.md` — `image-phase-1-decorative` + `image-phase-2-entity` (image subagents also get: page list, entity types to cover)
105
+ - `DESIGN_SYSTEM.md` — Phase 2 Designer (no Composer subagent — `compose.mjs` writes the six files)
106
+ - `astro/designer/INSTRUCTIONS.md` — page-design spec applied by the merged build agents while writing routes (not a separate dispatch)
107
+
108
+ Merged build agents **read `.wix/design-tokens.css` from disk** for the token vocabulary (gate-verified present at § "Step 4.5") — the orchestrator does **not** inline the styling-contract block (§ "Styling contract coordination").
109
+
110
+ **Every subagent ends with the return contract** (`references/shared/RETURN_CONTRACT.md`); the orchestrator parses each return as it arrives. Put the closing line in the dispatch prompt **verbatim** — it's the only copy a leaf agent is guaranteed to see:
111
+
112
+ ```
113
+ Return contract (your sole output channel — end your message with this fenced JSON block; it MUST be the last content, no trailing prose, no "**What was done:**" recap after it):
114
+ { ...the data shape for your scope, per references/shared/IMPLEMENTER.md § "Return contract"... }
115
+ ```
116
+
117
+ ---
118
+
119
+ ## The `.wix/seeded.json` handoff
120
+
121
+ Seeded entity IDs reach the build-wave Page readers through a **write-once, read-only shared artifact** — not by re-inlining a slice into every prompt. The conductor writes it once at the seed gate; each reader reads its own `<vertical>` slice. (Image Phase 2 keeps its inlined slice; Phase 3 Components need no seeded IDs.) It is a safe exception to the "inputs inlined / don't read shared state" rule.
122
+
123
+ **Scope of the exception (all three must hold):**
124
+ - exactly one writer — the conductor at the seed gate, before any reader dispatch;
125
+ - readers read only their own `<vertical>` slice; no reader writes the file;
126
+ - it carries seeded entity IDs only, never observability fields.
127
+
128
+ **Location:** `.wix/` (outside the Astro/Vite bundler root, so it never ships to `dist/` — same as `.wix/design-tokens.css`). Readers `Read` it to author code (slugs, `getStaticPaths`, demo content); pages query the live SDK at request time and **must not `import` it** into route files.
129
+
130
+ **Schema** — one top-level key per loaded pack, mirroring the `seeded` scratch map:
131
+
132
+ ```json
133
+ {
134
+ "stores": { "products": [{ "id": "...", "name": "...", "slug": "...", "variantId": "...", "price": 0 }], "productIds": ["..."], "categoryIds": ["..."] },
135
+ "cms": { "collectionIds": { "about": "...", "faq": "..." }, "itemIds": { "about": ["..."], "faq": ["..."] } },
136
+ "blog": { "postIds": ["..."], "categoryIds": ["..."] },
137
+ "forms": { "formIds": ["..."] }
138
+ }
139
+ ```
140
+
141
+ Packs that seeded nothing → `{"<pack>": {"status":"skipped"}}`. Exact per-pack keys = the seeders' `Returns` column in `SEED.md` § "Recipe map".
142
+
143
+ **Reader failure mode (fail loud):** a reader asserts its slice is present before using it. If the file or slice is absent → `status:"partial"`, `errors:[{code:"SEEDED_JSON_SLICE_MISSING", missing:"seeded.<vertical>"}]`. Do **not** render an empty page or fall back to re-querying via curl — a missing slice means an upstream phase didn't complete.
144
+
145
+ ---
146
+
147
+ ## Step 4.5 — the build wave (Components + Pages merged per vertical) + Image Phase 2
148
+
149
+ ONE wave of per-vertical "build" agents, each writing its **components first, then the pages that mount them** — the within-agent write-order replaces the old cross-agent barrier, so the orchestrator never re-enters between components and pages. Image Phase 2 rides this wave. All background.
150
+
151
+ **Gate (from the seed gate):** `seeded` populated, `.wix/seeded.json` written, bridge run. Verify **both** `.wix/design-tokens.css` **and** `.wix/site.d.ts` exist on disk, and `compose.mjs` wrote `src/layouts/Layout.astro` + `src/styles/global.css`. If a design-tokens file is missing, do not dispatch — surface the path and stop. (Each merged build agent reads `.wix/design-tokens.css` itself for the token vocabulary — the orchestrator does **not** read it or inline it into dispatch prompts, which would re-emit the full token block once per agent for no benefit; the cascade reaches components through `global.css`, not the prompt.)
152
+
153
+ ### Pre-batch (same message, before dispatches) — ALL pre-copies up front
154
+
155
+ **1 · Per-pack component-CSS templates** (deterministic `cp`; static `var(--token)` CSS, no subagent). `compose.mjs`'s Layout imports `src/styles/components-<pack>.css` for every pack with `components`; **skip this and `astro build` fails with `Could not resolve "../styles/components-<pack>.css"`.** For each loaded pack with a `components` scope (today: `stores`, `ecom`, `blog`, `forms`, `gift-cards`, `bookings`):
156
+
157
+ ```bash
158
+ for pack in <loaded packs with components>; do
159
+ cp "<SKILL_ROOT>/references/astro/templates/$pack/components-$pack.css" \
160
+ "src/styles/components-$pack.css"
161
+ done
162
+ ```
163
+
164
+ Idempotent. Packs without a template (`cms` — SSR inline) are skipped silently.
165
+
166
+ **2 · Pre-copied utility templates** (both components- and pages-phase utils, since one agent imports both). Each vertical's INSTRUCTIONS lists files under "Pre-copied by the orchestrator (do NOT write these yourself)":
167
+
168
+ ```bash
169
+ # stores (loaded)
170
+ cp "<SKILL_ROOT>/references/astro/templates/stores/back-in-stock.ts" "src/utils/back-in-stock.ts"
171
+ cp "<SKILL_ROOT>/references/astro/templates/stores/categories.ts" "src/utils/categories.ts"
172
+ # ecom (loaded)
173
+ cp "<SKILL_ROOT>/references/astro/templates/ecom/discounts.ts" "src/utils/discounts.ts"
174
+ # bookings (loaded) — the booking SDK module + SeoTags
175
+ cp "<SKILL_ROOT>/references/astro/templates/bookings/bookingDriver.ts" "src/components/bookingDriver.ts"
176
+ cp "<SKILL_ROOT>/references/astro/templates/bookings/SeoTags.astro" "src/components/SeoTags.astro"
177
+ ```
178
+
179
+ `categories.ts` is imported by `pages-categories`/`pages-products`/`pages-home-and-nav`; `back-in-stock.ts` by stores components; `discounts.ts` by ecom components + stores product pages; `bookingDriver.ts` (the ecom-Cart-V2 booking sequence — `book()`/`navigateToCheckout()`) by the bookings islands, and `SeoTags.astro` by `services/[slug].astro`. Static, brand-agnostic SDK wrappers — if not pre-copied, multiple scopes race to author them.
180
+
181
+ ### Dispatch the wave — one concurrent batch (private agents) + a serialized shell chain alongside it
182
+
183
+ One merged "build" agent per loaded vertical (Instruction file = that vertical's `INSTRUCTIONS.md`), owning its `components` scope **and** its private `pages` scopes, written islands-first then pages. Split by whether the agent's scopes touch a **shared shell** (`src/components/Navigation.astro` or `src/pages/index.astro`):
184
+
185
+ **A · Concurrent batch — agents that own only private files:**
186
+ - **stores-build** — `components` (AddToCartButton, ProductPurchase, BackInStockForm, SeoTags) → `pages-categories` (`category/[slug].astro`, `CategoryRail.astro`) → `pages-products` (`products/index.astro`, `products/[slug].astro`, `ProductCard.astro`). **Write order matters: islands → `pages-categories` (writes `CategoryRail.astro`) → `pages-products` (mounts it)** — every import a later scope mounts is already on disk.
187
+ - **blog-build** — `components` (blog service module, RicosViewer, consts) → `pages` (listing, detail, RSS, BlogPost layout, all under `src/pages/blog/*`). No `home:` marker → no shared-shell patch, stays concurrent.
188
+ - **cms-build** — `pages` (About + FAQ wired to live `@wix/data`). No `components` scope.
189
+ - **forms-build** — `components` (ContactForm island) + `pages` (`contact.astro`, private).
190
+
191
+ **B · Serialized shell chain — agents that patch `Navigation.astro` / `index.astro`** (read-modify-write a shared file → concurrent dispatch trips the staleness guard `File has been modified since read`, **per-file, not per-marker**). **Launch one, wait for its return, launch the next** — each sees the previous one's insertion. Runs **alongside** batch A, not after it. The shell-patchers (today): **ecom, stores `pages-home-and-nav`, bookings, gift-cards** — exactly the packs with `nav:`/`home:` markers:
192
+ - **ecom-build** — `components` (CartView, CartBadge) → `pages` (`cart.astro`, `thank-you.astro` private, **+ CartBadge mount in `Navigation.astro` at `<!-- nav:actions -->`**).
193
+ - **stores-home-and-nav** — patch `index.astro` product grid at `<!-- home:stores -->` + `Navigation.astro` Shop submenu at `<!-- nav:links -->`. Writes no islands; pure shell-patcher.
194
+ - **bookings-build** — `components` (AvailabilityCalendar, BookingForm, ServiceBookingFlow islands; `bookingDriver.ts` + `SeoTags.astro` are pre-copied) → `pages` (`services/index.astro`, `services/[slug].astro`, `ServiceCard.astro`, `booking-confirmation.astro` private, **+ Services link in `Navigation.astro` at `<!-- nav:links -->` / services teaser in `index.astro` at `<!-- home:bookings -->`**).
195
+ - **gift-cards-build** — `components` (probe util, GiftCardPurchase island) → `pages` (gift-cards landing + `Navigation.astro` `<!-- nav:links -->` / `index.astro` `<!-- home:gift-cards -->`).
196
+
197
+ Cross-vertical imports (`stores-home-and-nav` importing `CategoryRail`/`ProductCard`/`utils/categories.ts`) resolve at **build time**, not write time, so they impose no write-ordering between the chain and batch A. The only ordering: (i) shell-patchers serialize against each other (per-file), (ii) everything is on disk before Build.
198
+
199
+ **C · Image Phase 2 Entity** (imagery-gated) — same batch, background. Not dispatched on `themed-blocks`. On `ai-generated` with entities in `seeded`, dispatch it; the prompt **inlines** the `seeded.<pack>` slice (entity IDs + names + descriptions) + brand context (`images/INSTRUCTIONS.md` § "Scope: image-phase-2-entity"). It overlaps the whole wave, gated only at Build.
200
+
201
+ ### Merged-agent prompt additions (per vertical)
202
+
203
+ ```
204
+ Scopes (write in this order — islands/components FIRST, then pages, and a page-scope that writes a shared component before the page-scope that mounts it): <e.g. components, pages-categories, pages-products>
205
+ Files to own (absolute paths): <union of the scopes' files from the vertical's pack frontmatter>
206
+ Phase 1 Seed data: read your `seeded.<vertical>` slice from `.wix/seeded.json` (written once at the seed gate; do NOT import it into route files — use it to resolve slugs / getStaticPaths / demo content, then query the live SDK at request time). Fail loud (status: "partial", errors:[{code:"SEEDED_JSON_SLICE_MISSING", missing:"seeded.<vertical>"}]) if your slice is absent — do not render an empty page.
207
+ Styling contract: read .wix/design-tokens.css (on disk, gate-verified) for the token vocabulary — it is NOT inlined. Components do not write CSS (components-<pack>.css is already on disk, and global.css supplies the tokens to the build); use the token names only as the var(--token) / Tailwind utility vocabulary your markup references.
208
+ ```
209
+
210
+ Merged agents MUST NOT:
211
+ - Modify files outside their declared scopes (the union in their prompt)
212
+ - Modify CSS (`global.css` owned by `compose.mjs`; `components-<pack>.css` is pre-copied — never authored)
213
+ - Patch a shared shell unless they are the chain agent assigned to it
214
+
215
+ ---
216
+
217
+ ## Wait: build wave → Build
218
+
219
+ Wait on **all** build-wave agents — batch A and the full serialized chain B — then:
220
+ - **`ai-generated`** (wave dispatched `image-phase-2-entity`): wait that handle, hard **120 s timeout** from when build agents finish; on timeout, note it and proceed. (It's been running since the wave opened, so the timeout rarely fires.) Skipping this ships previews with entity images still attaching.
221
+ - **`themed-blocks`**: no wait — proceed immediately.
222
+
223
+ Ensure the background `npm install` (`npm_handle`, waited at the seed gate) exited 0 before Build. On non-zero, follow `SETUP.md` § "npm install recovery".
224
+
225
+ ## Build & Release
226
+
227
+ 1. `npx @wix/cli@latest build` — on failure, inspect `.wix/debug.log`, fix, retry (§ "Build failure modes"; Astro/React build-blockers in `IMPLEMENTER.md`).
228
+ 2. `npx @wix/cli@latest release` — extract the published URL from `Site published on <url>`. Also populates the **Frontend link** in headless settings natively. Transient errors (`ECONNRESET`, `ETIMEDOUT`, `EAI_AGAIN`, `STATE_MISMATCH`, `temporarily unavailable`, `try again shortly`) — retry serially up to 3× with `attempt * 5`s backoff. Do **not** retry build failures — those are code bugs.
229
+
230
+ Then **Final Message** (`BUILD.md` § "Final Message" — summary + `AGENTS.md` turn).
231
+
232
+ ## Styling contract coordination
233
+
234
+ `.wix/design-tokens.css` + `.wix/site.d.ts` are the coordination artifacts. **`DESIGN.md` is the single source of truth:** the Designer authors it (run-step 0); `emit-design-tokens.mjs` projects the `.wix` artifacts from it; `compose.mjs` reads it to write `global.css` + the other 5 files (run-step 2 bridge). The contract exists before the build wave launches; each merged build agent **reads `.wix/design-tokens.css` from disk** for the token vocabulary (gate-verified present at § "Step 4.5"). The orchestrator does **not** read it or inline it — inlining re-emits the full token block into every dispatch prompt (~one block per vertical per run) for no benefit, since the token cascade reaches components through `global.css`/`@theme`, not the prompt. The on-disk file is the single read source for the agent's token vocabulary.
235
+
236
+ ## Build failure modes
237
+
238
+ Inspect `.wix/debug.log` after a failed build:
239
+
240
+ | Failure | Detect | Fix |
241
+ |---------|--------|-----|
242
+ | `Legacy HTML single-line comments` | build stderr | An agent emitted HTML comments in `.astro` frontmatter — replace with `//` or `/* */` |
243
+ | `Missing environment variable WIX_CLIENT_ID` | build stderr | `npx @wix/cli@latest env pull --json` then retry |
244
+ | `Cannot find module '@wix/…'` | build stderr | npm install missed it; check the pack's `packages` list |
@@ -0,0 +1,167 @@
1
+ # Build — own-build framework class (`frontendBuild ∈ {none, own}`)
2
+
3
+ The post-approval conductor for the **non-astro** framework classes. Opened from `BUILD.md` the moment the run routes on `frontendBuild === "none"` (static HTML, no build) or `frontendBuild === "own"` (own-build SPA — Vite/React/Vue/Svelte, the project's own `npm run build`). This file owns the **framework spine** (install, build) for those classes; the **(operation × framework) bootstrap/wiring cells** and the **shared release tail** are owned by `BUILD.md` and detailed for this file's cells below.
4
+
5
+ The cross-cutting operational sections both framework conductors share — **Subagent rate / credit limits**, the **parallel-batch diagnostic**, the **Final Message** (summary + `AGENTS.md`), and the **Shared release tail** — live in `BUILD.md`. The pre-approval flow is `PLAN.md` → `PLAN-create.md`/`PLAN-connect.md`; the three cross-cutting rules referenced below — **Two tracks**, **Batching discipline**, **User-facing output** — live in `PLAN.md`. Set the model tier on every dispatch (`SKILL.md` § "Subagent model tier").
6
+
7
+ > **This file is framework-routed; the *operation* (create/connect/extend) reaches it only through the two cells.** The install/build spine below is operation-blind — it reads only `frontendBuild`. The Bootstrap cell and Wiring cell sections are the operation-specific halves (they read the contract's operation section). Live (operation × framework) pairings on this file: **connect × none** (a brought-in static HTML site), **connect × own** (a brought-in framework SPA), and **create × own** (the skill scaffolds a framework SPA — the companion case). The `extend` operation column is reserved.
8
+
9
+ ## Framework spine — `none` (static HTML)
10
+
11
+ Operation-blind. The brought design ships as-is; there is **no build**, and `@wix/sdk` loads from a CDN at runtime, so the usual install steps are skipped:
12
+
13
+ - **Install** — apply `SETUP.md` Step 4a (app installs per inferred capability, with `x-wix-request-id` capture) **only**. **Skip** `env pull` (Step 4b — CDN `@wix/sdk` inlines the `appId` from `wix.config.json`, needs no `WIX_CLIENT_ID`, and the `init`-bootstrapped project has no `env` command), **skip** the Step 4c per-pack `npm install` (CDN imports), and **skip** `scaffold.sh` / `seed-utilities.sh`.
14
+ - **Build** — **none.** The HTML is the deployable. Proceed straight to the shared release tail.
15
+
16
+ ## Framework spine — `own` (own-build SPA)
17
+
18
+ Operation-blind. A client-build single-page app (Vite + React/Vue/Svelte or similar) that ships its **own** build. `@wix/sdk` is **bundled**, not CDN-loaded, and the app is **built before release**.
19
+
20
+ **Framework-agnostic by construction — read this before touching anything framework-specific.** The skill carries **no per-framework instructions** (there is no `references/vite/`, no `references/vue/`):
21
+ - **Runtime is identical across every framework.** All of them call Wix through the same `@wix/sdk` modules (`createClient`, `OAuthStrategy`, `@wix/data`/`@wix/forms`/…). The wiring writes the *same SDK calls* whether the host is React, Vue, or Svelte — only the surrounding idiom differs (`useEffect` vs `onMounted` vs a store). The wiring agent adapts the idiom to whatever framework it finds.
22
+ - **Build is framework-dependent and derived, never hardcoded.** Each framework builds differently and `wix build` builds **astro only** — so for `own` you run the **project's own build command**. Derive the specifics from the project itself — its `package.json` scripts (`build` is the near-universal name), the framework config file (`vite.config.*`, `svelte.config.*`, …), and the framework's official docs via whatever doc source is available (web search, or a docs MCP **only if the user has one — never assume it**). React + Vite is the eval fixture, never a special case.
23
+
24
+ - **Install** — `SETUP.md` Step 4a (app installs per inferred capability, with `x-wix-request-id` capture). Then **bundle the SDK**: in the project dir, `npm install @wix/sdk` + the capability modules the connection needs (`@wix/data` for a CMS persistence swap, `@wix/forms`, `@wix/stores`, `@wix/bookings` + `@wix/redirects` for bookings, …) as real dependencies, so the bundler includes them. **Skip** `env pull` (the `appId` is inlined from `wix.config.json`, no `WIX_CLIENT_ID` at runtime) and **skip** the CDN-only `none` path. Capture timing as a `npm-install` phase.
25
+ - **One install, backgrounded, never verified.** Run this as a **single** `npm install` (all `@wix/*` modules in one command — do **not** split into per-module installs) **in the background** (capture `npm_handle`, wait it at the seed gate, like astro's `SETUP.md` Step 4c). The `npm install` exit code is authoritative — **do not** follow it with filesystem probes (`ls node_modules`, "check `package.json` for the deps", "confirm packages landed in the right dir"). This verification burns orchestrator wall for zero signal; trust the exit code. The app's own **framework** deps (e.g. `react-router-dom`) are **not** the orchestrator's job — the app-gen subagent installs whatever it imports (see § "create × own (companion case)"), so there is no second orchestrator `npm install` after app-gen returns.
26
+ - **Build** — run the **project's own build** (`npm run build`, confirmed against `package.json` `scripts`), producing the static output dir (commonly `dist/`). Then point `wix.config.json.site.outputDirectory` at that dir. This is **step 1 of the shared release tail** for `own`; never `wix build`. A build failure is a **code bug** — fix it (or report it), do **not** retry blindly (`BUILD-astro.md` § "Build failure modes").
27
+
28
+ ## The run from approval — `none` tenant (connect × none)
29
+
30
+ The user just approved; the contract lives in scratch — no disk snapshot. **Nothing is dispatched yet.** The frontend-track playbook is `<SKILL_ROOT>/references/custom/INSTRUCTIONS.md` (the conductor follows its § "The flow"; the subagents open the per-capability guides). The run:
31
+
32
+ 1. **Bootstrap cell (connect × none)** — see § "Bootstrap cell" below.
33
+ 2. **Setup (business track) — app installs only.** Apply the framework-spine install rule above (`SETUP.md` Step 4a; skip 4b/4c).
34
+ 3. **Seed (business track) — DISPATCH seeders as subagents, do NOT inline.** This is the **same per-pack seeder-dispatch model as astro** (`SEED.md` + `BUILD-astro.md` § "Wave 3"): fire **one seeder subagent per capability** that has a seed recipe, as a single concurrent background batch; capture a handle per seeder. Backend creation the augmentation needs — the **Wix Form definition** (forms), a **CMS collection + items** (cms), products/posts (stores/blog), services + staff + CLASS sessions (bookings, recipe within-skill at `references/bookings/SERVICES_DATA.md`) — is each a seeder subagent. **Never run seeding inline in the orchestrator:** the number of seeders is unpredictable (it scales with the brought-in site's content), and inlining serializes the work and bloats the orchestrator's context — exactly the failure the per-pack dispatch exists to prevent. Collect each seeder's returned IDs / form IDs at the gate, then write the aggregated map **once** to `.wix/seeded.json` before dispatching any wiring / Image Phase 2 reader — the same write-once handoff as astro (`BUILD-astro.md` § "The `.wix/seeded.json` handoff"). Wiring + Image Phase 2 read their slice from that file instead of receiving seeded IDs inlined.
35
+ - **A simple connection plan does NOT license inline seeding — these are independent decisions.** When a site has no dynamic regions (e.g. a one-page invite whose only connection is a single RSVP form), it is fine to *reason out the connection plan inline* — an empty binding map + one augmentation needs no subagent. **But that says nothing about seeding.** The Form/collection/products **still get created by a seeder subagent**, even when there is exactly one seeder and the schema is obvious. Do not generalize "the plan was trivial, so I'll do it all myself" into running the form-schema build + create-form API call inline — that is the `integration-inline` regression (inline Forms-install-retry + RSVP-schema work bloating the orchestrator's context). The floor is: **plan inline if trivial → seed via subagent always.**
36
+ 4. **Wiring cell (connect × none)** — see § "Wiring cell" below.
37
+ 5. **Release** — the **shared release tail** (`BUILD.md` § "Shared release tail"): `none` has no build, so run `npx @wix/cli@latest release` directly. See § "Release" below.
38
+
39
+ ## The run from approval — `own` tenant
40
+
41
+ The user just approved; the contract lives in scratch — no disk snapshot — and `frontendBuild: own` is in scratch. The frontend-track playbook is still `<SKILL_ROOT>/references/custom/INSTRUCTIONS.md` (the connection model is framework-blind); only the *mechanics* below differ from `none`. The run differs by **operation**:
42
+
43
+ 1. **Bootstrap cell** — `connect × own` (a brought-in SPA: connection plan + `init` over the source) or `create × own` (the companion case: two concurrent tracks — a foreground **`scaffold → init`** siteId track and a background **Designer → tokens → app-gen** frontend track). See § "Bootstrap cell". **`init` is the run's gate — run it first; Setup begins the moment it returns the siteId, not when the whole bootstrap finishes.**
44
+ 2. **Setup (business track) — app installs + bundle the SDK.** Apply the `own` framework-spine install rule above: `SETUP.md` Step 4a app installs, then `npm install @wix/sdk` + capability modules in the project dir. Skip `env pull`. **Gated only on the siteId from `init`** — start as soon as `init` returns; do not wait on the Designer / app-gen track, which runs in parallel.
45
+ 3. **Seed (business track) — DISPATCH seeders as subagents** (+ Image Phase 1 Decorative, gated). Same per-pack seeder-dispatch model as the `none` tenant and astro (`SEED.md`). Fires right after Setup, still concurrent with the frontend track. For a **persistence swap**, the cms seeder creates a **public-read CMS collection** whose schema is the connection plan's `persistenceSwap.inferredShape` (one collection per entity-shape — e.g. `Lists` + `Todos`), and returns the `collectionId`(s). In the **same concurrent batch**, dispatch `image-phase-1-decorative` when `imagery === "ai-generated"` (§ "Imagery gates (own)"). Collect seeder IDs + the Phase-1 slot→URL map at the gate; at the gate, write that map to `src/decorative-images.json` (see § "Imagery gates (own)").
46
+ 4. **Wiring cell** — `connect × own` (rewrite the source data layer to `@wix/data`) or `create × own` (write a fresh data module). See § "Wiring cell". In the message that opens this cell (post seed-gate, entities exist), also dispatch **Image Phase 2 Entity** when `imagery === "ai-generated"` (§ "Imagery gates (own)").
47
+ 5. **Build + Release** — the **shared release tail** (`BUILD.md` § "Shared release tail"): for `own`, step 1 runs the project's own `npm run build` and points `outputDirectory` at the build output (`dist/`), then `npx @wix/cli@latest release`. See § "Release" below. **On `ai-generated`, wait the Image Phase 2 handle (120 s cap) *before* `npm run build`** (§ "Imagery gates (own)").
48
+
49
+ ## Bootstrap cell
50
+
51
+ > **(operation × framework) cell.** Owned conceptually by `BUILD.md` § "The two (operation × framework) cells"; the content lives here (read-isolation — only the own-build conductor loads it). Three live tenants: **connect × none**, **connect × own**, **create × own**.
52
+
53
+ ### connect × none
54
+
55
+ **Normalize the entry HTML to `index.html` FIRST — before dispatching the connection plan.** Wix static hosting serves `index.html` at the site root (`/`); an entry under any other name publishes but the live root URL has no document to serve and errors at runtime — a failure `release` does **not** catch (it only confirms the upload). So as the first action of this cell, if the entry HTML is not named `index.html`, rename it (`mv "<entry>.html" index.html`) and fix any internal references to the old name. Doing this before the connection plan keeps the binding map, the wiring cell, and `outputDirectory` all keyed on `index.html`.
56
+
57
+ **Connection plan (background) + init (foreground), as the entry batch:**
58
+ - **Connection plan** — dispatch one subagent with Instruction file `<SKILL_ROOT>/references/custom/CONNECTION_PLAN.md`; inline the site's file list (now keyed on `index.html`) + inferred capabilities (from the contract's operation section / Discovery scratch). Capture `connplan_handle`. It returns the binding map + augmentation spec (JSON).
59
+ - **Init** — `npm create @wix/new@latest init` in the project dir (foreground; non-interactive when logged in). Then **fix `wix.config.json.site.outputDirectory`** to the dir holding the (now-`index.html`) entry HTML (init defaults it to `./dist`), and hold `siteId`/`appId` in scratch (durable source: `wix.config.json`) (`SETUP.md` Step 1 shape). Init registers the OAuth app's `allowedDomains` for the published origin — **no separate OAuth call needed.**
60
+
61
+ ### connect × own
62
+
63
+ A brought-in framework SPA. **Connection plan (background) + init (foreground), as the entry batch** — same shape as connect × none, with two `own` differences:
64
+ - **Connection plan** — dispatch the `CONNECTION_PLAN.md` subagent as for `none`, but inline `frontendBuild: own` so it reads **un-built `src/**` source** and emits a `persistenceSwap` (not an empty binding map). Capture `connplan_handle`.
65
+ - **Init** — `npm create @wix/new@latest init` in the project dir (the SPA repo). **Do NOT fix `outputDirectory` to the source dir** — for `own` it points at the **build output** (`dist/`), set later by the release tail *after* the build. Hold `siteId`/`appId` in scratch (durable source: `wix.config.json`). The source SPA is untouched at bootstrap (wiring edits it later).
66
+
67
+ ### create × own (companion case — scaffold a framework SPA)
68
+
69
+ No brought-in site; the prompt explicitly named a framework (`DISCOVERY.md` Wave 0 resolved `operation: create`, `frontendBuild: own`). Bootstrap runs **two concurrent tracks**, both opened in the **first dispatch message** after approval.
70
+
71
+ > **Open both tracks in ONE message.** Put the foreground scaffold/init Bash and the background Designer Agent in the **same** dispatch message — they run concurrently (the foreground Bash blocks that message until it returns; the background Agent keeps running). Scaffold+init is the critical path; the Designer rides alongside.
72
+
73
+ - a **siteId track** (foreground, **the critical path**): `scaffold → init` — produces the **siteId**, which **every backend step is blocked on** (Setup app-installs, all seeders, both image phases). Nothing on this track depends on the Designer, the tokens, or the generated app.
74
+ - a **frontend track** (background): `Designer → emit tokens → generate app` — produces the SPA the wiring cell edits.
75
+
76
+ **Run `init` as early as possible — it is the run's true gate.** Its only dependency is the scaffolded project dir + the user's approval; it does **not** wait on the Designer. So: scaffold, then `init`, **immediately and in the foreground**, while the Designer runs in the background. **The moment `init` returns the siteId, kick off run-step 2 (Setup) → run-step 3 (Seed + Image Phase 1)** — do **not** wait for the frontend track. The two tracks rejoin at the **Wiring cell** (needs app-gen done *and* seed done).
77
+
78
+ **siteId track — `scaffold → init` (foreground, FIRST):**
79
+ - **Scaffold** — run the framework's own create command, non-interactively, in the working dir, then `npm install`. Derive the exact command from the named framework (it is **not** hardcoded — pick the framework's documented create command; e.g. `npm create vite@latest … -- --template react` for React/Vite, the analogous command for Svelte/Vue/etc.). This replaces astro's `scaffold.sh` (astro-only). **Do not** use a `npm create @wix/new` template flag — scaffold-then-`init` is framework-general.
80
+ - **Single-folder requirement — the project MUST end up in the current directory, not a nested subdir** (one `.wix`, CWD == project == site-root, same as astro — `SKILL.md` § "Path resolution"). Scaffolders differ, so handle whichever you get: if the create command can scaffold **in place** (a `.` target or `--cwd`/in-place flag), use that. Otherwise scaffold into a **temp subdir** and run **`bash <SKILL_ROOT>/scripts/flatten.sh <temp-subdir>`** — the framework-agnostic, tested flatten that moves every entry (incl. dotfiles) up into CWD and folds the scaffold's `.wix/` into the existing one without clobbering existing `.wix/` entries (`mv -n`). Don't hand-write the `mv`/`rsync` logic; `flatten.sh` is the equivalent of what `scaffold.sh` does for astro.
81
+ - **Init** — `npm create @wix/new@latest init` over the scaffolded project (now in CWD), **the moment it exists** (do not gate it on `designer_handle`). Hold `siteId`/`appId` in scratch (durable source: `wix.config.json`); point `outputDirectory` at the build output later (release tail). This is the step that unblocks the entire business track — treat its return as the signal to start Setup.
82
+ - **Run `init` bare — no flags.** `npm create @wix/new@latest init` takes **no `--business-name`** (that flag is the astro `headless` scaffolder's, not `init`'s) and no other positional args here; the site is created under the logged-in account. Do **not** speculate about flags — run it as written.
83
+ - **`init` writes `wix.config.json` (`siteId`, `appId`) — read them into scratch; nothing else to reconcile.** It writes `wix.config.json` and its own `.wix/` entries: `init` → read `wix.config.json` → hold `siteId`/`appId` in scratch. There is no clobber to guard against.
84
+
85
+ **frontend track — `Designer → emit tokens → generate app` (background, concurrent with the siteId track):**
86
+ - **Designer (background, dispatched in the same first message as the scaffold).** Dispatch the Designer (`<SKILL_ROOT>/references/DESIGN_SYSTEM.md`), inlining the vibe/aesthetic craft held in scratch from Discovery — **identical to the astro branch** (`BUILD-astro.md` run-step 0). It **authors `DESIGN.md`** at the `designMdPath` you pass (`<site-root>/DESIGN.md` — the run dir, which exists) and returns `data.shell` + the `designMdPath` — framework-agnostic, identical to the astro branch (`BUILD-astro.md` run-step 0), so the tokens never round-trip through your output. Capture `designer_handle`. **Only the astro `compose.mjs` (the 6 astro files) is skipped on this branch — not the Designer.**
87
+ - **Emit design tokens + placeholder decorative map** — once `designer_handle` returns and the project dir exists, run `node <SKILL_ROOT>/scripts/emit-design-tokens.mjs "<project-dir>" --design-md "<site-root>/DESIGN.md"` (the Designer wrote `DESIGN.md` at `<site-root>` in run-step 0; `--design-md` points the projector at it explicitly, robust whether the project flattened into CWD or a scaffolder left it nested): projects `.wix/design-tokens.css` + `.wix/site.d.ts` into the project from its frontmatter. **Do NOT run `compose.mjs`** — it writes astro files. Then write a **placeholder decorative map**: `: | node <SKILL_ROOT>/scripts/write-decorative-json.mjs "<project-dir>"` (empty stdin → `src/decorative-images.json = {}`), so the generated app builds and renders themed blocks even if Image Phase 1 never runs (themed-blocks mode, or a Phase-1 failure). The real URLs overwrite this at the seed gate (§ "Imagery gates (own)").
88
+ - **Generate the initial app (first cut: minimal scaffold).** Produce a small, clean app — a few components — that **imports `.wix/design-tokens.css`** (or copies it into the app's styles) so the brand palette/type apply as CSS custom properties (`var(--color-paper)`, `var(--font-display)`, …) and `data.shell` strings fill the hero/nav copy. This is the **brand's look on the SPA** — real tokens, not invented ones. **Decorative images:** the app must `import` `src/decorative-images.json` and render a **`hero`** image from `decorativeImages.hero` and an **`about`** section image from `decorativeImages.about` — when the value is present render `<img src={…} alt="" loading="lazy" />`, when **empty/absent render a themed block** (`background: var(--color-paper-warm)` with the hero copy over it). **Exactly these two slot keys (`hero`, `about`) — do not invent others** (they must match the `["hero","about"]` set Image Phase 1 is asked for and the credit estimate in `DISCOVERY-create.md` §2.5.1). Astro's framework-specific *component composition* (`compose.mjs`'s 6 files) is **not** re-homed (deferred — SPA plan § Companion case 4b); the **tokens + imagery are**. The app generation is a normal subagent dispatch (inline the DESIGN.md token vocabulary + `data.shell`); the connection then runs over it via the spine below. **App-gen owns the deps it imports** — if it adds a framework library (e.g. `react-router-dom`), it runs that `npm install` itself inside its scope, so the orchestrator never does a follow-up install after it returns.
89
+ - **Dispatch app-gen the instant `emit-design-tokens.mjs` returns — in the background, concurrent with the *entire* business track** (Setup app-installs, the SDK `npm install`, and all seeders). App-gen depends on none of them (it imports `.wix/design-tokens.css` + `src/decorative-images.json`, both on disk, and calls a data module the Wiring cell writes later); the two tracks rejoin only at the Wiring cell. Fire it early; let it overlap.
90
+ - **Rendering contract for live Wix data — inline these two rules into the app-gen dispatch** (the SPA *owns* its markup + CSS, so unlike astro it gets no pre-sized templates; without these, real data breaks the layout):
91
+ 1. **Constrain every Wix image.** Wix media URLs serve full-resolution images; an `<img>` with no sizing renders at intrinsic size and **overflows its card onto the text**. Every image (product, hero/decorative, CMS) must sit in a slot with a fixed `aspect-ratio` (or `height`) and use `width: 100%; height: 100%; object-fit: cover` — mirror the astro rule in `references/astro/templates/stores/components-stores.css` (`.product-card-media > img`). Never render a Wix image unconstrained.
92
+ 2. **Rich-text fields are HTML — render the plain variant.** A Wix Stores product `description` (and many CMS rich fields) is **HTML/ricos**; rendered as text it shows literal `<p>…</p>` tags. Bind the **plain** field: products → **`product.plainDescription`** (fall back to `description.replace(/<[^>]*>/g, "")` if absent); never bind raw `description` into `textContent`/`{…}`. (The astro path does this at `references/astro/templates/stores/products/[slug].astro`.) Per-capability field paths (product image/price/slug, CMS fields) live in `references/custom/<cap>/WIRING.md` — follow them.
93
+
94
+ ## Wiring cell
95
+
96
+ > **(operation × framework) cell.** Owned conceptually by `BUILD.md` § "The two (operation × framework) cells"; the content lives here (read-isolation). Three live tenants: **connect × none**, **connect × own**, **create × own**.
97
+
98
+ ### connect × none
99
+
100
+ **Wiring gate → wire (parallelism is a RUNTIME decision keyed on file topology).** Wait `connplan_handle` + all seeder handles. Each capability's `<SKILL_ROOT>/references/custom/<capability>/WIRING.md` is the how-to; *how many writers* run is decided from the connection plan's `injectAt.file` / region `file` set:
101
+ - **Capabilities share a file (the common single-page case — e.g. one `index.html` with both a form and a feedback list):** wire them with a **single writer** — either inline, or one subagent handling *all* capabilities for that file. **Never dispatch parallel agents at the same file** — they clobber each other's edits and duplicate the SDK bootstrap. This mirrors the astro shared-shell-patcher discipline (serialize writers to a shared file).
102
+ - **Capabilities map to distinct files:** dispatch one wiring subagent per file (concurrent batch) — no conflict.
103
+
104
+ Inline each agent with its binding-map/augmentation-spec slice + the site's CSS token names; the agent reads its **seeded IDs from `.wix/seeded.json`** (its `<capability>` slice — written once at the seed gate, not inlined). Each injects client-side `@wix/sdk` `<script type="module">` (additive; styled from the design's tokens). The orchestrator decides writer count from the plan; the WIRING guides don't dictate it. (When wiring is run *inline* by the orchestrator rather than dispatched, the orchestrator already holds the seeded IDs in scratch — `.wix/seeded.json` is the read channel for *dispatched* wiring agents.)
105
+
106
+ ### connect × own
107
+
108
+ The brought-in SPA's data layer is **rewritten in source** to call `@wix/sdk` — **not** a `<script>` injection. The connection plan's `persistenceSwap` entries name the source file + the load/save functions to replace and the seeded `collectionId`(s).
109
+ - **Wire per `persistenceSwap.sourceFile`, not per capability.** Each swap entry targets one source file (e.g. `src/App.jsx`); dispatch one wiring subagent per distinct source file (or inline if one). **Never two writers on the same source file** (same shared-file discipline as `none`).
110
+ - Each writer opens `<SKILL_ROOT>/references/custom/cms/WIRING.md` § "Framework SPA — persistence swap" and rewrites the named `load`/`save` functions/effects to `@wix/data` `query`/`insert`/`update`/`remove` against the seeded collection, using bundled `import { items } from "@wix/data"` (the app `npm install`ed it — **not** the CDN). The component tree, JSX, and styling are untouched. Inline the `appId` (OAuth `clientId`) literally; the agent reads the seeded `collectionId`(s) from its slice in `.wix/seeded.json` (the `persistenceSwap` entry names which collection).
111
+ - The agent adapts to the framework idiom it finds (React `useEffect`/state, Vue `onMounted`/refs, Svelte stores) — the SDK calls are identical; only the surrounding idiom differs.
112
+
113
+ ### create × own (companion case)
114
+
115
+ The skill controls the source (it scaffolded the app), so there is **no data-layer archaeology** — the wiring agent **writes a fresh data module** (e.g. `src/wixData.js`) exposing the same `load`/`save` surface the generated components call, backed by `@wix/data` against the seeded collection. Same SDK calls as connect × own; the only difference is *write-fresh* vs *rewrite-existing*. `custom/cms/WIRING.md` § "Framework SPA — persistence swap" covers the call shapes. **Gate:** wait the **app-gen** handle *and* the seeder handles before wiring — app-gen fixes the `./wixData` export surface the generated components import, and the seeders return the `collectionId`(s) the module queries. It is **one writer** of `src/wixData.js`, so wiring is a single subagent (or inline), never a parallel batch.
116
+
117
+ > **Manifest check (two timings for `own`).** Run `node <SKILL_ROOT>/scripts/check-manifest.mjs <project-dir> integration <connection-plan.json>`:
118
+ > - **After wiring, before build** — verifies the *connection*: for `none`, an SDK `<script>` in each binding-map/augmentation `file`; for `own`, the bundled `@wix/sdk` import + a `@wix/data` CRUD call in each `persistenceSwap.sourceFile` (or the fresh data module). The always-connect invariant must hold (exit 1 if zero connections).
119
+ > - **After the build, before release (`own` only)** — re-run with `--build-output <dir>` (e.g. `--build-output dist`) to assert the build output exists and is non-empty, so release publishes the *built* app, not the un-built dev entry that 404s. (For `create × own` with no connection-plan JSON, feed a synthesized `{persistenceSwap:[{sourceFile:"src/wixData.js"}]}` so the same checker verifies the fresh module.)
120
+ >
121
+ > `BUILD-astro.md` § "Build failure modes" applies the same fail-loud discipline.
122
+
123
+ > **Always connect.** This framework class must end with the site reading from or writing to Wix; `init`+`release` of a static page with no connection is not acceptable (`references/custom/INSTRUCTIONS.md` § "Two locked principles"). The per-capability `custom/<cap>/WIRING.md` guides own the wiring step.
124
+
125
+ ## Imagery gates (own)
126
+
127
+ The `imagery` flag (`"ai-generated"` | `"themed-blocks"`, captured in `DISCOVERY-create.md` Step 2.5, default `"themed-blocks"`) gates **both** image phases on the `own` branch — exactly as it does on astro (`BUILD-astro.md` § "Imagery gates"; keep the two in sync). Both phases are framework-agnostic: Phase 2 PATCHes Wix-side entities (no frontend dependency at all); Phase 1's decorative URLs reach the SPA through `src/decorative-images.json` (which the generated app imports), **not** through astro's `patch-decorative-slots.mjs` (that script stays astro-only).
128
+
129
+ > **Generation runs through `generate-images.mjs` (parallel, deterministic).** Both phases' generate-then-import work is the parallelizable, recipe-free half — and when the agent drove it by hand it serialized (traces show product images fired one at a time across turns). Each phase's generation + Wix Media import is now done by `<SKILL_ROOT>/scripts/generate-images.mjs`, which fires every image as a **concurrent single-task request in one process** (`Promise.all`) — no per-turn serialization, and no `google:4@2` N≥3-in-one-request 504 (each task is its own request). Pass the **already-minted** site token via `WIX_TOKEN` (mint-once — `AUTHENTICATION.md`); the script returns a `slots`/`map` of key→URL. Attachment is unchanged and stays where the recipe lives (Phase 1 → `write-decorative-json.mjs`; Phase 2 → the entity PATCH/PUT/publish recipe in `images/INSTRUCTIONS.md` / `plan-entity-image-waves.mjs`).
130
+
131
+ **The two phases run concurrently — Phase 2 is gated on the entity seeders only, never on Phase 1 or on wiring.** Phase 1 (decorative) depends on brand context alone and rides the seed wave; Phase 2 (entity) needs seeded entity IDs and so cannot start before the seeders return — but the **instant** they do (the seed gate), dispatch Phase 2 in the **same message** that opens the Wiring cell, so it overlaps both Phase 1's tail and the wiring writers. Do **not** spend a dedicated later orchestrator turn on "now dispatch Phase 2" — it is part of the seed-gate batch.
132
+
133
+ - **Image Phase 1 — Decorative** (seed-wave batch, run-step 3). **Only when `imagery === "ai-generated"`**, generate the `["hero","about"]` slots (the canonical `own` set — matches the app-gen components + the credit estimate) via `generate-images.mjs` (keys = slot names). At the **seed gate**, pipe its `slots` map into `write-decorative-json.mjs` —
134
+ ```bash
135
+ echo '<generate-images.mjs .slots JSON>' | node <SKILL_ROOT>/scripts/write-decorative-json.mjs "<project-dir>"
136
+ ```
137
+ This rewrites `src/decorative-images.json` with the real URLs **before** the build. On `"themed-blocks"` (default): do **not** generate, leave the placeholder `{}` from bootstrap in place (the app renders themed blocks), and record `{phase: "image-phase-1-decorative", status: "skipped", notes: "themed-blocks mode"}`.
138
+ - **Image Phase 2 — Entity** (opens the Wiring cell, run-step 4; dispatched **in parallel** at the seed gate per the rule above). Only on `ai-generated`, after the seed gate (entities exist): generate the entity images via `generate-images.mjs` (keys = entityIds), then attach them — PATCH Wix entities (`stores/v3/products`, `wix-data/v2/items`, `blog/v3/...`) per the `images/INSTRUCTIONS.md` recipe (428-prevention GETs, `revision`, CMS read-merge-PUT). Inline the `seeded.<pack>` slice (productIds/collectionIds/itemIds + names/descriptions) + brand context — Image Phase 2 is a single dispatch with a battle-tested inline contract, so its slice stays inlined (only the per-file *wiring* agents read from `.wix/seeded.json`). No frontend touch. On `themed-blocks`: skip, record `{phase: "image-phase-2-entity", status: "skipped"}`.
139
+
140
+ > **The load-bearing ordering:** the seed-gate `write-decorative-json.mjs` overwrite **must precede `npm run build`** (Release step 1). Vite resolves the `src/decorative-images.json` import at build time, so a build run before the overwrite ships themed blocks even in `ai-generated` mode. The bootstrap placeholder + the seed-gate overwrite both run before Release, so the order holds — do not move the build earlier.
141
+
142
+ ## Release
143
+
144
+ Apply the **shared release tail** (`BUILD.md` § "Shared release tail"). Step 1 (build) is **framework-keyed**:
145
+
146
+ **`none`** — no build; the HTML is the deployable. **Before releasing, confirm the entry HTML in `outputDirectory` is `index.html`** (the bootstrap rename in connect × none — re-verify here, because a non-`index.html` entry publishes "successfully" yet the live root URL errors at runtime, and `release` won't flag it). Then run release directly:
147
+
148
+ ```bash
149
+ test -f "$(node -p "require('./wix.config.json').site.outputDirectory")/index.html" \
150
+ || { echo "FAIL: no index.html in outputDirectory — rename the entry HTML before release"; exit 1; }
151
+ npx @wix/cli@latest release 2>&1 # parse `Site published on <url>`; NO `wix build` first
152
+ ```
153
+
154
+ **`own`** — first settle imagery, then run the **project's own build**, point `outputDirectory` at the build output, then release:
155
+
156
+ - **On `imagery === "ai-generated"`:** wait the Image Phase 2 handle (dispatched at the Wiring cell) with a hard **120 s timeout** from when wiring finishes; on timeout, note the timeout and proceed. (Entity images attach server-side, so they don't block the SPA *build* — the gate is mainly so the run doesn't proceed with entity images still attaching.) Confirm the seed-gate `write-decorative-json.mjs` overwrite already ran (decorative URLs are in `src/decorative-images.json`) **before** building.
157
+ - **On `imagery === "themed-blocks"`:** no wait — `src/decorative-images.json` is the bootstrap `{}` placeholder; proceed to build.
158
+
159
+ ```bash
160
+ npm run build 2>&1 # the PROJECT's build (Vite/…), confirmed from package.json scripts — NEVER `wix build`
161
+ # ensure wix.config.json.site.outputDirectory points at the build output (e.g. ./dist)
162
+ npx @wix/cli@latest release 2>&1 # parse `Site published on <url>`
163
+ ```
164
+
165
+ A `npm run build` failure is a **code bug** — fix it, do not retry (only the `release` step retries on transient errors).
166
+
167
+ Either way: extract the published URL from `Site published on <url>`. Transient release errors (`ECONNRESET`, `STATE_MISMATCH`, `temporarily unavailable`, …) — retry serially up to 3× with `attempt * 5`s backoff (`references/shared/PRODUCTION_SHARP_EDGES.md`). Then the **Final Message** (`BUILD.md` § "Final Message" — the shared summary + `AGENTS.md` turn).