@wix/agent-skills 1.33.0 → 1.34.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 (635) hide show
  1. package/README.md +23 -0
  2. package/package.json +2 -2
  3. package/skills/wix-app/references/DASHBOARD_PAGE.md +1 -1
  4. package/skills/wix-export/SKILL.md +83 -0
  5. package/skills/wix-harmony-editor/.publish-manifest.json +8 -0
  6. package/skills/wix-harmony-editor/COPY-SITE.md +494 -0
  7. package/skills/wix-harmony-editor/SKILL.md +317 -0
  8. package/skills/wix-harmony-editor/scripts/copy/build-description.mjs +249 -0
  9. package/skills/wix-harmony-editor/scripts/copy/check-description.mjs +225 -0
  10. package/skills/wix-harmony-editor/scripts/copy/check-mirror.mjs +89 -0
  11. package/skills/wix-harmony-editor/scripts/copy/compare-preview.mjs +76 -0
  12. package/skills/wix-harmony-editor/scripts/copy/deploy-description.mjs +212 -0
  13. package/skills/wix-harmony-editor/scripts/copy/desc-hash.mjs +44 -0
  14. package/skills/wix-harmony-editor/scripts/copy/editor-run.mjs +45 -0
  15. package/skills/wix-harmony-editor/scripts/copy/export-page.mjs +53 -0
  16. package/skills/wix-harmony-editor/scripts/copy/find-interactions.mjs +76 -0
  17. package/skills/wix-harmony-editor/scripts/copy/hide-scrollbars.mjs +16 -0
  18. package/skills/wix-harmony-editor/scripts/copy/import-media.mjs +150 -0
  19. package/skills/wix-harmony-editor/scripts/copy/link-url.mjs +27 -0
  20. package/skills/wix-harmony-editor/scripts/copy/lint-api.mjs +56 -0
  21. package/skills/wix-harmony-editor/scripts/copy/measure-source.mjs +211 -0
  22. package/skills/wix-harmony-editor/scripts/copy/merge-mirrors.mjs +29 -0
  23. package/skills/wix-harmony-editor/scripts/copy/mirror-site.mjs +92 -0
  24. package/skills/wix-harmony-editor/scripts/copy/mobile-stage.mjs +56 -0
  25. package/skills/wix-harmony-editor/scripts/copy/preview-widths.mjs +73 -0
  26. package/skills/wix-harmony-editor/scripts/copy/render-plate.mjs +67 -0
  27. package/skills/wix-harmony-editor/scripts/copy/serve-mirror.mjs +102 -0
  28. package/skills/wix-harmony-editor/scripts/copy/snapshot-capabilities.mjs +40 -0
  29. package/skills/wix-harmony-editor/scripts/copy/split-sections.mjs +191 -0
  30. package/skills/wix-harmony-editor/scripts/copy/upload-media-manager.mjs +61 -0
  31. package/skills/wix-harmony-editor/scripts/launch.sh +359 -0
  32. package/skills/wix-headless/SKILL.md +7 -2
  33. package/skills/wix-headless/references/CAPABILITIES.md +6 -1
  34. package/skills/wix-headless/references/DISCOVERY.md +2 -1
  35. package/skills/wix-headless/references/SDK_HANDOFF.md +6 -1
  36. package/skills/wix-headless/references/SEED.md +3 -2
  37. package/skills/wix-headless/references/SETUP.md +1 -0
  38. package/skills/wix-headless/references/inline-recipes/experience-donations.md +102 -0
  39. package/skills/wix-headless/references/inline-recipes/how-to-code-donations.md +146 -0
  40. package/skills/wix-headless/references/inline-recipes/setup-donations.md +15 -0
  41. package/skills/wix-headless/references/managed/CREATE.md +1 -1
  42. package/skills/wix-headless-kit/SKILL.md +110 -21
  43. package/skills/wix-headless-kit/guides/api-run.md +15 -13
  44. package/skills/wix-headless-kit/guides/existing-site.md +31 -0
  45. package/skills/wix-headless-kit/guides/migration.md +49 -17
  46. package/skills/wix-headless-kit/install/agents-md.mjs +1 -1
  47. package/skills/wix-headless-kit/install/context.mjs +61 -6
  48. package/skills/wix-headless-kit/install/pins.json +1 -1
  49. package/skills/wix-headless-kit/install/setup.mjs +107 -12
  50. package/skills/wix-headless-replatform/.publish-manifest.json +8 -0
  51. package/skills/wix-headless-replatform/SKILL.md +116 -0
  52. package/skills/wix-headless-replatform/agents/openai.yaml +6 -0
  53. package/skills/wix-headless-replatform/references/control-and-visual-fidelity-contract.md +43 -0
  54. package/skills/wix-headless-replatform/references/extraction-schema.md +187 -0
  55. package/skills/wix-headless-replatform/references/interaction-runtime-contract.md +137 -0
  56. package/skills/wix-headless-replatform/references/layout-blueprint-contract.md +41 -0
  57. package/skills/wix-headless-replatform/references/output-contract.md +93 -0
  58. package/skills/wix-headless-replatform/references/post-build-gap-contract.md +125 -0
  59. package/skills/wix-headless-replatform/references/qa-checklist.md +83 -0
  60. package/skills/wix-headless-replatform/references/safety.md +19 -0
  61. package/skills/wix-headless-replatform/references/ui-normalization-contract.md +70 -0
  62. package/skills/wix-headless-replatform/references/workflow.md +157 -0
  63. package/skills/wix-headless-replatform/registry/README.md +20 -0
  64. package/skills/wix-headless-replatform/registry/approvals/button/shadcn-default-ac60ef5.json +28 -0
  65. package/skills/wix-headless-replatform/registry/items/button/shadcn-default-ac60ef5/button.tsx +54 -0
  66. package/skills/wix-headless-replatform/registry/items/button/shadcn-default-ac60ef5/capabilities.json +60 -0
  67. package/skills/wix-headless-replatform/registry/items/button/shadcn-default-ac60ef5/contract.md +48 -0
  68. package/skills/wix-headless-replatform/registry/licenses/shadcn-ui-ac60ef5-MIT.txt +21 -0
  69. package/skills/wix-headless-replatform/registry/registry.json +36 -0
  70. package/skills/wix-headless-replatform/resources/rp-facelift/SKILL.md +32 -0
  71. package/skills/wix-headless-replatform/resources/rp-project-context/SKILL.md +62 -0
  72. package/skills/wix-headless-replatform/resources/rp-qa-gap-loop/SKILL.md +64 -0
  73. package/skills/wix-headless-replatform/resources/rp-source-evidence/SKILL.md +42 -0
  74. package/skills/wix-headless-replatform/resources/rp-ui-implementation/SKILL.md +73 -0
  75. package/skills/wix-headless-replatform/schemas/build-plan.schema.json +10 -0
  76. package/skills/wix-headless-replatform/schemas/candidate.schema.json +19 -0
  77. package/skills/wix-headless-replatform/schemas/common.schema.json +33 -0
  78. package/skills/wix-headless-replatform/schemas/decision-patch.schema.json +10 -0
  79. package/skills/wix-headless-replatform/schemas/decision-request.schema.json +10 -0
  80. package/skills/wix-headless-replatform/schemas/extraction-gap.schema.json +28 -0
  81. package/skills/wix-headless-replatform/schemas/extraction-manifest.schema.json +34 -0
  82. package/skills/wix-headless-replatform/schemas/final-report.schema.json +10 -0
  83. package/skills/wix-headless-replatform/schemas/foundation.schema.json +11 -0
  84. package/skills/wix-headless-replatform/schemas/metadata.schema.json +11 -0
  85. package/skills/wix-headless-replatform/schemas/observation-packet.schema.json +17 -0
  86. package/skills/wix-headless-replatform/schemas/page-capture.schema.json +11 -0
  87. package/skills/wix-headless-replatform/schemas/page-resolution.schema.json +33 -0
  88. package/skills/wix-headless-replatform/schemas/shared-chrome.schema.json +11 -0
  89. package/skills/wix-headless-replatform/schemas/unit.schema.json +40 -0
  90. package/skills/wix-headless-replatform/scripts/assemble-extraction.mjs +844 -0
  91. package/skills/wix-headless-replatform/scripts/benchmark-extraction.mjs +163 -0
  92. package/skills/wix-headless-replatform/scripts/browser-extraction-preflight.mjs +42 -0
  93. package/skills/wix-headless-replatform/scripts/build-extracted-homepage.mjs +228 -0
  94. package/skills/wix-headless-replatform/scripts/clear-wix-starter.mjs +87 -0
  95. package/skills/wix-headless-replatform/scripts/create-wix-project.mjs +505 -0
  96. package/skills/wix-headless-replatform/scripts/discover-urls.mjs +142 -0
  97. package/skills/wix-headless-replatform/scripts/extract-assets.mjs +140 -0
  98. package/skills/wix-headless-replatform/scripts/extract-design-system.mjs +637 -0
  99. package/skills/wix-headless-replatform/scripts/extract-interactions.mjs +1903 -0
  100. package/skills/wix-headless-replatform/scripts/extract-page.mjs +2461 -0
  101. package/skills/wix-headless-replatform/scripts/extract-seo.mjs +25 -0
  102. package/skills/wix-headless-replatform/scripts/extract-tokens.mjs +63 -0
  103. package/skills/wix-headless-replatform/scripts/finalize-extraction-report.mjs +126 -0
  104. package/skills/wix-headless-replatform/scripts/finalize-gap-review.mjs +180 -0
  105. package/skills/wix-headless-replatform/scripts/finalize-gap-review.test.mjs +98 -0
  106. package/skills/wix-headless-replatform/scripts/finalize-migration-website.mjs +103 -0
  107. package/skills/wix-headless-replatform/scripts/generate-control-state-contract.mjs +176 -0
  108. package/skills/wix-headless-replatform/scripts/generate-design-md.mjs +261 -0
  109. package/skills/wix-headless-replatform/scripts/generate-extraction-validators.mjs +25 -0
  110. package/skills/wix-headless-replatform/scripts/generate-invoice-download-backend.mjs +342 -0
  111. package/skills/wix-headless-replatform/scripts/generate-layout-blueprint.mjs +140 -0
  112. package/skills/wix-headless-replatform/scripts/generate-repeater-cms.mjs +22 -0
  113. package/skills/wix-headless-replatform/scripts/generate-route-plan.mjs +143 -0
  114. package/skills/wix-headless-replatform/scripts/generate-scene-contract.mjs +288 -0
  115. package/skills/wix-headless-replatform/scripts/generate-ui-normalization.mjs +266 -0
  116. package/skills/wix-headless-replatform/scripts/generate-visual-assets.mjs +111 -0
  117. package/skills/wix-headless-replatform/scripts/lib/browser-tooling.mjs +570 -0
  118. package/skills/wix-headless-replatform/scripts/lib/common.mjs +329 -0
  119. package/skills/wix-headless-replatform/scripts/lib/component-capabilities.mjs +121 -0
  120. package/skills/wix-headless-replatform/scripts/lib/component-registry.mjs +282 -0
  121. package/skills/wix-headless-replatform/scripts/lib/content-boundary.mjs +61 -0
  122. package/skills/wix-headless-replatform/scripts/lib/extraction-contract.mjs +374 -0
  123. package/skills/wix-headless-replatform/scripts/lib/extraction-detectors.mjs +243 -0
  124. package/skills/wix-headless-replatform/scripts/lib/extraction-validators.generated.mjs +1139 -0
  125. package/skills/wix-headless-replatform/scripts/lib/font-contract.mjs +326 -0
  126. package/skills/wix-headless-replatform/scripts/lib/frontend-automation-state.mjs +184 -0
  127. package/skills/wix-headless-replatform/scripts/lib/gap-analysis.mjs +396 -0
  128. package/skills/wix-headless-replatform/scripts/lib/html-extract.mjs +168 -0
  129. package/skills/wix-headless-replatform/scripts/lib/interaction-bootstrap.mjs +10 -0
  130. package/skills/wix-headless-replatform/scripts/lib/interaction-runtime.mjs +194 -0
  131. package/skills/wix-headless-replatform/scripts/lib/interaction-timeline.mjs +348 -0
  132. package/skills/wix-headless-replatform/scripts/lib/layout-blueprint/classifiers.mjs +141 -0
  133. package/skills/wix-headless-replatform/scripts/lib/layout-blueprint/geometry.mjs +43 -0
  134. package/skills/wix-headless-replatform/scripts/lib/layout-blueprint/vocabulary.mjs +18 -0
  135. package/skills/wix-headless-replatform/scripts/lib/ui-normalization.css +64 -0
  136. package/skills/wix-headless-replatform/scripts/optimize-svg.mjs +31 -0
  137. package/skills/wix-headless-replatform/scripts/post-build-gap.mjs +358 -0
  138. package/skills/wix-headless-replatform/scripts/provision-repeater-cms.mjs +25 -0
  139. package/skills/wix-headless-replatform/scripts/record-gap-decision.mjs +39 -0
  140. package/skills/wix-headless-replatform/scripts/replay-extraction.mjs +107 -0
  141. package/skills/wix-headless-replatform/scripts/resolve-home-page.mjs +96 -0
  142. package/skills/wix-headless-replatform/scripts/site-clone.mjs +658 -0
  143. package/skills/wix-headless-replatform/scripts/validate-font-contract.mjs +29 -0
  144. package/skills/wix-headless-replatform/scripts/verify-interactions.mjs +669 -0
  145. package/skills/wix-headless-replatform/scripts/visual-qa.mjs +370 -0
  146. package/skills/wix-headless-templates/donations/INSTRUCTIONS.md +37 -24
  147. package/skills/wix-headless-templates/donations/app/components/donations/DonateForm.tsx +49 -23
  148. package/skills/wix-headless-templates/donations/app/components/donations/DonationReceipt.tsx +6 -5
  149. package/skills/wix-headless-templates/donations/app/components/donations/GoalProgress.tsx +5 -5
  150. package/skills/wix-headless-templates/donations/app/wix/donations/campaigns.ts +4 -4
  151. package/skills/wix-headless-templates/donations/app/wix/donations/donate.ts +7 -3
  152. package/skills/wix-headless-templates/donations/app/wix/donations/donation-store.ts +2 -2
  153. package/skills/wix-headless-templates/donations/app/wix/donations/donations-core.ts +12 -9
  154. package/skills/wix-headless-templates/donations/project/src/components/donations/DonateForm.tsx +49 -23
  155. package/skills/wix-headless-templates/donations/project/src/components/donations/DonationReceipt.tsx +6 -5
  156. package/skills/wix-headless-templates/donations/project/src/components/donations/GoalProgress.tsx +5 -5
  157. package/skills/wix-headless-templates/donations/project/src/wix/donations/campaigns.ts +4 -4
  158. package/skills/wix-headless-templates/donations/project/src/wix/donations/donate.ts +7 -3
  159. package/skills/wix-headless-templates/donations/project/src/wix/donations/donation-store.ts +2 -2
  160. package/skills/wix-headless-templates/donations/project/src/wix/donations/donations-core.ts +12 -9
  161. package/skills/wix-headless-templates/donations/rest/campaigns.ts +4 -4
  162. package/skills/wix-headless-templates/donations/rest/donate.ts +7 -3
  163. package/skills/wix-headless-templates/donations/seed/SEED.md +12 -7
  164. package/skills/wix-headless-templates/donations/tests/donation-contract.test.mjs +71 -0
  165. package/skills/wix-headless-templates/donations/tests/donation-form.test.cjs +137 -0
  166. package/skills/wix-headless-templates/restaurants/INSTRUCTIONS.md +28 -14
  167. package/skills/wix-headless-templates/restaurants/app/components/restaurants/OrderCartDrawer.tsx +87 -5
  168. package/skills/wix-headless-templates/restaurants/app/hooks/restaurants/useOrderCart.ts +9 -1
  169. package/skills/wix-headless-templates/restaurants/app/wix/restaurants/order-store.ts +33 -4
  170. package/skills/wix-headless-templates/restaurants/app/wix/restaurants/ordering-core.ts +100 -5
  171. package/skills/wix-headless-templates/restaurants/app/wix/restaurants/ordering.ts +101 -15
  172. package/skills/wix-headless-templates/restaurants/app/wix/restaurants/types.ts +35 -1
  173. package/skills/wix-headless-templates/restaurants/project/src/components/restaurants/OrderCartDrawer.tsx +87 -5
  174. package/skills/wix-headless-templates/restaurants/project/src/hooks/restaurants/useOrderCart.ts +9 -1
  175. package/skills/wix-headless-templates/restaurants/project/src/wix/restaurants/order-store.ts +33 -4
  176. package/skills/wix-headless-templates/restaurants/project/src/wix/restaurants/ordering-core.ts +100 -5
  177. package/skills/wix-headless-templates/restaurants/project/src/wix/restaurants/ordering.ts +101 -15
  178. package/skills/wix-headless-templates/restaurants/project/src/wix/restaurants/types.ts +35 -1
  179. package/skills/wix-headless-templates/restaurants/rest/ordering.ts +91 -14
  180. package/skills/wix-import/SKILL.md +90 -0
  181. package/skills/wix-manage/SKILL.md +38 -10
  182. package/skills/wix-manage/references/automations/actions.md +11 -11
  183. package/skills/wix-manage/references/automations/activation-status.md +6 -9
  184. package/skills/wix-manage/references/automations/api-catalog.md +48 -32
  185. package/skills/wix-manage/references/automations/automation-model.md +97 -22
  186. package/skills/wix-manage/references/automations/bracket-expressions.md +7 -7
  187. package/skills/wix-manage/references/automations/build-and-manage-automations.md +140 -309
  188. package/skills/wix-manage/references/automations/conditions.md +187 -0
  189. package/skills/wix-manage/references/automations/schemas-and-scheduling.md +191 -0
  190. package/skills/wix-manage/references/automations/special-actions.md +210 -0
  191. package/skills/wix-manage/references/automations/triggers.md +47 -10
  192. package/skills/wix-manage/references/automations/validation-and-verification.md +320 -0
  193. package/skills/wix-manage/references/custom-apps/use-app-tools.md +124 -0
  194. package/skills/wix-manage/references/dashboard-navigation/dashboard-navigation.md +2 -1
  195. package/skills/wix-manage/references/dashboard-navigation/routes.json +249 -0
  196. package/skills/wix-manage/references/donations/create-and-update-donation-campaigns.md +139 -0
  197. package/skills/wix-manage/references/events/create-wix-event.md +136 -73
  198. package/skills/wix-manage/references/events/events-dashboard-navigation.md +81 -0
  199. package/skills/wix-manage/references/events/manage-event-guests.md +366 -0
  200. package/skills/wix-manage/references/events/manage-event-tickets.md +293 -0
  201. package/skills/wix-manage/references/events/manage-wix-events.md +313 -55
  202. package/skills/wix-manage/references/sites/manage-oauth-apps.md +1 -0
  203. package/skills/wix-manage/references/sites/upload-static-site.md +127 -8
  204. package/skills/wix-manage/references/stores/update-product-with-options.md +58 -2
  205. package/skills/wix-replatform/.publish-manifest.json +5 -5
  206. package/skills/wix-replatform/CLI.md +162 -0
  207. package/skills/wix-replatform/README.md +52 -0
  208. package/skills/wix-replatform/SKILL.md +229 -684
  209. package/skills/wix-replatform/console/account.css +1 -0
  210. package/skills/wix-replatform/console/app.css +1 -0
  211. package/skills/wix-replatform/console/app.js +117 -0
  212. package/skills/wix-replatform/console/index.html +4 -0
  213. package/skills/wix-replatform/console/json.css +11 -0
  214. package/skills/wix-replatform/lib/agent-adapters/index.js +71 -0
  215. package/skills/wix-replatform/lib/app-page-routing.js +75 -0
  216. package/skills/wix-replatform/lib/artifact-freshness.js +11 -1
  217. package/skills/wix-replatform/lib/blocked-data-requests.js +427 -0
  218. package/skills/wix-replatform/lib/census-reconciliation.js +426 -0
  219. package/skills/wix-replatform/lib/completion-report.js +1393 -13
  220. package/skills/wix-replatform/lib/config-env.js +85 -11
  221. package/skills/wix-replatform/lib/confirmed-pictures.js +212 -0
  222. package/skills/wix-replatform/lib/dependency-readiness.js +423 -0
  223. package/skills/wix-replatform/lib/dependency-recovery.js +21 -0
  224. package/skills/wix-replatform/lib/destination-choice.js +163 -0
  225. package/skills/wix-replatform/lib/destination-handoff.js +62 -0
  226. package/skills/wix-replatform/lib/destination-http.js +81 -0
  227. package/skills/wix-replatform/lib/destination-route.js +98 -0
  228. package/skills/wix-replatform/lib/destination.js +919 -0
  229. package/skills/wix-replatform/lib/discovered-census.js +231 -0
  230. package/skills/wix-replatform/lib/discovered-set-status.js +255 -0
  231. package/skills/wix-replatform/lib/document-url-guard.js +203 -0
  232. package/skills/wix-replatform/lib/entity-qa-attestation.js +339 -0
  233. package/skills/wix-replatform/lib/entity-verification.js +18 -0
  234. package/skills/wix-replatform/lib/execution-capability.js +120 -0
  235. package/skills/wix-replatform/lib/execution-log.js +170 -0
  236. package/skills/wix-replatform/lib/execution-manifest.js +20 -2
  237. package/skills/wix-replatform/lib/execution-state.js +22 -0
  238. package/skills/wix-replatform/lib/expectations-ledger.js +96 -0
  239. package/skills/wix-replatform/lib/generated-plugin-handoff.js +140 -0
  240. package/skills/wix-replatform/lib/import-readiness-contract.js +23 -0
  241. package/skills/wix-replatform/lib/import-recovery.js +800 -6
  242. package/skills/wix-replatform/lib/imported-redirect-targets.js +608 -0
  243. package/skills/wix-replatform/lib/internal-link-reconciliation.js +166 -0
  244. package/skills/wix-replatform/lib/link-audit.js +173 -0
  245. package/skills/wix-replatform/lib/link-census.js +194 -0
  246. package/skills/wix-replatform/lib/link-plan.js +148 -0
  247. package/skills/wix-replatform/lib/link-verification.js +274 -0
  248. package/skills/wix-replatform/lib/link-write-journal.js +42 -0
  249. package/skills/wix-replatform/lib/local-state.js +869 -30
  250. package/skills/wix-replatform/lib/member-completion.js +658 -0
  251. package/skills/wix-replatform/lib/member-crosswalk.js +69 -0
  252. package/skills/wix-replatform/lib/member-outcome-registry.js +265 -0
  253. package/skills/wix-replatform/lib/migration-completion.js +311 -0
  254. package/skills/wix-replatform/lib/operator-identity.js +47 -0
  255. package/skills/wix-replatform/lib/orchestration-decisions.js +248 -0
  256. package/skills/wix-replatform/lib/orchestration-preflight.js +401 -19
  257. package/skills/wix-replatform/lib/orchestration-router.js +608 -32
  258. package/skills/wix-replatform/lib/orchestration-state.js +188 -12
  259. package/skills/wix-replatform/lib/order-reference-readiness.js +30 -0
  260. package/skills/wix-replatform/lib/payments-outcome-registry.js +200 -0
  261. package/skills/wix-replatform/lib/plugin-cms-fallback.js +618 -0
  262. package/skills/wix-replatform/lib/preservation-approval-stamp.js +54 -0
  263. package/skills/wix-replatform/lib/product-media-deferral.js +96 -0
  264. package/skills/wix-replatform/lib/progress-log.js +19 -3
  265. package/skills/wix-replatform/lib/read-back-approval.js +184 -0
  266. package/skills/wix-replatform/lib/read-back-comparison.js +136 -0
  267. package/skills/wix-replatform/lib/read-back-contract.js +243 -0
  268. package/skills/wix-replatform/lib/read-back-extract.js +118 -0
  269. package/skills/wix-replatform/lib/read-back-gate.js +734 -0
  270. package/skills/wix-replatform/lib/read-back-reads.js +94 -0
  271. package/skills/wix-replatform/lib/read-back-state.js +107 -0
  272. package/skills/wix-replatform/lib/read-back-summary.js +81 -0
  273. package/skills/wix-replatform/lib/rerun-conflicts.js +334 -0
  274. package/skills/wix-replatform/lib/run-controller.js +401 -0
  275. package/skills/wix-replatform/lib/seo-outcome-registry.js +45 -0
  276. package/skills/wix-replatform/lib/setup-verification.js +148 -0
  277. package/skills/wix-replatform/lib/source-access.js +231 -0
  278. package/skills/wix-replatform/lib/source-coverage.js +1130 -0
  279. package/skills/wix-replatform/lib/source-secrets.js +277 -0
  280. package/skills/wix-replatform/lib/structured-link-patch.js +59 -0
  281. package/skills/wix-replatform/lib/task-state.js +110 -0
  282. package/skills/wix-replatform/lib/url-preservation-report.js +319 -0
  283. package/skills/wix-replatform/lib/url-preservation-state.js +349 -1
  284. package/skills/wix-replatform/lib/url-redirect-plan.js +728 -0
  285. package/skills/wix-replatform/lib/url-verification.js +315 -0
  286. package/skills/wix-replatform/lib/user-action-effects.js +42 -0
  287. package/skills/wix-replatform/lib/user-actions.js +264 -0
  288. package/skills/wix-replatform/lib/website-handoff.js +1220 -0
  289. package/skills/wix-replatform/lib/wix-client-callers.js +54 -0
  290. package/skills/wix-replatform/lib/wix-dashboard-url.js +35 -0
  291. package/skills/wix-replatform/lib/write-verification-state.js +92 -0
  292. package/skills/wix-replatform/lib/write-verification.js +274 -0
  293. package/skills/wix-replatform/resources/rp-destination/SKILL.md +137 -0
  294. package/skills/wix-replatform/resources/rp-discovery/SKILL.md +189 -16
  295. package/skills/wix-replatform/resources/rp-discovery/scripts/promote-source-coverage.js +47 -0
  296. package/skills/wix-replatform/resources/rp-execute-import/SKILL.md +869 -29
  297. package/skills/wix-replatform/resources/rp-execute-import/scripts/shipping-estimate-audit.js +70 -0
  298. package/skills/wix-replatform/resources/rp-execute-setup/SKILL.md +195 -29
  299. package/skills/wix-replatform/resources/rp-execute-setup/scripts/execute-setup.js +442 -0
  300. package/skills/wix-replatform/resources/rp-execution-policy/SKILL.md +112 -0
  301. package/skills/wix-replatform/resources/rp-execution-policy/lib/coupon-currency-plan-report.js +143 -0
  302. package/skills/wix-replatform/resources/rp-execution-policy/lib/payments-report.js +244 -0
  303. package/skills/wix-replatform/resources/rp-import-codegen/SKILL.md +2082 -38
  304. package/skills/wix-replatform/resources/rp-mapper/SKILL.md +528 -11
  305. package/skills/wix-replatform/resources/rp-mapper/lib/structure-bridge-planning.js +303 -0
  306. package/skills/wix-replatform/resources/rp-mapper/scripts/coverage-reconcile.js +88 -0
  307. package/skills/wix-replatform/resources/rp-mapper/wix-business-solutions-taxonomy.md +6 -5
  308. package/skills/wix-replatform/resources/rp-preflight/SKILL.md +40 -0
  309. package/skills/wix-replatform/resources/rp-project-intake/SKILL.md +55 -0
  310. package/skills/wix-replatform/resources/rp-quick-runtime/SKILL.md +60 -0
  311. package/skills/wix-replatform/resources/rp-quick-runtime/lib/import-progress.js +89 -0
  312. package/skills/wix-replatform/resources/rp-quick-runtime/lib/limit-recovery.js +36 -0
  313. package/skills/wix-replatform/resources/rp-quick-shopify/SKILL.md +123 -0
  314. package/skills/wix-replatform/resources/rp-quick-shopify/quick-mode.json +124 -0
  315. package/skills/wix-replatform/resources/rp-quick-shopify/scripts/quick-mode.js +522 -0
  316. package/skills/wix-replatform/resources/rp-quick-woocommerce/SKILL.md +56 -0
  317. package/skills/wix-replatform/resources/rp-quick-woocommerce/quick-mode.json +91 -0
  318. package/skills/wix-replatform/resources/rp-quick-woocommerce/scripts/quick-mode.js +255 -0
  319. package/skills/wix-replatform/resources/rp-setup-discovery/SKILL.md +80 -10
  320. package/skills/wix-replatform/resources/rp-setup-discovery/scripts/quick-setup-plan.js +44 -0
  321. package/skills/wix-replatform/resources/rp-source-csv/SKILL.md +3 -0
  322. package/skills/wix-replatform/resources/rp-source-csv/lib/csv-fileset.js +0 -0
  323. package/skills/wix-replatform/resources/rp-source-csv/scripts/csv-discovery.js +21 -1
  324. package/skills/wix-replatform/resources/rp-source-inputs/SKILL.md +66 -0
  325. package/skills/wix-replatform/resources/rp-source-sfcc/SKILL.md +153 -0
  326. package/skills/wix-replatform/resources/rp-source-shopify/SKILL.md +394 -0
  327. package/skills/wix-replatform/resources/rp-source-shopify/lib/discovery-reads.js +200 -0
  328. package/skills/wix-replatform/resources/rp-source-shopify/lib/import-findings.js +34 -0
  329. package/skills/wix-replatform/resources/rp-source-shopify/lib/shopify-bulk-sqlite-worker.js +44 -0
  330. package/skills/wix-replatform/resources/rp-source-shopify/lib/shopify-bulk.js +1470 -0
  331. package/skills/wix-replatform/resources/rp-source-shopify/lib/shopify-cli.js +446 -0
  332. package/skills/wix-replatform/resources/rp-source-shopify/lib/shopify-gift-cards.js +474 -0
  333. package/skills/wix-replatform/resources/rp-source-shopify/lib/shopify-protected-fields.js +879 -0
  334. package/skills/wix-replatform/resources/rp-source-shopify/lib/shopify-session.js +426 -0
  335. package/skills/wix-replatform/resources/rp-source-shopify/queries/articles.graphql +24 -0
  336. package/skills/wix-replatform/resources/rp-source-shopify/queries/blogs.graphql +18 -0
  337. package/skills/wix-replatform/resources/rp-source-shopify/queries/collections.graphql +40 -0
  338. package/skills/wix-replatform/resources/rp-source-shopify/queries/customers.graphql +76 -0
  339. package/skills/wix-replatform/resources/rp-source-shopify/queries/delivery-profiles.graphql +51 -0
  340. package/skills/wix-replatform/resources/rp-source-shopify/queries/discounts.graphql +35 -0
  341. package/skills/wix-replatform/resources/rp-source-shopify/queries/files.graphql +20 -0
  342. package/skills/wix-replatform/resources/rp-source-shopify/queries/gift-cards.graphql +18 -0
  343. package/skills/wix-replatform/resources/rp-source-shopify/queries/inventory.graphql +31 -0
  344. package/skills/wix-replatform/resources/rp-source-shopify/queries/locations.graphql +21 -0
  345. package/skills/wix-replatform/resources/rp-source-shopify/queries/menus.graphql +21 -0
  346. package/skills/wix-replatform/resources/rp-source-shopify/queries/metaobjects.graphql +30 -0
  347. package/skills/wix-replatform/resources/rp-source-shopify/queries/orders-core.graphql +150 -0
  348. package/skills/wix-replatform/resources/rp-source-shopify/queries/orders-fulfillments.graphql +36 -0
  349. package/skills/wix-replatform/resources/rp-source-shopify/queries/orders-refunds.graphql +48 -0
  350. package/skills/wix-replatform/resources/rp-source-shopify/queries/pages.graphql +20 -0
  351. package/skills/wix-replatform/resources/rp-source-shopify/queries/probe-customers-address.graphql +8 -0
  352. package/skills/wix-replatform/resources/rp-source-shopify/queries/probe-customers-email.graphql +6 -0
  353. package/skills/wix-replatform/resources/rp-source-shopify/queries/probe-customers-name.graphql +8 -0
  354. package/skills/wix-replatform/resources/rp-source-shopify/queries/probe-customers-phone.graphql +8 -0
  355. package/skills/wix-replatform/resources/rp-source-shopify/queries/probe-orders-address.graphql +12 -0
  356. package/skills/wix-replatform/resources/rp-source-shopify/queries/probe-orders-email.graphql +6 -0
  357. package/skills/wix-replatform/resources/rp-source-shopify/queries/probe-orders-name.graphql +13 -0
  358. package/skills/wix-replatform/resources/rp-source-shopify/queries/probe-orders-phone.graphql +13 -0
  359. package/skills/wix-replatform/resources/rp-source-shopify/queries/products.graphql +73 -0
  360. package/skills/wix-replatform/resources/rp-source-shopify/queries/url-redirects.graphql +13 -0
  361. package/skills/wix-replatform/resources/rp-source-shopify/scripts/shopify-discovery.js +693 -0
  362. package/skills/wix-replatform/resources/rp-source-shopify/scripts/shopify-extract.js +283 -0
  363. package/skills/wix-replatform/resources/rp-source-shopify/scripts/shopify-gift-card-remedy.js +191 -0
  364. package/skills/wix-replatform/resources/rp-source-shopify/scripts/shopify-session-check.js +115 -0
  365. package/skills/wix-replatform/resources/rp-source-shopify/source-schema.example.json +201 -0
  366. package/skills/wix-replatform/resources/rp-source-wordpress/PLUGIN-READ-PLANS.md +146 -0
  367. package/skills/wix-replatform/resources/rp-source-wordpress/SKILL.md +736 -22
  368. package/skills/wix-replatform/resources/rp-source-wordpress/lib/blocked-data-handlers.js +73 -0
  369. package/skills/wix-replatform/resources/rp-source-wordpress/lib/checkout-field-csv-parser.js +115 -0
  370. package/skills/wix-replatform/resources/rp-source-wordpress/lib/checkout-field-csv-parser.test-fixture.js +91 -0
  371. package/skills/wix-replatform/resources/rp-source-wordpress/lib/coupon-discovery.js +440 -0
  372. package/skills/wix-replatform/resources/rp-source-wordpress/lib/currency-gate.js +125 -0
  373. package/skills/wix-replatform/resources/rp-source-wordpress/lib/gateway-source-keys.js +252 -0
  374. package/skills/wix-replatform/resources/rp-source-wordpress/lib/gateway-source-keys.json +183 -0
  375. package/skills/wix-replatform/resources/rp-source-wordpress/lib/gateway-summary.mjs +333 -0
  376. package/skills/wix-replatform/resources/rp-source-wordpress/lib/invoice-discovery.js +426 -0
  377. package/skills/wix-replatform/resources/rp-source-wordpress/lib/plugin-disposition.js +400 -0
  378. package/skills/wix-replatform/resources/rp-source-wordpress/lib/plugin-entity-read-plan.js +633 -0
  379. package/skills/wix-replatform/resources/rp-source-wordpress/lib/plugin-knowledge.js +1127 -0
  380. package/skills/wix-replatform/resources/rp-source-wordpress/lib/refund-corroboration.js +194 -0
  381. package/skills/wix-replatform/resources/rp-source-wordpress/lib/refund-corroboration.json +100 -0
  382. package/skills/wix-replatform/resources/rp-source-wordpress/lib/sampled-ids-batch.js +157 -0
  383. package/skills/wix-replatform/resources/rp-source-wordpress/lib/secret-value-guard.js +234 -0
  384. package/skills/wix-replatform/resources/rp-source-wordpress/lib/store-currency.js +101 -0
  385. package/skills/wix-replatform/resources/rp-source-wordpress/lib/structure-bridge-reader.js +755 -0
  386. package/skills/wix-replatform/resources/rp-source-wordpress/lib/wix-wp-plugin-v2-client.js +1074 -0
  387. package/skills/wix-replatform/resources/rp-source-wordpress/lib/wix-wp-plugin-v2-client.test-fixture.js +149 -0
  388. package/skills/wix-replatform/resources/rp-source-wordpress/lib/woo-inventory.js +25 -0
  389. package/skills/wix-replatform/resources/rp-source-wordpress/lib/wp-http.js +204 -9
  390. package/skills/wix-replatform/resources/rp-source-wordpress/lib/wp-image-url.js +186 -0
  391. package/skills/wix-replatform/resources/rp-source-wordpress/lib/wp-plugin-detect.js +1422 -0
  392. package/skills/wix-replatform/resources/rp-source-wordpress/lib/wp-redirect-sources.js +343 -0
  393. package/skills/wix-replatform/resources/rp-source-wordpress/lib/wp-route-classifier.js +262 -26
  394. package/skills/wix-replatform/resources/rp-source-wordpress/lib/yoast-product-seo-evidence.js +272 -0
  395. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/README.md +373 -0
  396. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/advanced-custom-fields.json +101 -0
  397. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/back-in-stock-notifier-for-woocommerce.json +81 -0
  398. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/capabilities-pending-decision.json +128 -0
  399. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/cms-fallback-eligible.json +18 -0
  400. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/contact-form-7.json +104 -0
  401. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/facebook-for-woocommerce.json +44 -0
  402. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/fingerprint-aliases.json +49 -0
  403. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/free-gifts-for-woocommerce.json +94 -0
  404. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/index.json +863 -0
  405. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/mailpoet.json +52 -0
  406. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/membership-for-woocommerce.json +161 -0
  407. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/mwb-bookings-for-woocommerce.json +180 -0
  408. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/no-migration-needed.json +286 -0
  409. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/pricing-deals-for-woocommerce.json +79 -0
  410. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/product-extras-for-woocommerce.json +120 -0
  411. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/pw-woocommerce-gift-cards.json +128 -0
  412. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/requires-development.json +88 -0
  413. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/seo-by-rank-math.json +80 -0
  414. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/seriously-simple-podcasting.json +46 -0
  415. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/strong-testimonials.json +55 -0
  416. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/subscriptions-for-woocommerce.json +99 -0
  417. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/tablepress.json +55 -0
  418. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/the-events-calendar.json +160 -0
  419. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/ti-woocommerce-wishlist.json +81 -0
  420. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/woo-checkout-field-editor-pro.json +60 -0
  421. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/woo-discount-rules.json +74 -0
  422. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/woo-product-bundle.json +75 -0
  423. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/woocommerce-gift-cards.json +60 -0
  424. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/woocommerce-other-payment-gateway.json +44 -0
  425. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/woocommerce-pdf-invoices-packing-slips.json +57 -0
  426. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/woocommerce-product-addon.json +141 -0
  427. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/woocommerce-progressive-discounts.json +54 -0
  428. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/wordpress-seo.json +158 -0
  429. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/wpc-composite-products.json +97 -0
  430. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/wpforms-lite.json +86 -0
  431. package/skills/wix-replatform/resources/rp-source-wordpress/scripts/capture-store-settings.js +90 -0
  432. package/skills/wix-replatform/resources/rp-source-wordpress/scripts/plugin-knowledge-validate.js +51 -0
  433. package/skills/wix-replatform/resources/rp-source-wordpress/scripts/plugin-knowledge.js +103 -0
  434. package/skills/wix-replatform/resources/rp-source-wordpress/scripts/wp-discovery.js +1668 -33
  435. package/skills/wix-replatform/resources/rp-source-wordpress/scripts/wp-plugin-inventory.js +273 -0
  436. package/skills/wix-replatform/resources/rp-source-wordpress/secret-value-patterns.v1.json +11 -0
  437. package/skills/wix-replatform/resources/rp-source-wordpress/sub-parts.json +13 -0
  438. package/skills/wix-replatform/resources/rp-target-wix/SKILL.md +446 -32
  439. package/skills/wix-replatform/resources/rp-target-wix/app-page-routing-capabilities.json +36 -0
  440. package/skills/wix-replatform/resources/rp-target-wix/domains/README.md +38 -2
  441. package/skills/wix-replatform/resources/rp-target-wix/domains/SERVICE-PLUGINS.md +322 -0
  442. package/skills/wix-replatform/resources/rp-target-wix/domains/blog/docs-survey.json +70 -0
  443. package/skills/wix-replatform/resources/rp-target-wix/domains/blog/domain.json +19 -9
  444. package/skills/wix-replatform/resources/rp-target-wix/domains/blog/entities/category.json +42 -8
  445. package/skills/wix-replatform/resources/rp-target-wix/domains/blog/entities/comment.json +54 -8
  446. package/skills/wix-replatform/resources/rp-target-wix/domains/blog/entities/post.json +66 -10
  447. package/skills/wix-replatform/resources/rp-target-wix/domains/blog/entities/tag.json +38 -7
  448. package/skills/wix-replatform/resources/rp-target-wix/domains/bookings/docs-survey.json +332 -0
  449. package/skills/wix-replatform/resources/rp-target-wix/domains/bookings/domain.json +75 -0
  450. package/skills/wix-replatform/resources/rp-target-wix/domains/bookings/entities/booking.json +181 -0
  451. package/skills/wix-replatform/resources/rp-target-wix/domains/bookings/entities/service-add-on.json +130 -0
  452. package/skills/wix-replatform/resources/rp-target-wix/domains/bookings/entities/service.json +180 -0
  453. package/skills/wix-replatform/resources/rp-target-wix/domains/cms/docs-survey.json +161 -0
  454. package/skills/wix-replatform/resources/rp-target-wix/domains/cms/domain.json +15 -4
  455. package/skills/wix-replatform/resources/rp-target-wix/domains/cms/entities/collection.json +39 -7
  456. package/skills/wix-replatform/resources/rp-target-wix/domains/cms/entities/data-item.json +47 -8
  457. package/skills/wix-replatform/resources/rp-target-wix/domains/cms/entities/reference.json +7 -1
  458. package/skills/wix-replatform/resources/rp-target-wix/domains/crm/docs-survey.json +204 -0
  459. package/skills/wix-replatform/resources/rp-target-wix/domains/crm/domain.json +17 -4
  460. package/skills/wix-replatform/resources/rp-target-wix/domains/crm/entities/contact.json +159 -15
  461. package/skills/wix-replatform/resources/rp-target-wix/domains/crm/entities/email-subscription.json +80 -12
  462. package/skills/wix-replatform/resources/rp-target-wix/domains/crm/entities/label.json +48 -8
  463. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/docs-survey.json +306 -0
  464. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/domain.json +30 -7
  465. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/delivery-profile.json +171 -0
  466. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/discount-rule.json +182 -0
  467. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order-applied-discount.json +129 -0
  468. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order-invoice-document.json +192 -0
  469. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order-line-item-options.json +123 -0
  470. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order-line-item.json +60 -12
  471. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order-merchant-note.json +112 -0
  472. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order-payment.json +191 -0
  473. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order-refund.json +140 -13
  474. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order.json +383 -18
  475. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/pickup-location.json +122 -0
  476. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/shipping-option.json +98 -0
  477. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/wishlist-item.json +86 -0
  478. package/skills/wix-replatform/resources/rp-target-wix/domains/events/docs-survey.json +128 -0
  479. package/skills/wix-replatform/resources/rp-target-wix/domains/events/domain.json +38 -0
  480. package/skills/wix-replatform/resources/rp-target-wix/domains/events/entities/category.json +73 -0
  481. package/skills/wix-replatform/resources/rp-target-wix/domains/events/entities/event.json +107 -0
  482. package/skills/wix-replatform/resources/rp-target-wix/domains/events/entities/registration-form.json +89 -0
  483. package/skills/wix-replatform/resources/rp-target-wix/domains/events/entities/rsvp.json +118 -0
  484. package/skills/wix-replatform/resources/rp-target-wix/domains/events/entities/ticket-definition.json +93 -0
  485. package/skills/wix-replatform/resources/rp-target-wix/domains/forms/docs-survey.json +86 -0
  486. package/skills/wix-replatform/resources/rp-target-wix/domains/forms/domain.json +56 -0
  487. package/skills/wix-replatform/resources/rp-target-wix/domains/forms/entities/form-submission.json +121 -0
  488. package/skills/wix-replatform/resources/rp-target-wix/domains/forms/entities/form.json +134 -0
  489. package/skills/wix-replatform/resources/rp-target-wix/domains/gift-cards/docs-survey.json +41 -0
  490. package/skills/wix-replatform/resources/rp-target-wix/domains/gift-cards/domain.json +50 -0
  491. package/skills/wix-replatform/resources/rp-target-wix/domains/gift-cards/entities/gift-card-product.json +87 -0
  492. package/skills/wix-replatform/resources/rp-target-wix/domains/gift-cards/entities/gift-card.json +130 -0
  493. package/skills/wix-replatform/resources/rp-target-wix/domains/index.json +914 -24
  494. package/skills/wix-replatform/resources/rp-target-wix/domains/media/docs-survey.json +41 -0
  495. package/skills/wix-replatform/resources/rp-target-wix/domains/media/domain.json +14 -4
  496. package/skills/wix-replatform/resources/rp-target-wix/domains/media/entities/media-file.json +45 -8
  497. package/skills/wix-replatform/resources/rp-target-wix/domains/media/entities/media-folder.json +41 -7
  498. package/skills/wix-replatform/resources/rp-target-wix/domains/members/docs-survey.json +119 -0
  499. package/skills/wix-replatform/resources/rp-target-wix/domains/members/domain.json +13 -3
  500. package/skills/wix-replatform/resources/rp-target-wix/domains/members/entities/badge.json +41 -7
  501. package/skills/wix-replatform/resources/rp-target-wix/domains/members/entities/custom-field.json +82 -0
  502. package/skills/wix-replatform/resources/rp-target-wix/domains/members/entities/member-about.json +77 -0
  503. package/skills/wix-replatform/resources/rp-target-wix/domains/members/entities/member.json +165 -13
  504. package/skills/wix-replatform/resources/rp-target-wix/domains/pricing-plans/docs-survey.json +41 -0
  505. package/skills/wix-replatform/resources/rp-target-wix/domains/pricing-plans/domain.json +46 -0
  506. package/skills/wix-replatform/resources/rp-target-wix/domains/pricing-plans/entities/plan-order.json +137 -0
  507. package/skills/wix-replatform/resources/rp-target-wix/domains/pricing-plans/entities/plan.json +133 -0
  508. package/skills/wix-replatform/resources/rp-target-wix/domains/sales-channels/docs-survey.json +7 -0
  509. package/skills/wix-replatform/resources/rp-target-wix/domains/sales-channels/domain.json +36 -0
  510. package/skills/wix-replatform/resources/rp-target-wix/domains/sales-channels/entities/amazon-shop-connect.json +71 -0
  511. package/skills/wix-replatform/resources/rp-target-wix/domains/sales-channels/entities/ebay-shop-connect.json +67 -0
  512. package/skills/wix-replatform/resources/rp-target-wix/domains/sales-channels/entities/google-youtube-connect.json +72 -0
  513. package/skills/wix-replatform/resources/rp-target-wix/domains/sales-channels/entities/meta-catalog-connect.json +74 -0
  514. package/skills/wix-replatform/resources/rp-target-wix/domains/sales-channels/entities/pinterest-catalog-connect.json +69 -0
  515. package/skills/wix-replatform/resources/rp-target-wix/domains/sales-channels/entities/tiktok-catalog-connect.json +61 -0
  516. package/skills/wix-replatform/resources/rp-target-wix/domains/schema.json +28 -1
  517. package/skills/wix-replatform/resources/rp-target-wix/domains/seo/docs-survey.json +109 -0
  518. package/skills/wix-replatform/resources/rp-target-wix/domains/seo/domain.json +73 -0
  519. package/skills/wix-replatform/resources/rp-target-wix/domains/seo/entities/item-seo-tags.json +148 -0
  520. package/skills/wix-replatform/resources/rp-target-wix/domains/seo/entities/seo-pattern.json +91 -0
  521. package/skills/wix-replatform/resources/rp-target-wix/domains/seo/entities/site-seo-tags.json +79 -0
  522. package/skills/wix-replatform/resources/rp-target-wix/domains/site/docs-survey.json +32 -0
  523. package/skills/wix-replatform/resources/rp-target-wix/domains/site/domain.json +49 -0
  524. package/skills/wix-replatform/resources/rp-target-wix/domains/site/entities/business-contact.json +103 -0
  525. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/docs-survey.json +203 -0
  526. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/domain.json +27 -10
  527. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/back-in-stock-request.json +119 -0
  528. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/brand.json +111 -0
  529. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/category.json +52 -8
  530. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/coupon.json +214 -10
  531. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/inventory-item.json +93 -13
  532. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/product-customization.json +111 -0
  533. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/product-tag.json +52 -10
  534. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/product.json +145 -14
  535. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/promotion.json +84 -0
  536. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/review.json +178 -0
  537. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/subscription-product.json +87 -0
  538. package/skills/wix-replatform/resources/rp-target-wix/domains/tax/docs-survey.json +106 -0
  539. package/skills/wix-replatform/resources/rp-target-wix/domains/tax/domain.json +64 -0
  540. package/skills/wix-replatform/resources/rp-target-wix/domains/tax/entities/manual-tax-mapping.json +119 -0
  541. package/skills/wix-replatform/resources/rp-target-wix/domains/tax/entities/tax-group.json +94 -0
  542. package/skills/wix-replatform/resources/rp-target-wix/domains/tax/entities/tax-region.json +113 -0
  543. package/skills/wix-replatform/resources/rp-target-wix/domains/tax/entities/tax-settings.json +65 -0
  544. package/skills/wix-replatform/resources/rp-target-wix/lib/blog-author-attribution.js +165 -0
  545. package/skills/wix-replatform/resources/rp-target-wix/lib/blog-post-build-client.js +60 -0
  546. package/skills/wix-replatform/resources/rp-target-wix/lib/blog-post-build-duplicates.js +201 -0
  547. package/skills/wix-replatform/resources/rp-target-wix/lib/blog-post-build-ledger.js +306 -0
  548. package/skills/wix-replatform/resources/rp-target-wix/lib/blog-post-build-report.js +229 -0
  549. package/skills/wix-replatform/resources/rp-target-wix/lib/blog-post-build-stage.js +55 -0
  550. package/skills/wix-replatform/resources/rp-target-wix/lib/blog-post-build.js +715 -0
  551. package/skills/wix-replatform/resources/rp-target-wix/lib/blog-post-media.js +567 -0
  552. package/skills/wix-replatform/resources/rp-target-wix/lib/bulk-results.js +73 -0
  553. package/skills/wix-replatform/resources/rp-target-wix/lib/contact-extended-fields.js +194 -0
  554. package/skills/wix-replatform/resources/rp-target-wix/lib/contact-import.js +133 -0
  555. package/skills/wix-replatform/resources/rp-target-wix/lib/contract-ledger.js +13 -4
  556. package/skills/wix-replatform/resources/rp-target-wix/lib/coupon-redemption-drift.js +491 -0
  557. package/skills/wix-replatform/resources/rp-target-wix/lib/customer-member.js +104 -0
  558. package/skills/wix-replatform/resources/rp-target-wix/lib/data-extension-schema.js +673 -0
  559. package/skills/wix-replatform/resources/rp-target-wix/lib/domain-knowledge.js +453 -2
  560. package/skills/wix-replatform/resources/rp-target-wix/lib/gift-card-balance-reconciliation.js +119 -0
  561. package/skills/wix-replatform/resources/rp-target-wix/lib/gift-card-build.js +566 -0
  562. package/skills/wix-replatform/resources/rp-target-wix/lib/gift-card-redemption-build.js +249 -0
  563. package/skills/wix-replatform/resources/rp-target-wix/lib/order-applied-discount-build.js +63 -0
  564. package/skills/wix-replatform/resources/rp-target-wix/lib/order-buyer.js +187 -0
  565. package/skills/wix-replatform/resources/rp-target-wix/lib/order-channel-build.js +64 -0
  566. package/skills/wix-replatform/resources/rp-target-wix/lib/order-history.js +1027 -0
  567. package/skills/wix-replatform/resources/rp-target-wix/lib/order-invoice-contract.js +90 -0
  568. package/skills/wix-replatform/resources/rp-target-wix/lib/order-payment-mapping.js +420 -0
  569. package/skills/wix-replatform/resources/rp-target-wix/lib/pricing-plan-definition.js +177 -0
  570. package/skills/wix-replatform/resources/rp-target-wix/lib/product-import.js +151 -0
  571. package/skills/wix-replatform/resources/rp-target-wix/lib/product-seo.js +723 -0
  572. package/skills/wix-replatform/resources/rp-target-wix/lib/seo-redirects.js +353 -0
  573. package/skills/wix-replatform/resources/rp-target-wix/lib/shipping-build.js +1437 -0
  574. package/skills/wix-replatform/resources/rp-target-wix/lib/shipping-option-stage.js +354 -0
  575. package/skills/wix-replatform/resources/rp-target-wix/lib/store-config-build.js +134 -0
  576. package/skills/wix-replatform/resources/rp-target-wix/lib/stores-category-attach.js +221 -0
  577. package/skills/wix-replatform/resources/rp-target-wix/lib/stores-inventory.js +248 -0
  578. package/skills/wix-replatform/resources/rp-target-wix/lib/stores-verification.js +86 -3
  579. package/skills/wix-replatform/resources/rp-target-wix/lib/tax-build.js +231 -0
  580. package/skills/wix-replatform/resources/rp-target-wix/lib/url-mapper-transport.js +28 -0
  581. package/skills/wix-replatform/resources/rp-target-wix/lib/value-utils.js +14 -0
  582. package/skills/wix-replatform/resources/rp-target-wix/lib/variant-correlation.js +34 -0
  583. package/skills/wix-replatform/resources/rp-target-wix/lib/wix-build.js +166 -15
  584. package/skills/wix-replatform/resources/rp-target-wix/lib/wix-target-spec.js +19 -2
  585. package/skills/wix-replatform/resources/rp-target-wix/lib/wix-writers.js +4079 -257
  586. package/skills/wix-replatform/resources/rp-target-wix/lib/write-verification.js +3 -0
  587. package/skills/wix-replatform/resources/rp-target-wix/scripts/docs-survey-sync.js +150 -0
  588. package/skills/wix-replatform/resources/rp-target-wix/scripts/domain-knowledge-validate.js +40 -2
  589. package/skills/wix-replatform/resources/rp-target-wix/scripts/verify-stores.js +6 -1
  590. package/skills/wix-replatform/resources/rp-telemetry/SKILL.md +148 -8
  591. package/skills/wix-replatform/resources/rp-telemetry/lib/bi-sink.js +83 -15
  592. package/skills/wix-replatform/resources/rp-telemetry/lib/telemetry-recorder.js +1119 -215
  593. package/skills/wix-replatform/resources/rp-telemetry/lib/transcript-digest.js +318 -0
  594. package/skills/wix-replatform/resources/rp-telemetry/scripts/meter-from-audit.js +2 -2
  595. package/skills/wix-replatform/resources/rp-telemetry/scripts/rp-telemetry.js +106 -4
  596. package/skills/wix-replatform/resources/rp-website-continuation/SKILL.md +94 -0
  597. package/skills/wix-replatform/scripts/census-reconciliation.js +25 -0
  598. package/skills/wix-replatform/scripts/cms-fallback.js +89 -0
  599. package/skills/wix-replatform/scripts/discovered-census.js +26 -0
  600. package/skills/wix-replatform/scripts/discovered-set-status.js +33 -0
  601. package/skills/wix-replatform/scripts/entity-qa-attestation.js +130 -0
  602. package/skills/wix-replatform/scripts/execution-health-check.js +415 -0
  603. package/skills/wix-replatform/scripts/execution-manifest-validate.js +1 -1
  604. package/skills/wix-replatform/scripts/execution-state-prepare.js +1 -1
  605. package/skills/wix-replatform/scripts/expectations-ledger.js +44 -0
  606. package/skills/wix-replatform/scripts/import-contract-verify.js +183 -0
  607. package/skills/wix-replatform/scripts/internal-link-audit.js +90 -0
  608. package/skills/wix-replatform/scripts/item-seo-tags-verify.js +205 -0
  609. package/skills/wix-replatform/scripts/migration-completion.js +76 -0
  610. package/skills/wix-replatform/scripts/orchestration-preflight.js +21 -2
  611. package/skills/wix-replatform/scripts/orchestration-route.js +32 -1
  612. package/skills/wix-replatform/scripts/orchestration-state.js +146 -10
  613. package/skills/wix-replatform/scripts/read-back-gate.js +175 -0
  614. package/skills/wix-replatform/scripts/replatform-console.js +146 -0
  615. package/skills/wix-replatform/scripts/replatform.js +436 -0
  616. package/skills/wix-replatform/scripts/source-secrets.js +77 -0
  617. package/skills/wix-replatform/scripts/url-redirects.js +286 -0
  618. package/skills/wix-replatform/scripts/user-action.js +58 -0
  619. package/skills/wix-replatform/scripts/website-handoff-generate.js +64 -0
  620. package/skills/wix-replatform/scripts/wix-dashboard-url.js +54 -0
  621. package/skills/wix-replatform/scripts/wix-destination.js +143 -0
  622. package/skills/wix-replatform/scripts/wix-headless-scaffold.js +762 -0
  623. package/skills/wix-vibe-headless/SKILL.md +7 -3
  624. package/skills/wix-vibe-headless/install/deploy.cjs +61 -34
  625. package/skills/wix-vibe-headless/platforms/base44.md +1 -0
  626. package/skills/wix-vibe-headless/references/donations/INSTRUCTIONS.md +88 -0
  627. package/skills/wix-vibe-headless/references/donations/app/rest/wix-donations.js +112 -0
  628. package/skills/wix-vibe-headless/references/donations/seed/SEED.md +11 -0
  629. package/skills/wix-vibe-headless/references/donations/tests/donations.test.mjs +258 -0
  630. package/skills/wix-vibe-headless/references/restaurants/INSTRUCTIONS.md +5 -2
  631. package/skills/wix-vibe-headless/references/restaurants/app/context/OrderCartContext.jsx +4 -1
  632. package/skills/wix-vibe-headless/references/restaurants/app/rest/wix-restaurants-ordering.js +67 -3
  633. package/skills/wix-vibe-headless/references/shared/app/rest/wix-client.js +4 -3
  634. package/skills/wix-manage/references/custom-apps/use-app-skills-and-app-tools.md +0 -208
  635. package/skills/wix-replatform/resources/rp-target-wix/SPEC-product-reviews-and-blog-authorship.md +0 -330
@@ -0,0 +1,370 @@
1
+ #!/usr/bin/env node
2
+ import path from "node:path";
3
+ import { docsDir, normalizeUrl, parseArgs, readJson, resolveOutputDir, writeJson } from "./lib/common.mjs";
4
+ import { verifyFrozenManifest } from "./lib/extraction-contract.mjs";
5
+
6
+ async function main() {
7
+ const args = parseArgs();
8
+ const url = normalizeUrl(args._[0] || args.url).toString();
9
+ const outputDir = resolveOutputDir(url, args.out);
10
+ const report = await visualQa({ outputDir });
11
+ await writeJson(path.join(docsDir(outputDir), "qa", "visual-qa.json"), report);
12
+ if (args.json) process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
13
+ else console.log(`Visual QA heuristic score: ${report.score}/100`);
14
+ }
15
+
16
+ export async function visualQa({ outputDir }) {
17
+ const dir = docsDir(outputDir);
18
+ const latest = await safeRead(path.join(dir, "extraction", "latest.json"), null);
19
+ if (!latest?.captureId) return missingManifestReport();
20
+ const extractionDir = path.join(dir, "extraction", latest.captureId);
21
+ const integrity = await verifyFrozenManifest(extractionDir);
22
+ const observations = path.join(extractionDir, "observations");
23
+ const page = await safeRead(path.join(observations, "page.json"), {});
24
+ const seo = await safeRead(path.join(observations, "seo.json"), {});
25
+ const sourceMap = { pages: [page], seo };
26
+ const interactionMap = await safeRead(path.join(observations, "interaction-map.json"), { interactions: [], structural: {} });
27
+ const sceneContract = await safeRead(path.join(observations, "scene-contract.json"), { scenes: [] });
28
+ const controlStateContract = await safeRead(path.join(observations, "control-state-contract.json"), { controls: [] });
29
+ const visualAssets = await safeRead(path.join(observations, "visual-assets.json"), { logos: [], icons: [] });
30
+ const layoutBlueprint = await safeRead(path.join(observations, "layout-blueprint.json"), { pages: [] });
31
+ const buildPlan = await safeRead(path.join(dir, "build", "build-plan.json"), { units: [] });
32
+ const ledger = await safeRead(path.join(dir, "build", "section-implementation.json"), { units: [] });
33
+ const specIndex = await safeRead(path.join(extractionDir, "spec-index.json"), {});
34
+ const extractionGaps = await safeRead(path.join(extractionDir, "extraction-gaps.json"), { gaps: [] });
35
+ const chromePages = (sourceMap.pages || []).filter((page) => page.chrome);
36
+ const implementationText = await readImplementationText(outputDir);
37
+ const chromeWarnings = chromeReviewWarnings({ chromePages, implementationText });
38
+ const repeaterWarnings = repeaterReviewWarnings({ pages: sourceMap.pages || [], implementationText });
39
+ const interactionWarnings = interactionReviewWarnings({ pages: sourceMap.pages || [], interactionMap, implementationText });
40
+ const checks = [];
41
+ checks.push(check("frozen manifest integrity", integrity.ok && integrity.manifest.manifestHash === latest.manifestHash, 20, integrity.failures));
42
+ checks.push(check("home build plan matches manifest", buildPlan.manifestHash === latest.manifestHash, 10));
43
+ checks.push(check("every planned unit has a build ledger entry", buildPlan.units?.every((unit) => ledger.units?.some((entry) => entry.id === unit.id && entry.specHash === unit.hash)), 10));
44
+ checks.push(check("source pages extracted", sourceMap.pages?.length > 0, 10));
45
+ checks.push(check("text content captured", sourceMap.pages?.some((p) => p.sections?.some((s) => s.text?.length > 80)), 15));
46
+ checks.push(check("seo captured", Boolean(sourceMap.seo?.title || sourceMap.pages?.some((p) => p.seo?.title)), 10));
47
+ checks.push(check("screenshots captured or fallback recorded", sourceMap.pages?.some((p) => Object.keys(p.screenshots || {}).length > 0 || p.extractionWarnings?.length), 5));
48
+ checks.push(check("stateful scene contract generated", Array.isArray(sceneContract.scenes) && sceneContract.scenes.length > 0, 10));
49
+ checks.push(check("control state contract generated", Array.isArray(controlStateContract.controls) && controlStateContract.controls.length > 0, 10));
50
+ checks.push(check("source logo assets materialized", (visualAssets.logos || []).length > 0 && (visualAssets.logos || []).every((logo) => Boolean(logo.localPath || logo.sourceUrl)), 10));
51
+ checks.push(check("important text geometry captured", (layoutBlueprint.pages || []).some((page) => page.sections?.some((section) => section.regions?.some((region) => region.textGeometry?.lineCount))), 10));
52
+ checks.push(check("chrome evidence captured or fallback warning recorded", chromeEvidenceAvailable(sourceMap.pages), 10));
53
+ checks.push(check("repeaters preserved or manually flagged", !repeaterWarnings.some((warning) => warning.kind === "collapsed-repeater"), 5, repeaterWarnings.filter((warning) => warning.kind === "collapsed-repeater").map((warning) => warning.message)));
54
+ checks.push(check("repeater headings preserved or manually flagged", !repeaterWarnings.some((warning) => warning.kind === "missing-repeater-headings"), 5, repeaterWarnings.filter((warning) => warning.kind === "missing-repeater-headings").map((warning) => warning.message)));
55
+ checks.push(check("multi-image repeaters preserved or manually flagged", !repeaterWarnings.some((warning) => warning.kind === "collapsed-multi-image-repeater"), 5, repeaterWarnings.filter((warning) => warning.kind === "collapsed-multi-image-repeater").map((warning) => warning.message)));
56
+ checks.push(check("dropdown hierarchy preserved or manually flagged", !chromeWarnings.some((warning) => warning.kind === "flattened-dropdown"), 10, chromeWarnings.filter((warning) => warning.kind === "flattened-dropdown").map((warning) => warning.message)));
57
+ checks.push(check("sticky header footprint reviewed", !chromeWarnings.some((warning) => warning.kind === "sticky-header-footprint"), 5, chromeWarnings.filter((warning) => warning.kind === "sticky-header-footprint").map((warning) => warning.message)));
58
+ checks.push(check("seo-only hero text reviewed", !chromeWarnings.some((warning) => warning.kind === "seo-only-hero-text"), 5, chromeWarnings.filter((warning) => warning.kind === "seo-only-hero-text").map((warning) => warning.message)));
59
+ checks.push(check("core interaction evidence consumed", !interactionWarnings.some((warning) => warning.kind !== "manual-interaction-review"), 20, interactionWarnings.filter((warning) => warning.kind !== "manual-interaction-review").map((warning) => warning.message)));
60
+ checks.push(check("source footer content preserved", !interactionWarnings.some((warning) => warning.kind === "missing-footer-content" || warning.kind === "clone-process-copy"), 10, interactionWarnings.filter((warning) => warning.kind === "missing-footer-content" || warning.kind === "clone-process-copy").map((warning) => warning.message)));
61
+ const rawScore = checks.reduce((sum, item) => sum + (item.pass ? item.points : 0), 0);
62
+ const possiblePoints = checks.reduce((sum, item) => sum + item.points, 0);
63
+ const unitAcceptance = await acceptanceResults({
64
+ extractionDir,
65
+ buildPlan,
66
+ ledger,
67
+ specIndex,
68
+ gaps: extractionGaps.gaps || [],
69
+ });
70
+ return {
71
+ score: possiblePoints ? Math.round((rawScore / possiblePoints) * 100) : 0,
72
+ rawScore,
73
+ possiblePoints,
74
+ checks,
75
+ unitAcceptance,
76
+ pageAcceptance: checks.map(({ name, pass, warnings = [] }) => ({
77
+ criterion: name,
78
+ status: pass ? "verified" : "failed-or-pending",
79
+ warnings,
80
+ })),
81
+ warnings: [...chromeWarnings, ...repeaterWarnings, ...interactionWarnings].map((warning) => warning.message),
82
+ manifestHash: latest.manifestHash,
83
+ provisionalUnits: buildPlan.units?.filter((unit) => unit.status === "provisional").map((unit) => unit.id) || [],
84
+ note: "Frozen-spec preflight only. Run browser-backed result comparison and report unresolved local gaps without blocking unrelated units.",
85
+ generatedAt: new Date().toISOString(),
86
+ };
87
+ }
88
+
89
+ async function acceptanceResults({ extractionDir, buildPlan, ledger, specIndex, gaps }) {
90
+ const gapById = new Map(gaps.map((gap) => [gap.id, gap]));
91
+ const ledgerById = new Map((ledger.units || []).map((entry) => [entry.id, entry]));
92
+ const results = [];
93
+ for (const unit of buildPlan.units || []) {
94
+ const relativePath = specIndex[unit.id];
95
+ const spec = relativePath ? await safeRead(path.join(extractionDir, relativePath), {}) : {};
96
+ const ledgerEntry = ledgerById.get(unit.id);
97
+ const ownedGaps = (unit.gapRefs || []).map((id) => gapById.get(id)).filter(Boolean);
98
+ const unresolvedGapRefs = ownedGaps
99
+ .filter((gap) => !["resolved", "user-accepted"].includes(gap.status))
100
+ .map((gap) => gap.id);
101
+ const viewports = Object.values(ledgerEntry?.verification || {});
102
+ const browserVerified = viewports.length > 0 && viewports.every((status) => status === "passed");
103
+ const implementationMatches = Boolean(ledgerEntry && ledgerEntry.specHash === unit.hash);
104
+ const required = Array.isArray(spec.acceptance?.required) ? spec.acceptance.required : [];
105
+ const criteria = required.map((criterion) => ({
106
+ criterion,
107
+ status: !implementationMatches
108
+ ? "not-implemented"
109
+ : unresolvedGapRefs.length
110
+ ? "provisional-gap-backed"
111
+ : browserVerified
112
+ ? "verified"
113
+ : "pending-browser-verification",
114
+ ...(unresolvedGapRefs.length ? { gapRefs: unresolvedGapRefs } : {}),
115
+ }));
116
+ results.push({
117
+ unitId: unit.id,
118
+ specHash: unit.hash,
119
+ implementationMatches,
120
+ status: criteria.length && criteria.every((entry) => entry.status === "verified")
121
+ ? "verified"
122
+ : unresolvedGapRefs.length
123
+ ? "provisional"
124
+ : implementationMatches
125
+ ? "verification-pending"
126
+ : "not-implemented",
127
+ criteria,
128
+ sourceAssertions: spec.acceptance?.sourceAssertions || [],
129
+ gapRefs: unresolvedGapRefs,
130
+ });
131
+ }
132
+ return results;
133
+ }
134
+
135
+ function missingManifestReport() {
136
+ return {
137
+ score: 0,
138
+ rawScore: 0,
139
+ possiblePoints: 20,
140
+ checks: [{ name: "frozen manifest integrity", pass: false, points: 20, warnings: ["No frozen extraction manifest exists."] }],
141
+ warnings: ["No frozen extraction manifest exists."],
142
+ provisionalUnits: [],
143
+ note: "Extraction must freeze before build QA.",
144
+ generatedAt: new Date().toISOString(),
145
+ };
146
+ }
147
+
148
+ function interactionReviewWarnings({ pages, interactionMap, implementationText }) {
149
+ const warnings = [];
150
+ if (!implementationText) return [{ kind: "manual-interaction-review", message: "No implementation source exists yet; verify every core interaction after UI code is written." }];
151
+ const required = new Set((pages || []).flatMap((page) => page.interactionDiscovery?.requiredBehaviors || []));
152
+ const media = interactionMap.structural?.media || (pages || []).flatMap((page) => page.interactionDiscovery?.media || []);
153
+ for (const item of media.filter((entry) => entry.src && entry.role === "background")) {
154
+ if (!mediaReferenced(implementationText, item.src)) {
155
+ warnings.push({ kind: "missing-embedded-media", message: `Required ${item.provider || item.tag} background media is not referenced by the implementation: ${item.src}` });
156
+ }
157
+ }
158
+ if (required.has("preserve-carousel-card-expansion") && !(/carousel|story-rail|rail-track|case-card/i.test(implementationText) && /overflow-x|overflow\s*:\s*auto|scrollLeft|scrollWidth|translateX/i.test(implementationText) && /active|expanded/i.test(implementationText))) {
159
+ warnings.push({ kind: "flattened-carousel", message: "Source carousel has an active-card expansion state, but implementation does not show an overflowing rail with active/expanded state handling." });
160
+ }
161
+ if (required.has("preserve-scroll-expanded-section-state") && !(/position\s*:\s*(sticky|fixed)|scrolltrigger|intersectionobserver/i.test(implementationText) && /scroll/i.test(implementationText))) {
162
+ warnings.push({ kind: "flattened-scroll-state", message: "Source scroll-state section is required, but implementation does not show pinned/sticky scroll-state handling." });
163
+ }
164
+ if (/this cloned homepage|development reconstruction|first-pass clone|video background unavailable/i.test(implementationText)) {
165
+ warnings.push({ kind: "clone-process-copy", message: "Implementation contains clone/migration-process copy that must not appear on a migrated source page." });
166
+ }
167
+ for (const page of pages || []) {
168
+ const legalText = String(page.footer?.legalText || "").replace(/\s+/g, " ").trim();
169
+ const meaningful = legalText.split(/(?<=[.!?])\s+/).find((sentence) => sentence.length >= 80);
170
+ if (meaningful && !implementationText.includes(meaningful.slice(0, 80))) {
171
+ warnings.push({ kind: "missing-footer-content", message: "Source footer legal text was extracted but is not present in implementation source." });
172
+ }
173
+ }
174
+ return warnings;
175
+ }
176
+
177
+ function mediaReferenced(implementationText, source) {
178
+ const canonicalSource = canonicalMediaUrl(source);
179
+ if (implementationText.includes(source) || implementationText.includes(canonicalSource)) return true;
180
+ return canonicalSource ? implementationText.includes(canonicalSource.replace(/&amp;/g, "&")) : false;
181
+ }
182
+
183
+ function canonicalMediaUrl(value) {
184
+ const raw = String(value || "").trim();
185
+ if (!raw) return raw;
186
+ try {
187
+ const url = new URL(raw);
188
+ url.search = url.search.replace(/\?([^?]*)\?/g, "?$1&");
189
+ return url.toString();
190
+ } catch {
191
+ return raw.replace(/\?([^?]*)\?/g, "?$1&");
192
+ }
193
+ }
194
+
195
+ function repeaterReviewWarnings({ pages, implementationText }) {
196
+ const warnings = [];
197
+ for (const page of pages || []) {
198
+ for (const warning of page.repeaterDiagnostics?.warnings || []) {
199
+ warnings.push({
200
+ kind: "manual-repeater-review",
201
+ message: `Source page ${page.path || page.url}: ${warning}`,
202
+ });
203
+ }
204
+ for (const repeater of page.repeaters || []) {
205
+ if (!implementationText) {
206
+ warnings.push({
207
+ kind: "manual-repeater-review",
208
+ message: `Source page ${page.path || page.url} has structured repeater content (${repeater.itemCount || repeater.items?.length || 0} items); verify the implementation consumes repeaters instead of flattening the content.`,
209
+ });
210
+ continue;
211
+ }
212
+ const headings = (repeater.items || []).map((item) => item.heading).filter(Boolean);
213
+ const matchedHeadings = headings.filter((heading) => implementationText.includes(heading)).length;
214
+ const hasRepeaterStructure = /\brepeaters\b|\bstories\b|\bitems\b|\bmap\s*\(/.test(implementationText);
215
+ if (headings.length && matchedHeadings < Math.min(3, headings.length)) {
216
+ warnings.push({
217
+ kind: "missing-repeater-headings",
218
+ message: `Source page ${page.path || page.url} has ${headings.length} repeater heading(s), but fewer than ${Math.min(3, headings.length)} appear in implementation files.`,
219
+ });
220
+ }
221
+ if (matchedHeadings >= Math.min(3, headings.length) && !hasRepeaterStructure) {
222
+ warnings.push({
223
+ kind: "collapsed-repeater",
224
+ message: `Source page ${page.path || page.url} has structured repeater items, but implementation files contain multiple repeater headings without an obvious repeated-content structure.`,
225
+ });
226
+ }
227
+ if ((repeater.schema?.maxImagesPerItem || 0) > 1) {
228
+ const supportsMultipleImages = /\bimages\b|\bgallery\b|\bcarousel\b|map\s*\(\s*\(?image\b|image[s2-9]/.test(implementationText);
229
+ if (!supportsMultipleImages) {
230
+ warnings.push({
231
+ kind: "collapsed-multi-image-repeater",
232
+ message: `Source page ${page.path || page.url} has repeater items with up to ${repeater.schema.maxImagesPerItem} images each, but implementation files do not show an obvious multi-image item structure.`,
233
+ });
234
+ }
235
+ }
236
+ }
237
+ }
238
+ return warnings;
239
+ }
240
+
241
+ function check(name, pass, points, warnings = []) {
242
+ return { name, pass: Boolean(pass), points, ...(warnings.length ? { warnings } : {}) };
243
+ }
244
+
245
+ async function existsJsonOrText(filePath) {
246
+ try {
247
+ await import("node:fs/promises").then(({ access }) => access(filePath));
248
+ return true;
249
+ } catch {
250
+ return false;
251
+ }
252
+ }
253
+
254
+ async function safeRead(filePath, fallback) {
255
+ try {
256
+ return await readJson(filePath);
257
+ } catch {
258
+ return fallback;
259
+ }
260
+ }
261
+
262
+ function chromeEvidenceAvailable(pages = []) {
263
+ return pages.some((page) => {
264
+ if (!page.chrome) return false;
265
+ if (page.chrome.warnings?.length) return true;
266
+ return Boolean(page.chrome.header?.variants?.length || page.chrome.navigation?.length || page.chrome.heroEvidence);
267
+ });
268
+ }
269
+
270
+ function chromeReviewWarnings({ chromePages, implementationText }) {
271
+ const warnings = [];
272
+ if (!chromePages.length) {
273
+ warnings.push({
274
+ kind: "manual-chrome-review",
275
+ message: "No chrome evidence is available; manually review header behavior, menu hierarchy, logo size, and hero text before completion.",
276
+ });
277
+ return warnings;
278
+ }
279
+ for (const page of chromePages) {
280
+ for (const warning of page.chrome?.warnings || []) {
281
+ warnings.push({ kind: "manual-chrome-review", message: warning });
282
+ }
283
+ const dropdowns = (page.chrome?.navigation || []).filter((item) => item.children?.length);
284
+ if (dropdowns.length && implementationText) {
285
+ for (const dropdown of dropdowns) {
286
+ const childLabels = dropdown.children.map((child) => child.label).filter(Boolean);
287
+ const hasStructuredChildren = /children\s*[:=]|\bsubmenu\b|\bdropdown\b|<details\b|aria-haspopup/.test(implementationText);
288
+ const flattenedCount = childLabels.filter((label) => implementationText.includes(label)).length;
289
+ if (!hasStructuredChildren && flattenedCount >= Math.min(3, childLabels.length)) {
290
+ warnings.push({
291
+ kind: "flattened-dropdown",
292
+ message: `Navigation dropdown "${dropdown.label || dropdown.href}" has ${childLabels.length} source child item(s), but implementation files contain child labels without an obvious submenu structure.`,
293
+ });
294
+ }
295
+ }
296
+ } else if (dropdowns.length && !implementationText) {
297
+ warnings.push({
298
+ kind: "manual-chrome-review",
299
+ message: `Source navigation has dropdowns (${dropdowns.map((item) => item.label || item.href).join(", ")}); verify implementation preserves them as submenus after UI code exists.`,
300
+ });
301
+ }
302
+
303
+ const variants = page.chrome?.header?.variants || [];
304
+ const initial = variants.find((variant) => variant.name === "initial");
305
+ const scrolled = variants.find((variant) => variant.name === "scrolled");
306
+ const viewportHeight = page.chrome?.viewport?.height || 1200;
307
+ const limit = page.chrome?.header?.maxStickyViewportRatio || 0.16;
308
+ if (implementationText && initial?.height && initial.height / viewportHeight > limit && /position\s*:\s*sticky|position\s*:\s*fixed/.test(implementationText)) {
309
+ const hasCompactState = /scrolled|compact|is-sticky|shrink|small-header|sticky-header/.test(implementationText);
310
+ if (!hasCompactState && (!scrolled?.height || scrolled.height < initial.height * 0.75)) {
311
+ warnings.push({
312
+ kind: "sticky-header-footprint",
313
+ message: `Source initial header is large (${initial.height}px); implementation appears to use sticky/fixed positioning without an obvious compact scrolled state.`,
314
+ });
315
+ }
316
+ }
317
+
318
+ const seoOnly = page.chrome?.heroEvidence?.forbiddenSeoOnlyText || [];
319
+ if (implementationText && seoOnly.some((text) => text.length > 12 && implementationText.includes(text))) {
320
+ warnings.push({
321
+ kind: "seo-only-hero-text",
322
+ message: "Implementation contains SEO-only title/tagline text that was not confirmed as visible first-viewport hero content.",
323
+ });
324
+ } else if (!implementationText && seoOnly.length) {
325
+ warnings.push({
326
+ kind: "manual-chrome-review",
327
+ message: "SEO-only title/tagline text was detected; verify it is not rendered as hero copy without visual source evidence.",
328
+ });
329
+ }
330
+ }
331
+ return warnings;
332
+ }
333
+
334
+ async function readImplementationText(outputDir) {
335
+ const srcDir = path.join(outputDir, "src");
336
+ const files = await listSourceFiles(srcDir);
337
+ const chunks = [];
338
+ for (const file of files.slice(0, 80)) {
339
+ try {
340
+ const { readFile } = await import("node:fs/promises");
341
+ chunks.push(await readFile(file, "utf8"));
342
+ } catch {
343
+ // Ignore unreadable generated files during heuristic QA.
344
+ }
345
+ }
346
+ return chunks.join("\n").slice(0, 500000);
347
+ }
348
+
349
+ async function listSourceFiles(dir) {
350
+ try {
351
+ const { readdir } = await import("node:fs/promises");
352
+ const entries = await readdir(dir, { withFileTypes: true });
353
+ const files = [];
354
+ for (const entry of entries) {
355
+ const fullPath = path.join(dir, entry.name);
356
+ if (entry.isDirectory()) files.push(...await listSourceFiles(fullPath));
357
+ else if (/\.(astro|tsx?|jsx?|css|scss)$/.test(entry.name)) files.push(fullPath);
358
+ }
359
+ return files;
360
+ } catch {
361
+ return [];
362
+ }
363
+ }
364
+
365
+ if (import.meta.url === `file://${process.argv[1]}`) {
366
+ main().catch((error) => {
367
+ console.error(error.stack || error.message);
368
+ process.exit(1);
369
+ });
370
+ }
@@ -6,8 +6,19 @@ typed end-to-end. **The presentation is yours**: you design and implement the ca
6
6
  campaigns index, the campaign page's layout around the shipped form, the home page and the brand. You
7
7
  never write checkout logic; you never skip designing.
8
8
 
9
+ Read [Donations experience](../../wix-headless/references/inline-recipes/experience-donations.md)
10
+ before designing the donor surfaces. If that sibling skill is not installed, read the
11
+ [published overlay](https://www.wix.com/skills/wix-headless/references/inline-recipes/experience-donations.md).
12
+ It supplies the short,
13
+ framework-independent page/form quality bar; the code contracts below supply the implementation.
14
+ Apply its intent/draft recovery requirements in the UI layer: extend the supplied form/store where
15
+ needed, retaining its validation and checkout exports. In-memory defaults alone do not survive an
16
+ external checkout. Do not put donor notes in route parameters or reset them on an unverified return.
17
+
9
18
  A donation is an eCom cart (Cart V2) with one line that references the campaign; in V2 the cart IS the
10
19
  checkout, so the cart's id is the id the redirect session takes — there is no separate checkout entity.
20
+ The cart's donation `options.amount` is a **number**, even though campaign price amounts are strings.
21
+ Omit `options.frequency` for one-time giving; send only `WEEK`, `MONTH`, `YEAR` for recurring giving.
11
22
  Wix's hosted checkout takes the payment and the donor's details, and the eCom order is the receipt. The campaign entity carries
12
23
  **no description and no slug**: the story on a campaign page is the site's own copy, and routes key by
13
24
  the campaign id (`/donate/<id>`).
@@ -65,23 +76,9 @@ Astro stack additionally gets:
65
76
 
66
77
  Plus the **theme** (`@theme` block, one edit) and the **chrome** (`SiteLayout`, one pass).
67
78
 
68
- ### What a complete donations site shows (recommended defaults)
69
-
70
- Defaults for a brief that says nothing about them; the prompt wins where it differs. Look at the
71
- campaigns before designing (how many, goals or not, frequencies, presets, images).
72
-
73
- - **Campaign page:** the Donate CTA and the amount picker in the first screen at 390px wide; the
74
- frequency picker only when the campaign offers more than one frequency (the form decides); the
75
- custom amount only when enabled; the story after the form on phones, beside it on desktop.
76
- - **Closed campaigns** (goal reached / expired): the progress and a closing message — never a Donate
77
- button. `DonateForm` renders your `children` then; the card shows the state, not a CTA.
78
- - **Goal figures only from the DTO:** raised, target, percent, count, time left come from the metrics
79
- API and the owner's goal. A campaign without a goal shows no progress; a goal whose raised total
80
- couldn't be read shows the target alone.
81
- - **Copy:** nothing the owner didn't supply — no donor counts beyond `donationCount`, no "tax
82
- deductible", no urgency the owner didn't set, no Wix IDs in visible text.
83
- - **Thank-you page:** the shipped island's rules — thanks with the order's facts when they can be
84
- read, thanks without them otherwise, never "paid" unless the order says so.
79
+ The shared Donations experience overlay above owns page composition, mobile density, truthful
80
+ progress/copy and return-state quality. The contracts below own the wiring; apply both rather than
81
+ maintaining a second set of design rules here.
85
82
 
86
83
  ### The contracts your components consume (tested and work as they are; read the source when something is off or the brief wants more)
87
84
 
@@ -107,7 +104,8 @@ campaigns before designing (how many, goals or not, frequencies, presets, images
107
104
  // submitting, error, available /* campaign.acceptsDonations */,
108
105
  // selectPreset(n), selectCustom(), setCustomAmount(text), setFrequency(f), setCoverFee(b), setNote(s),
109
106
  // donate(): Promise<void> } // resolves as the browser navigates to the hosted checkout (or with
110
- // // messages showing); rejects with a visitor-facing message — surface it
107
+ // // messages showing); rejects with the original diagnostic error;
108
+ // // render state.error for the visitor, not the raw API response
111
109
  // <DonateForm campaign={c} options? children? className? buttonClassName? /> wraps it: you only place
112
110
  // it; it decides what to render, what to say, and shows its own errors.
113
111
 
@@ -288,6 +286,18 @@ Wix as a return target must be one the host serves (SKILL.md step 1) — pass it
288
286
  - **Browsing and donating need no login.** They run on the visitor session the shipped client already
289
287
  holds; don't gate campaigns behind sign-in.
290
288
 
289
+ ## Verify the donation handoff
290
+
291
+ Before calling this build working, follow the bounded anonymous API smoke test in
292
+ [How to Code Donations](../../wix-headless/references/inline-recipes/how-to-code-donations.md#5-verify-before-handoff):
293
+ campaign read → one Cart V2 → calculated line/totals → redirect session, using the same visitor.
294
+ Use the sibling file when installed, otherwise
295
+ `https://www.wix.com/skills/wix-headless/references/inline-recipes/how-to-code-donations.md`.
296
+ Do not add a V1 Create Checkout step. A local test or a session URL is not proof of payment. Report
297
+ API, hosted-checkout and payment verification separately; no payment without explicit authorization.
298
+ For `ITEM_NOT_FOUND_IN_CATALOG`, inspect numeric amount, app/campaign IDs and frequency first, not
299
+ reinstallation or premium. Keep sanitized error code/body/stage for diagnosis; do not swallow failures.
300
+
291
301
  ## Out of scope (don't improvise these)
292
302
 
293
303
  A donor's history or receipts page (member-only order reads), managing a recurring donation (Wix's
@@ -308,16 +318,19 @@ Hand the owner these links — `{siteId}` is `siteId` in `wix.config.json` (the
308
318
  | Accept payments — connect a payment method | `wix-cashier/payments` |
309
319
  | Upgrade the plan — online payments need premium | full URL: `https://www.wix.com/upgrade/website?metaSiteId={siteId}` |
310
320
 
311
- **Taking real donations needs a connected payment method plus a premium plan.** Until both are done, a visitor who reaches hosted checkout sees **"We can't accept online payments. Contact us for help with your order."** Recurring frequencies (`WEEK`/`MONTH`/`YEAR`) additionally need a
321
+ **Taking real donations needs a connected payment method plus a payments-capable plan.** Cart/session
322
+ creation can succeed before these are ready; it does not prove a charge can succeed. Do not use a
323
+ premium explanation for a malformed catalog reference. A visitor can encounter an unavailable-payments
324
+ message at hosted checkout until setup is complete. Recurring frequencies (`WEEK`/`MONTH`/`YEAR`) additionally need a
312
325
  payment provider that supports recurring payments. Mention it; don't treat it as a code failure. The
313
326
  cover-fee 2.9% is added to every recurring charge.
314
327
 
315
328
  ## Seeding
316
329
 
317
330
  Per `seed/SEED.md` — plain-data `plan.json` into `seed-donations.mjs` from the project root. Seed one
318
- campaign that exercises every form branch (3 presets with impact text, one-time + monthly, a goal with
319
- an end date, a custom amount with a minimum, note and cover-fee on, a cover image); a second campaign
320
- only when the brief lists several causes.
331
+ approved cause for a new setup unless the brief lists several. Do not invent impact claims, goals or
332
+ deadlines to exercise every form branch, and never reseed for a frontend-only request. Optional form
333
+ states can be tested in local fixtures. Ongoing edits use the shared management recipe linked there.
321
334
 
322
335
  ## Caveats — verified against the SDK, not yet against a live site
323
336
 
@@ -344,5 +357,5 @@ first real site and read the owning file if one bites.
344
357
  provisions eCom, is unverified; the seed installs both and reports each result.
345
358
  - **Dashboard route.** The `app/<appDefId>` link redirects to the app's slug route; the slug itself
346
359
  was not resolved live.
347
- - The `donorCoveringFees` option key and the fixed 2.9% come from the Wix widget's source, not a
348
- public reference page.
360
+ - The `donorCoveringFees` flag, 2.9% and one-time frequency omission are documented in the public
361
+ [donation eCommerce integration](https://dev.wix.com/docs/api-reference/business-solutions/donations/donation-campaigns/e-commerce-integration-with-donation-campaigns).
@@ -8,7 +8,7 @@
8
8
  // donations (goal reached / expired) it renders `children` — your closing message — or nothing.
9
9
  // The redirect itself is useDonation → donationCheckoutUrl; nothing here builds a URL or marks
10
10
  // anything paid.
11
- import type { ReactNode } from "react";
11
+ import { useId, type ReactNode } from "react";
12
12
  import { useDonation, type UseDonationOptions } from "../../hooks/donations/useDonation";
13
13
  import type { CampaignDetail } from "../../wix/donations/types";
14
14
 
@@ -23,7 +23,7 @@ export interface DonateFormProps {
23
23
  }
24
24
 
25
25
  const choice = (selected: boolean) =>
26
- `cursor-pointer rounded-md border px-4 py-3 text-sm transition-colors ${
26
+ `relative block cursor-pointer rounded-md border px-4 py-3 text-sm transition-colors focus-within:outline-2 focus-within:outline-offset-2 focus-within:outline-primary ${
27
27
  selected ? "border-primary bg-primary text-primary-foreground" : "border-border bg-background text-foreground hover:bg-secondary"
28
28
  }`;
29
29
 
@@ -36,10 +36,10 @@ export default function DonateForm({
36
36
  }: DonateFormProps) {
37
37
  const d = useDonation(campaign, options);
38
38
  const o = campaign.options;
39
+ const fid = `donate-${campaign.id}-${useId()}`;
39
40
  if (!d.available) return children ? <>{children}</> : null;
40
41
 
41
42
  const show = (field: keyof typeof d.messages) => (d.showErrors && d.messages[field] ? d.messages[field] : null);
42
- const fid = `donate-${campaign.id}`;
43
43
 
44
44
  return (
45
45
  <form
@@ -47,43 +47,65 @@ export default function DonateForm({
47
47
  noValidate
48
48
  onSubmit={(e) => {
49
49
  e.preventDefault();
50
- void d.donate().catch(() => {});
50
+ const form = e.currentTarget;
51
+ void d.donate().then(() => {
52
+ if (!d.valid) {
53
+ // Wait for the store's validation state to render; do not steal focus while typing.
54
+ requestAnimationFrame(() => form.querySelector<HTMLElement>('[aria-invalid="true"]')?.focus());
55
+ }
56
+ }).catch((error) => {
57
+ // The store shows a recoverable message; keep safe diagnostics, not donor data or tokens.
58
+ console.error("Donation checkout failed", {
59
+ stage: error?.stage ?? "checkout",
60
+ status: error?.status,
61
+ code: error?.body?.details?.applicationError?.code ?? error?.details?.applicationError?.code ?? error?.body?.code,
62
+ });
63
+ });
51
64
  }}
52
65
  >
53
66
  {o.frequencies.length > 1 && (
54
- <fieldset>
67
+ <fieldset disabled={d.submitting}>
55
68
  <legend className="eyebrow mb-2">How often</legend>
56
- <div className="grid grid-cols-2 gap-2 sm:grid-cols-4" role="radiogroup">
69
+ <div className="grid grid-cols-2 gap-2 sm:grid-cols-4">
57
70
  {o.frequencies.map((f) => (
58
- <button key={f.value} type="button" role="radio" aria-checked={d.frequency === f.value} className={choice(d.frequency === f.value)} onClick={() => d.setFrequency(f.value)}>
71
+ <label key={f.value} className={choice(d.frequency === f.value)}>
72
+ <input type="radio" name={`${fid}-frequency`} value={f.value} checked={d.frequency === f.value}
73
+ onChange={() => d.setFrequency(f.value)} className="sr-only"
74
+ aria-invalid={!!show("frequency")} aria-describedby={show("frequency") ? `${fid}-frequency-error` : undefined} />
59
75
  {f.label}
60
- </button>
76
+ </label>
61
77
  ))}
62
78
  </div>
63
- {show("frequency") && <p className="mt-2 text-sm text-destructive" role="alert">{show("frequency")}</p>}
79
+ {show("frequency") && <p id={`${fid}-frequency-error`} className="mt-2 text-sm text-destructive" role="alert">{show("frequency")}</p>}
64
80
  </fieldset>
65
81
  )}
66
82
 
67
83
  {(o.presets.length > 0 || o.customAmount.enabled) && (
68
- <fieldset>
84
+ <fieldset disabled={d.submitting}>
69
85
  <legend className="eyebrow mb-2">Amount</legend>
70
- <div className="grid grid-cols-2 gap-2 sm:grid-cols-3" role="radiogroup">
86
+ <div className="grid grid-cols-2 gap-2 sm:grid-cols-3">
71
87
  {o.presets.map((p) => {
72
88
  const selected = !d.customMode && d.presetAmount === p.amount;
73
89
  return (
74
- <button key={p.amount} type="button" role="radio" aria-checked={selected} className={`${choice(selected)} text-left`} onClick={() => d.selectPreset(p.amount)}>
90
+ <label key={p.amount} className={`${choice(selected)} text-left`}>
91
+ <input type="radio" name={`${fid}-amount-choice`} value={p.amount} checked={selected}
92
+ onChange={() => d.selectPreset(p.amount)} className="sr-only"
93
+ aria-invalid={!!show("amount")} aria-describedby={show("amount") ? `${fid}-amount-error` : undefined} />
75
94
  <span className="block text-base font-semibold">{p.label}</span>
76
95
  {p.impact && <span className={`mt-0.5 block text-xs ${selected ? "opacity-80" : "text-muted-foreground"}`}>{p.impact}</span>}
77
- </button>
96
+ </label>
78
97
  );
79
98
  })}
80
99
  {o.customAmount.enabled && o.presets.length > 0 && (
81
- <button type="button" role="radio" aria-checked={d.customMode} className={choice(d.customMode)} onClick={() => d.selectCustom()}>
100
+ <label className={choice(d.customMode)}>
101
+ <input type="radio" name={`${fid}-amount-choice`} value="custom" checked={d.customMode}
102
+ onChange={() => d.selectCustom()} className="sr-only"
103
+ aria-invalid={!!show("amount")} aria-describedby={show("amount") ? `${fid}-amount-error` : undefined} />
82
104
  Other amount
83
- </button>
105
+ </label>
84
106
  )}
85
107
  </div>
86
- {show("amount") && <p className="mt-2 text-sm text-destructive" role="alert">{show("amount")}</p>}
108
+ {show("amount") && <p id={`${fid}-amount-error`} className="mt-2 text-sm text-destructive" role="alert">{show("amount")}</p>}
87
109
  {d.customMode && (
88
110
  <div className="mt-3">
89
111
  <label htmlFor={`${fid}-amount`} className="sr-only">
@@ -95,19 +117,20 @@ export default function DonateForm({
95
117
  id={`${fid}-amount`}
96
118
  inputMode="decimal"
97
119
  autoComplete="off"
98
- className="w-full bg-transparent py-3 text-base text-foreground outline-none"
120
+ className="min-w-0 flex-1 bg-transparent py-3 text-base text-foreground outline-none focus-visible:ring-2 focus-visible:ring-primary"
99
121
  placeholder={o.customAmount.minLabel ? `${o.customAmount.minLabel} or more` : "Enter an amount"}
100
122
  value={d.customAmount}
101
123
  onChange={(e) => d.setCustomAmount(e.target.value)}
102
124
  aria-invalid={!!show("customAmount")}
125
+ aria-describedby={show("customAmount") || o.customAmount.minLabel || o.customAmount.maxLabel ? `${fid}-custom-help` : undefined}
103
126
  />
104
127
  </div>
105
128
  {(o.customAmount.minLabel || o.customAmount.maxLabel) && !show("customAmount") && (
106
- <p className="mt-1 text-xs text-muted-foreground">
129
+ <p id={`${fid}-custom-help`} className="mt-1 text-xs text-muted-foreground">
107
130
  {[o.customAmount.minLabel && `Minimum ${o.customAmount.minLabel}`, o.customAmount.maxLabel && `Maximum ${o.customAmount.maxLabel}`].filter(Boolean).join(" · ")}
108
131
  </p>
109
132
  )}
110
- {show("customAmount") && <p className="mt-1 text-sm text-destructive" role="alert">{show("customAmount")}</p>}
133
+ {show("customAmount") && <p id={`${fid}-custom-help`} className="mt-1 text-sm text-destructive" role="alert">{show("customAmount")}</p>}
111
134
  </div>
112
135
  )}
113
136
  </fieldset>
@@ -115,7 +138,7 @@ export default function DonateForm({
115
138
 
116
139
  {o.askCoverFee && (
117
140
  <label className="flex items-start gap-3 text-sm text-foreground">
118
- <input type="checkbox" className="mt-0.5" checked={d.coverFee} onChange={(e) => d.setCoverFee(e.target.checked)} />
141
+ <input type="checkbox" className="mt-0.5" checked={d.coverFee} disabled={d.submitting} onChange={(e) => d.setCoverFee(e.target.checked)} />
119
142
  <span>
120
143
  {d.feeLabel ? `Add ${d.feeLabel} to cover the processing fees` : "Cover the processing fees (2.9%)"}
121
144
  {d.frequency && d.frequency !== "ONE_TIME" && <span className="text-muted-foreground"> — on every payment</span>}
@@ -132,14 +155,17 @@ export default function DonateForm({
132
155
  id={`${fid}-note`}
133
156
  rows={3}
134
157
  maxLength={o.commentMaxLength}
135
- className="w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground outline-none"
158
+ className="w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground outline-none focus-visible:ring-2 focus-visible:ring-primary"
136
159
  value={d.note}
137
160
  onChange={(e) => d.setNote(e.target.value)}
161
+ disabled={d.submitting}
162
+ aria-invalid={!!show("note")}
163
+ aria-describedby={`${fid}-note-hint${show("note") ? ` ${fid}-note-error` : ""}`}
138
164
  />
139
- <p className="mt-1 text-right text-xs text-muted-foreground">
165
+ <p id={`${fid}-note-hint`} className="mt-1 text-right text-xs text-muted-foreground">
140
166
  {d.note.length}/{o.commentMaxLength}
141
167
  </p>
142
- {show("note") && <p className="text-sm text-destructive" role="alert">{show("note")}</p>}
168
+ {show("note") && <p id={`${fid}-note-error`} className="text-sm text-destructive" role="alert">{show("note")}</p>}
143
169
  </div>
144
170
  )}
145
171