@wix/agent-skills 1.33.1 → 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 (616) hide show
  1. package/README.md +2 -0
  2. package/package.json +1 -1
  3. package/skills/wix-export/SKILL.md +83 -0
  4. package/skills/wix-harmony-editor/.publish-manifest.json +8 -0
  5. package/skills/wix-harmony-editor/COPY-SITE.md +494 -0
  6. package/skills/wix-harmony-editor/SKILL.md +317 -0
  7. package/skills/wix-harmony-editor/scripts/copy/build-description.mjs +249 -0
  8. package/skills/wix-harmony-editor/scripts/copy/check-description.mjs +225 -0
  9. package/skills/wix-harmony-editor/scripts/copy/check-mirror.mjs +89 -0
  10. package/skills/wix-harmony-editor/scripts/copy/compare-preview.mjs +76 -0
  11. package/skills/wix-harmony-editor/scripts/copy/deploy-description.mjs +212 -0
  12. package/skills/wix-harmony-editor/scripts/copy/desc-hash.mjs +44 -0
  13. package/skills/wix-harmony-editor/scripts/copy/editor-run.mjs +45 -0
  14. package/skills/wix-harmony-editor/scripts/copy/export-page.mjs +53 -0
  15. package/skills/wix-harmony-editor/scripts/copy/find-interactions.mjs +76 -0
  16. package/skills/wix-harmony-editor/scripts/copy/hide-scrollbars.mjs +16 -0
  17. package/skills/wix-harmony-editor/scripts/copy/import-media.mjs +150 -0
  18. package/skills/wix-harmony-editor/scripts/copy/link-url.mjs +27 -0
  19. package/skills/wix-harmony-editor/scripts/copy/lint-api.mjs +56 -0
  20. package/skills/wix-harmony-editor/scripts/copy/measure-source.mjs +211 -0
  21. package/skills/wix-harmony-editor/scripts/copy/merge-mirrors.mjs +29 -0
  22. package/skills/wix-harmony-editor/scripts/copy/mirror-site.mjs +92 -0
  23. package/skills/wix-harmony-editor/scripts/copy/mobile-stage.mjs +56 -0
  24. package/skills/wix-harmony-editor/scripts/copy/preview-widths.mjs +73 -0
  25. package/skills/wix-harmony-editor/scripts/copy/render-plate.mjs +67 -0
  26. package/skills/wix-harmony-editor/scripts/copy/serve-mirror.mjs +102 -0
  27. package/skills/wix-harmony-editor/scripts/copy/snapshot-capabilities.mjs +40 -0
  28. package/skills/wix-harmony-editor/scripts/copy/split-sections.mjs +191 -0
  29. package/skills/wix-harmony-editor/scripts/copy/upload-media-manager.mjs +61 -0
  30. package/skills/wix-harmony-editor/scripts/launch.sh +359 -0
  31. package/skills/wix-headless/SKILL.md +7 -2
  32. package/skills/wix-headless/references/CAPABILITIES.md +6 -1
  33. package/skills/wix-headless/references/DISCOVERY.md +2 -1
  34. package/skills/wix-headless/references/SDK_HANDOFF.md +6 -1
  35. package/skills/wix-headless/references/SEED.md +3 -2
  36. package/skills/wix-headless/references/SETUP.md +1 -0
  37. package/skills/wix-headless/references/inline-recipes/experience-donations.md +102 -0
  38. package/skills/wix-headless/references/inline-recipes/how-to-code-donations.md +146 -0
  39. package/skills/wix-headless/references/inline-recipes/setup-donations.md +15 -0
  40. package/skills/wix-headless/references/managed/CREATE.md +1 -1
  41. package/skills/wix-headless-kit/SKILL.md +110 -21
  42. package/skills/wix-headless-kit/guides/api-run.md +15 -13
  43. package/skills/wix-headless-kit/guides/existing-site.md +31 -0
  44. package/skills/wix-headless-kit/guides/migration.md +49 -17
  45. package/skills/wix-headless-kit/install/agents-md.mjs +1 -1
  46. package/skills/wix-headless-kit/install/context.mjs +61 -6
  47. package/skills/wix-headless-kit/install/pins.json +1 -1
  48. package/skills/wix-headless-kit/install/setup.mjs +107 -12
  49. package/skills/wix-headless-replatform/.publish-manifest.json +8 -0
  50. package/skills/wix-headless-replatform/SKILL.md +116 -0
  51. package/skills/wix-headless-replatform/agents/openai.yaml +6 -0
  52. package/skills/wix-headless-replatform/references/control-and-visual-fidelity-contract.md +43 -0
  53. package/skills/wix-headless-replatform/references/extraction-schema.md +187 -0
  54. package/skills/wix-headless-replatform/references/interaction-runtime-contract.md +137 -0
  55. package/skills/wix-headless-replatform/references/layout-blueprint-contract.md +41 -0
  56. package/skills/wix-headless-replatform/references/output-contract.md +93 -0
  57. package/skills/wix-headless-replatform/references/post-build-gap-contract.md +125 -0
  58. package/skills/wix-headless-replatform/references/qa-checklist.md +83 -0
  59. package/skills/wix-headless-replatform/references/safety.md +19 -0
  60. package/skills/wix-headless-replatform/references/ui-normalization-contract.md +70 -0
  61. package/skills/wix-headless-replatform/references/workflow.md +157 -0
  62. package/skills/wix-headless-replatform/registry/README.md +20 -0
  63. package/skills/wix-headless-replatform/registry/approvals/button/shadcn-default-ac60ef5.json +28 -0
  64. package/skills/wix-headless-replatform/registry/items/button/shadcn-default-ac60ef5/button.tsx +54 -0
  65. package/skills/wix-headless-replatform/registry/items/button/shadcn-default-ac60ef5/capabilities.json +60 -0
  66. package/skills/wix-headless-replatform/registry/items/button/shadcn-default-ac60ef5/contract.md +48 -0
  67. package/skills/wix-headless-replatform/registry/licenses/shadcn-ui-ac60ef5-MIT.txt +21 -0
  68. package/skills/wix-headless-replatform/registry/registry.json +36 -0
  69. package/skills/wix-headless-replatform/resources/rp-facelift/SKILL.md +32 -0
  70. package/skills/wix-headless-replatform/resources/rp-project-context/SKILL.md +62 -0
  71. package/skills/wix-headless-replatform/resources/rp-qa-gap-loop/SKILL.md +64 -0
  72. package/skills/wix-headless-replatform/resources/rp-source-evidence/SKILL.md +42 -0
  73. package/skills/wix-headless-replatform/resources/rp-ui-implementation/SKILL.md +73 -0
  74. package/skills/wix-headless-replatform/schemas/build-plan.schema.json +10 -0
  75. package/skills/wix-headless-replatform/schemas/candidate.schema.json +19 -0
  76. package/skills/wix-headless-replatform/schemas/common.schema.json +33 -0
  77. package/skills/wix-headless-replatform/schemas/decision-patch.schema.json +10 -0
  78. package/skills/wix-headless-replatform/schemas/decision-request.schema.json +10 -0
  79. package/skills/wix-headless-replatform/schemas/extraction-gap.schema.json +28 -0
  80. package/skills/wix-headless-replatform/schemas/extraction-manifest.schema.json +34 -0
  81. package/skills/wix-headless-replatform/schemas/final-report.schema.json +10 -0
  82. package/skills/wix-headless-replatform/schemas/foundation.schema.json +11 -0
  83. package/skills/wix-headless-replatform/schemas/metadata.schema.json +11 -0
  84. package/skills/wix-headless-replatform/schemas/observation-packet.schema.json +17 -0
  85. package/skills/wix-headless-replatform/schemas/page-capture.schema.json +11 -0
  86. package/skills/wix-headless-replatform/schemas/page-resolution.schema.json +33 -0
  87. package/skills/wix-headless-replatform/schemas/shared-chrome.schema.json +11 -0
  88. package/skills/wix-headless-replatform/schemas/unit.schema.json +40 -0
  89. package/skills/wix-headless-replatform/scripts/assemble-extraction.mjs +844 -0
  90. package/skills/wix-headless-replatform/scripts/benchmark-extraction.mjs +163 -0
  91. package/skills/wix-headless-replatform/scripts/browser-extraction-preflight.mjs +42 -0
  92. package/skills/wix-headless-replatform/scripts/build-extracted-homepage.mjs +228 -0
  93. package/skills/wix-headless-replatform/scripts/clear-wix-starter.mjs +87 -0
  94. package/skills/wix-headless-replatform/scripts/create-wix-project.mjs +505 -0
  95. package/skills/wix-headless-replatform/scripts/discover-urls.mjs +142 -0
  96. package/skills/wix-headless-replatform/scripts/extract-assets.mjs +140 -0
  97. package/skills/wix-headless-replatform/scripts/extract-design-system.mjs +637 -0
  98. package/skills/wix-headless-replatform/scripts/extract-interactions.mjs +1903 -0
  99. package/skills/wix-headless-replatform/scripts/extract-page.mjs +2461 -0
  100. package/skills/wix-headless-replatform/scripts/extract-seo.mjs +25 -0
  101. package/skills/wix-headless-replatform/scripts/extract-tokens.mjs +63 -0
  102. package/skills/wix-headless-replatform/scripts/finalize-extraction-report.mjs +126 -0
  103. package/skills/wix-headless-replatform/scripts/finalize-gap-review.mjs +180 -0
  104. package/skills/wix-headless-replatform/scripts/finalize-gap-review.test.mjs +98 -0
  105. package/skills/wix-headless-replatform/scripts/finalize-migration-website.mjs +103 -0
  106. package/skills/wix-headless-replatform/scripts/generate-control-state-contract.mjs +176 -0
  107. package/skills/wix-headless-replatform/scripts/generate-design-md.mjs +261 -0
  108. package/skills/wix-headless-replatform/scripts/generate-extraction-validators.mjs +25 -0
  109. package/skills/wix-headless-replatform/scripts/generate-invoice-download-backend.mjs +342 -0
  110. package/skills/wix-headless-replatform/scripts/generate-layout-blueprint.mjs +140 -0
  111. package/skills/wix-headless-replatform/scripts/generate-repeater-cms.mjs +22 -0
  112. package/skills/wix-headless-replatform/scripts/generate-route-plan.mjs +143 -0
  113. package/skills/wix-headless-replatform/scripts/generate-scene-contract.mjs +288 -0
  114. package/skills/wix-headless-replatform/scripts/generate-ui-normalization.mjs +266 -0
  115. package/skills/wix-headless-replatform/scripts/generate-visual-assets.mjs +111 -0
  116. package/skills/wix-headless-replatform/scripts/lib/browser-tooling.mjs +570 -0
  117. package/skills/wix-headless-replatform/scripts/lib/common.mjs +329 -0
  118. package/skills/wix-headless-replatform/scripts/lib/component-capabilities.mjs +121 -0
  119. package/skills/wix-headless-replatform/scripts/lib/component-registry.mjs +282 -0
  120. package/skills/wix-headless-replatform/scripts/lib/content-boundary.mjs +61 -0
  121. package/skills/wix-headless-replatform/scripts/lib/extraction-contract.mjs +374 -0
  122. package/skills/wix-headless-replatform/scripts/lib/extraction-detectors.mjs +243 -0
  123. package/skills/wix-headless-replatform/scripts/lib/extraction-validators.generated.mjs +1139 -0
  124. package/skills/wix-headless-replatform/scripts/lib/font-contract.mjs +326 -0
  125. package/skills/wix-headless-replatform/scripts/lib/frontend-automation-state.mjs +184 -0
  126. package/skills/wix-headless-replatform/scripts/lib/gap-analysis.mjs +396 -0
  127. package/skills/wix-headless-replatform/scripts/lib/html-extract.mjs +168 -0
  128. package/skills/wix-headless-replatform/scripts/lib/interaction-bootstrap.mjs +10 -0
  129. package/skills/wix-headless-replatform/scripts/lib/interaction-runtime.mjs +194 -0
  130. package/skills/wix-headless-replatform/scripts/lib/interaction-timeline.mjs +348 -0
  131. package/skills/wix-headless-replatform/scripts/lib/layout-blueprint/classifiers.mjs +141 -0
  132. package/skills/wix-headless-replatform/scripts/lib/layout-blueprint/geometry.mjs +43 -0
  133. package/skills/wix-headless-replatform/scripts/lib/layout-blueprint/vocabulary.mjs +18 -0
  134. package/skills/wix-headless-replatform/scripts/lib/ui-normalization.css +64 -0
  135. package/skills/wix-headless-replatform/scripts/optimize-svg.mjs +31 -0
  136. package/skills/wix-headless-replatform/scripts/post-build-gap.mjs +358 -0
  137. package/skills/wix-headless-replatform/scripts/provision-repeater-cms.mjs +25 -0
  138. package/skills/wix-headless-replatform/scripts/record-gap-decision.mjs +39 -0
  139. package/skills/wix-headless-replatform/scripts/replay-extraction.mjs +107 -0
  140. package/skills/wix-headless-replatform/scripts/resolve-home-page.mjs +96 -0
  141. package/skills/wix-headless-replatform/scripts/site-clone.mjs +658 -0
  142. package/skills/wix-headless-replatform/scripts/validate-font-contract.mjs +29 -0
  143. package/skills/wix-headless-replatform/scripts/verify-interactions.mjs +669 -0
  144. package/skills/wix-headless-replatform/scripts/visual-qa.mjs +370 -0
  145. package/skills/wix-headless-templates/donations/INSTRUCTIONS.md +37 -24
  146. package/skills/wix-headless-templates/donations/app/components/donations/DonateForm.tsx +49 -23
  147. package/skills/wix-headless-templates/donations/app/components/donations/DonationReceipt.tsx +6 -5
  148. package/skills/wix-headless-templates/donations/app/components/donations/GoalProgress.tsx +5 -5
  149. package/skills/wix-headless-templates/donations/app/wix/donations/campaigns.ts +4 -4
  150. package/skills/wix-headless-templates/donations/app/wix/donations/donate.ts +7 -3
  151. package/skills/wix-headless-templates/donations/app/wix/donations/donation-store.ts +2 -2
  152. package/skills/wix-headless-templates/donations/app/wix/donations/donations-core.ts +12 -9
  153. package/skills/wix-headless-templates/donations/project/src/components/donations/DonateForm.tsx +49 -23
  154. package/skills/wix-headless-templates/donations/project/src/components/donations/DonationReceipt.tsx +6 -5
  155. package/skills/wix-headless-templates/donations/project/src/components/donations/GoalProgress.tsx +5 -5
  156. package/skills/wix-headless-templates/donations/project/src/wix/donations/campaigns.ts +4 -4
  157. package/skills/wix-headless-templates/donations/project/src/wix/donations/donate.ts +7 -3
  158. package/skills/wix-headless-templates/donations/project/src/wix/donations/donation-store.ts +2 -2
  159. package/skills/wix-headless-templates/donations/project/src/wix/donations/donations-core.ts +12 -9
  160. package/skills/wix-headless-templates/donations/rest/campaigns.ts +4 -4
  161. package/skills/wix-headless-templates/donations/rest/donate.ts +7 -3
  162. package/skills/wix-headless-templates/donations/seed/SEED.md +12 -7
  163. package/skills/wix-headless-templates/donations/tests/donation-contract.test.mjs +71 -0
  164. package/skills/wix-headless-templates/donations/tests/donation-form.test.cjs +137 -0
  165. package/skills/wix-headless-templates/restaurants/INSTRUCTIONS.md +28 -14
  166. package/skills/wix-headless-templates/restaurants/app/components/restaurants/OrderCartDrawer.tsx +87 -5
  167. package/skills/wix-headless-templates/restaurants/app/hooks/restaurants/useOrderCart.ts +9 -1
  168. package/skills/wix-headless-templates/restaurants/app/wix/restaurants/order-store.ts +33 -4
  169. package/skills/wix-headless-templates/restaurants/app/wix/restaurants/ordering-core.ts +100 -5
  170. package/skills/wix-headless-templates/restaurants/app/wix/restaurants/ordering.ts +101 -15
  171. package/skills/wix-headless-templates/restaurants/app/wix/restaurants/types.ts +35 -1
  172. package/skills/wix-headless-templates/restaurants/project/src/components/restaurants/OrderCartDrawer.tsx +87 -5
  173. package/skills/wix-headless-templates/restaurants/project/src/hooks/restaurants/useOrderCart.ts +9 -1
  174. package/skills/wix-headless-templates/restaurants/project/src/wix/restaurants/order-store.ts +33 -4
  175. package/skills/wix-headless-templates/restaurants/project/src/wix/restaurants/ordering-core.ts +100 -5
  176. package/skills/wix-headless-templates/restaurants/project/src/wix/restaurants/ordering.ts +101 -15
  177. package/skills/wix-headless-templates/restaurants/project/src/wix/restaurants/types.ts +35 -1
  178. package/skills/wix-headless-templates/restaurants/rest/ordering.ts +91 -14
  179. package/skills/wix-import/SKILL.md +90 -0
  180. package/skills/wix-manage/SKILL.md +13 -3
  181. package/skills/wix-manage/references/dashboard-navigation/dashboard-navigation.md +2 -1
  182. package/skills/wix-manage/references/dashboard-navigation/routes.json +249 -0
  183. package/skills/wix-manage/references/donations/create-and-update-donation-campaigns.md +139 -0
  184. package/skills/wix-manage/references/events/events-dashboard-navigation.md +81 -0
  185. package/skills/wix-manage/references/sites/manage-oauth-apps.md +1 -0
  186. package/skills/wix-manage/references/sites/upload-static-site.md +127 -8
  187. package/skills/wix-replatform/.publish-manifest.json +5 -5
  188. package/skills/wix-replatform/CLI.md +162 -0
  189. package/skills/wix-replatform/README.md +52 -0
  190. package/skills/wix-replatform/SKILL.md +229 -684
  191. package/skills/wix-replatform/console/account.css +1 -0
  192. package/skills/wix-replatform/console/app.css +1 -0
  193. package/skills/wix-replatform/console/app.js +117 -0
  194. package/skills/wix-replatform/console/index.html +4 -0
  195. package/skills/wix-replatform/console/json.css +11 -0
  196. package/skills/wix-replatform/lib/agent-adapters/index.js +71 -0
  197. package/skills/wix-replatform/lib/app-page-routing.js +75 -0
  198. package/skills/wix-replatform/lib/artifact-freshness.js +11 -1
  199. package/skills/wix-replatform/lib/blocked-data-requests.js +427 -0
  200. package/skills/wix-replatform/lib/census-reconciliation.js +426 -0
  201. package/skills/wix-replatform/lib/completion-report.js +1393 -13
  202. package/skills/wix-replatform/lib/config-env.js +85 -11
  203. package/skills/wix-replatform/lib/confirmed-pictures.js +212 -0
  204. package/skills/wix-replatform/lib/dependency-readiness.js +423 -0
  205. package/skills/wix-replatform/lib/dependency-recovery.js +21 -0
  206. package/skills/wix-replatform/lib/destination-choice.js +163 -0
  207. package/skills/wix-replatform/lib/destination-handoff.js +62 -0
  208. package/skills/wix-replatform/lib/destination-http.js +81 -0
  209. package/skills/wix-replatform/lib/destination-route.js +98 -0
  210. package/skills/wix-replatform/lib/destination.js +919 -0
  211. package/skills/wix-replatform/lib/discovered-census.js +231 -0
  212. package/skills/wix-replatform/lib/discovered-set-status.js +255 -0
  213. package/skills/wix-replatform/lib/document-url-guard.js +203 -0
  214. package/skills/wix-replatform/lib/entity-qa-attestation.js +339 -0
  215. package/skills/wix-replatform/lib/entity-verification.js +18 -0
  216. package/skills/wix-replatform/lib/execution-capability.js +120 -0
  217. package/skills/wix-replatform/lib/execution-log.js +170 -0
  218. package/skills/wix-replatform/lib/execution-manifest.js +20 -2
  219. package/skills/wix-replatform/lib/execution-state.js +22 -0
  220. package/skills/wix-replatform/lib/expectations-ledger.js +96 -0
  221. package/skills/wix-replatform/lib/generated-plugin-handoff.js +140 -0
  222. package/skills/wix-replatform/lib/import-readiness-contract.js +23 -0
  223. package/skills/wix-replatform/lib/import-recovery.js +800 -6
  224. package/skills/wix-replatform/lib/imported-redirect-targets.js +608 -0
  225. package/skills/wix-replatform/lib/internal-link-reconciliation.js +166 -0
  226. package/skills/wix-replatform/lib/link-audit.js +173 -0
  227. package/skills/wix-replatform/lib/link-census.js +194 -0
  228. package/skills/wix-replatform/lib/link-plan.js +148 -0
  229. package/skills/wix-replatform/lib/link-verification.js +274 -0
  230. package/skills/wix-replatform/lib/link-write-journal.js +42 -0
  231. package/skills/wix-replatform/lib/local-state.js +869 -30
  232. package/skills/wix-replatform/lib/member-completion.js +658 -0
  233. package/skills/wix-replatform/lib/member-crosswalk.js +69 -0
  234. package/skills/wix-replatform/lib/member-outcome-registry.js +265 -0
  235. package/skills/wix-replatform/lib/migration-completion.js +311 -0
  236. package/skills/wix-replatform/lib/operator-identity.js +47 -0
  237. package/skills/wix-replatform/lib/orchestration-decisions.js +248 -0
  238. package/skills/wix-replatform/lib/orchestration-preflight.js +401 -19
  239. package/skills/wix-replatform/lib/orchestration-router.js +608 -32
  240. package/skills/wix-replatform/lib/orchestration-state.js +188 -12
  241. package/skills/wix-replatform/lib/order-reference-readiness.js +30 -0
  242. package/skills/wix-replatform/lib/payments-outcome-registry.js +200 -0
  243. package/skills/wix-replatform/lib/plugin-cms-fallback.js +618 -0
  244. package/skills/wix-replatform/lib/preservation-approval-stamp.js +54 -0
  245. package/skills/wix-replatform/lib/product-media-deferral.js +96 -0
  246. package/skills/wix-replatform/lib/progress-log.js +19 -3
  247. package/skills/wix-replatform/lib/read-back-approval.js +184 -0
  248. package/skills/wix-replatform/lib/read-back-comparison.js +136 -0
  249. package/skills/wix-replatform/lib/read-back-contract.js +243 -0
  250. package/skills/wix-replatform/lib/read-back-extract.js +118 -0
  251. package/skills/wix-replatform/lib/read-back-gate.js +734 -0
  252. package/skills/wix-replatform/lib/read-back-reads.js +94 -0
  253. package/skills/wix-replatform/lib/read-back-state.js +107 -0
  254. package/skills/wix-replatform/lib/read-back-summary.js +81 -0
  255. package/skills/wix-replatform/lib/rerun-conflicts.js +334 -0
  256. package/skills/wix-replatform/lib/run-controller.js +401 -0
  257. package/skills/wix-replatform/lib/seo-outcome-registry.js +45 -0
  258. package/skills/wix-replatform/lib/setup-verification.js +148 -0
  259. package/skills/wix-replatform/lib/source-access.js +231 -0
  260. package/skills/wix-replatform/lib/source-coverage.js +1130 -0
  261. package/skills/wix-replatform/lib/source-secrets.js +277 -0
  262. package/skills/wix-replatform/lib/structured-link-patch.js +59 -0
  263. package/skills/wix-replatform/lib/task-state.js +110 -0
  264. package/skills/wix-replatform/lib/url-preservation-report.js +319 -0
  265. package/skills/wix-replatform/lib/url-preservation-state.js +349 -1
  266. package/skills/wix-replatform/lib/url-redirect-plan.js +728 -0
  267. package/skills/wix-replatform/lib/url-verification.js +315 -0
  268. package/skills/wix-replatform/lib/user-action-effects.js +42 -0
  269. package/skills/wix-replatform/lib/user-actions.js +264 -0
  270. package/skills/wix-replatform/lib/website-handoff.js +1220 -0
  271. package/skills/wix-replatform/lib/wix-client-callers.js +54 -0
  272. package/skills/wix-replatform/lib/wix-dashboard-url.js +35 -0
  273. package/skills/wix-replatform/lib/write-verification-state.js +92 -0
  274. package/skills/wix-replatform/lib/write-verification.js +274 -0
  275. package/skills/wix-replatform/resources/rp-destination/SKILL.md +137 -0
  276. package/skills/wix-replatform/resources/rp-discovery/SKILL.md +189 -16
  277. package/skills/wix-replatform/resources/rp-discovery/scripts/promote-source-coverage.js +47 -0
  278. package/skills/wix-replatform/resources/rp-execute-import/SKILL.md +869 -29
  279. package/skills/wix-replatform/resources/rp-execute-import/scripts/shipping-estimate-audit.js +70 -0
  280. package/skills/wix-replatform/resources/rp-execute-setup/SKILL.md +195 -29
  281. package/skills/wix-replatform/resources/rp-execute-setup/scripts/execute-setup.js +442 -0
  282. package/skills/wix-replatform/resources/rp-execution-policy/SKILL.md +112 -0
  283. package/skills/wix-replatform/resources/rp-execution-policy/lib/coupon-currency-plan-report.js +143 -0
  284. package/skills/wix-replatform/resources/rp-execution-policy/lib/payments-report.js +244 -0
  285. package/skills/wix-replatform/resources/rp-import-codegen/SKILL.md +2082 -38
  286. package/skills/wix-replatform/resources/rp-mapper/SKILL.md +528 -11
  287. package/skills/wix-replatform/resources/rp-mapper/lib/structure-bridge-planning.js +303 -0
  288. package/skills/wix-replatform/resources/rp-mapper/scripts/coverage-reconcile.js +88 -0
  289. package/skills/wix-replatform/resources/rp-mapper/wix-business-solutions-taxonomy.md +6 -5
  290. package/skills/wix-replatform/resources/rp-preflight/SKILL.md +40 -0
  291. package/skills/wix-replatform/resources/rp-project-intake/SKILL.md +55 -0
  292. package/skills/wix-replatform/resources/rp-quick-runtime/SKILL.md +60 -0
  293. package/skills/wix-replatform/resources/rp-quick-runtime/lib/import-progress.js +89 -0
  294. package/skills/wix-replatform/resources/rp-quick-runtime/lib/limit-recovery.js +36 -0
  295. package/skills/wix-replatform/resources/rp-quick-shopify/SKILL.md +123 -0
  296. package/skills/wix-replatform/resources/rp-quick-shopify/quick-mode.json +124 -0
  297. package/skills/wix-replatform/resources/rp-quick-shopify/scripts/quick-mode.js +522 -0
  298. package/skills/wix-replatform/resources/rp-quick-woocommerce/SKILL.md +56 -0
  299. package/skills/wix-replatform/resources/rp-quick-woocommerce/quick-mode.json +91 -0
  300. package/skills/wix-replatform/resources/rp-quick-woocommerce/scripts/quick-mode.js +255 -0
  301. package/skills/wix-replatform/resources/rp-setup-discovery/SKILL.md +80 -10
  302. package/skills/wix-replatform/resources/rp-setup-discovery/scripts/quick-setup-plan.js +44 -0
  303. package/skills/wix-replatform/resources/rp-source-csv/SKILL.md +3 -0
  304. package/skills/wix-replatform/resources/rp-source-csv/lib/csv-fileset.js +0 -0
  305. package/skills/wix-replatform/resources/rp-source-csv/scripts/csv-discovery.js +21 -1
  306. package/skills/wix-replatform/resources/rp-source-inputs/SKILL.md +66 -0
  307. package/skills/wix-replatform/resources/rp-source-sfcc/SKILL.md +153 -0
  308. package/skills/wix-replatform/resources/rp-source-shopify/SKILL.md +394 -0
  309. package/skills/wix-replatform/resources/rp-source-shopify/lib/discovery-reads.js +200 -0
  310. package/skills/wix-replatform/resources/rp-source-shopify/lib/import-findings.js +34 -0
  311. package/skills/wix-replatform/resources/rp-source-shopify/lib/shopify-bulk-sqlite-worker.js +44 -0
  312. package/skills/wix-replatform/resources/rp-source-shopify/lib/shopify-bulk.js +1470 -0
  313. package/skills/wix-replatform/resources/rp-source-shopify/lib/shopify-cli.js +446 -0
  314. package/skills/wix-replatform/resources/rp-source-shopify/lib/shopify-gift-cards.js +474 -0
  315. package/skills/wix-replatform/resources/rp-source-shopify/lib/shopify-protected-fields.js +879 -0
  316. package/skills/wix-replatform/resources/rp-source-shopify/lib/shopify-session.js +426 -0
  317. package/skills/wix-replatform/resources/rp-source-shopify/queries/articles.graphql +24 -0
  318. package/skills/wix-replatform/resources/rp-source-shopify/queries/blogs.graphql +18 -0
  319. package/skills/wix-replatform/resources/rp-source-shopify/queries/collections.graphql +40 -0
  320. package/skills/wix-replatform/resources/rp-source-shopify/queries/customers.graphql +76 -0
  321. package/skills/wix-replatform/resources/rp-source-shopify/queries/delivery-profiles.graphql +51 -0
  322. package/skills/wix-replatform/resources/rp-source-shopify/queries/discounts.graphql +35 -0
  323. package/skills/wix-replatform/resources/rp-source-shopify/queries/files.graphql +20 -0
  324. package/skills/wix-replatform/resources/rp-source-shopify/queries/gift-cards.graphql +18 -0
  325. package/skills/wix-replatform/resources/rp-source-shopify/queries/inventory.graphql +31 -0
  326. package/skills/wix-replatform/resources/rp-source-shopify/queries/locations.graphql +21 -0
  327. package/skills/wix-replatform/resources/rp-source-shopify/queries/menus.graphql +21 -0
  328. package/skills/wix-replatform/resources/rp-source-shopify/queries/metaobjects.graphql +30 -0
  329. package/skills/wix-replatform/resources/rp-source-shopify/queries/orders-core.graphql +150 -0
  330. package/skills/wix-replatform/resources/rp-source-shopify/queries/orders-fulfillments.graphql +36 -0
  331. package/skills/wix-replatform/resources/rp-source-shopify/queries/orders-refunds.graphql +48 -0
  332. package/skills/wix-replatform/resources/rp-source-shopify/queries/pages.graphql +20 -0
  333. package/skills/wix-replatform/resources/rp-source-shopify/queries/probe-customers-address.graphql +8 -0
  334. package/skills/wix-replatform/resources/rp-source-shopify/queries/probe-customers-email.graphql +6 -0
  335. package/skills/wix-replatform/resources/rp-source-shopify/queries/probe-customers-name.graphql +8 -0
  336. package/skills/wix-replatform/resources/rp-source-shopify/queries/probe-customers-phone.graphql +8 -0
  337. package/skills/wix-replatform/resources/rp-source-shopify/queries/probe-orders-address.graphql +12 -0
  338. package/skills/wix-replatform/resources/rp-source-shopify/queries/probe-orders-email.graphql +6 -0
  339. package/skills/wix-replatform/resources/rp-source-shopify/queries/probe-orders-name.graphql +13 -0
  340. package/skills/wix-replatform/resources/rp-source-shopify/queries/probe-orders-phone.graphql +13 -0
  341. package/skills/wix-replatform/resources/rp-source-shopify/queries/products.graphql +73 -0
  342. package/skills/wix-replatform/resources/rp-source-shopify/queries/url-redirects.graphql +13 -0
  343. package/skills/wix-replatform/resources/rp-source-shopify/scripts/shopify-discovery.js +693 -0
  344. package/skills/wix-replatform/resources/rp-source-shopify/scripts/shopify-extract.js +283 -0
  345. package/skills/wix-replatform/resources/rp-source-shopify/scripts/shopify-gift-card-remedy.js +191 -0
  346. package/skills/wix-replatform/resources/rp-source-shopify/scripts/shopify-session-check.js +115 -0
  347. package/skills/wix-replatform/resources/rp-source-shopify/source-schema.example.json +201 -0
  348. package/skills/wix-replatform/resources/rp-source-wordpress/PLUGIN-READ-PLANS.md +146 -0
  349. package/skills/wix-replatform/resources/rp-source-wordpress/SKILL.md +736 -22
  350. package/skills/wix-replatform/resources/rp-source-wordpress/lib/blocked-data-handlers.js +73 -0
  351. package/skills/wix-replatform/resources/rp-source-wordpress/lib/checkout-field-csv-parser.js +115 -0
  352. package/skills/wix-replatform/resources/rp-source-wordpress/lib/checkout-field-csv-parser.test-fixture.js +91 -0
  353. package/skills/wix-replatform/resources/rp-source-wordpress/lib/coupon-discovery.js +440 -0
  354. package/skills/wix-replatform/resources/rp-source-wordpress/lib/currency-gate.js +125 -0
  355. package/skills/wix-replatform/resources/rp-source-wordpress/lib/gateway-source-keys.js +252 -0
  356. package/skills/wix-replatform/resources/rp-source-wordpress/lib/gateway-source-keys.json +183 -0
  357. package/skills/wix-replatform/resources/rp-source-wordpress/lib/gateway-summary.mjs +333 -0
  358. package/skills/wix-replatform/resources/rp-source-wordpress/lib/invoice-discovery.js +426 -0
  359. package/skills/wix-replatform/resources/rp-source-wordpress/lib/plugin-disposition.js +400 -0
  360. package/skills/wix-replatform/resources/rp-source-wordpress/lib/plugin-entity-read-plan.js +633 -0
  361. package/skills/wix-replatform/resources/rp-source-wordpress/lib/plugin-knowledge.js +1127 -0
  362. package/skills/wix-replatform/resources/rp-source-wordpress/lib/refund-corroboration.js +194 -0
  363. package/skills/wix-replatform/resources/rp-source-wordpress/lib/refund-corroboration.json +100 -0
  364. package/skills/wix-replatform/resources/rp-source-wordpress/lib/sampled-ids-batch.js +157 -0
  365. package/skills/wix-replatform/resources/rp-source-wordpress/lib/secret-value-guard.js +234 -0
  366. package/skills/wix-replatform/resources/rp-source-wordpress/lib/store-currency.js +101 -0
  367. package/skills/wix-replatform/resources/rp-source-wordpress/lib/structure-bridge-reader.js +755 -0
  368. package/skills/wix-replatform/resources/rp-source-wordpress/lib/wix-wp-plugin-v2-client.js +1074 -0
  369. package/skills/wix-replatform/resources/rp-source-wordpress/lib/wix-wp-plugin-v2-client.test-fixture.js +149 -0
  370. package/skills/wix-replatform/resources/rp-source-wordpress/lib/woo-inventory.js +25 -0
  371. package/skills/wix-replatform/resources/rp-source-wordpress/lib/wp-http.js +204 -9
  372. package/skills/wix-replatform/resources/rp-source-wordpress/lib/wp-image-url.js +186 -0
  373. package/skills/wix-replatform/resources/rp-source-wordpress/lib/wp-plugin-detect.js +1422 -0
  374. package/skills/wix-replatform/resources/rp-source-wordpress/lib/wp-redirect-sources.js +343 -0
  375. package/skills/wix-replatform/resources/rp-source-wordpress/lib/wp-route-classifier.js +262 -26
  376. package/skills/wix-replatform/resources/rp-source-wordpress/lib/yoast-product-seo-evidence.js +272 -0
  377. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/README.md +373 -0
  378. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/advanced-custom-fields.json +101 -0
  379. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/back-in-stock-notifier-for-woocommerce.json +81 -0
  380. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/capabilities-pending-decision.json +128 -0
  381. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/cms-fallback-eligible.json +18 -0
  382. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/contact-form-7.json +104 -0
  383. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/facebook-for-woocommerce.json +44 -0
  384. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/fingerprint-aliases.json +49 -0
  385. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/free-gifts-for-woocommerce.json +94 -0
  386. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/index.json +863 -0
  387. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/mailpoet.json +52 -0
  388. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/membership-for-woocommerce.json +161 -0
  389. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/mwb-bookings-for-woocommerce.json +180 -0
  390. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/no-migration-needed.json +286 -0
  391. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/pricing-deals-for-woocommerce.json +79 -0
  392. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/product-extras-for-woocommerce.json +120 -0
  393. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/pw-woocommerce-gift-cards.json +128 -0
  394. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/requires-development.json +88 -0
  395. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/seo-by-rank-math.json +80 -0
  396. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/seriously-simple-podcasting.json +46 -0
  397. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/strong-testimonials.json +55 -0
  398. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/subscriptions-for-woocommerce.json +99 -0
  399. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/tablepress.json +55 -0
  400. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/the-events-calendar.json +160 -0
  401. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/ti-woocommerce-wishlist.json +81 -0
  402. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/woo-checkout-field-editor-pro.json +60 -0
  403. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/woo-discount-rules.json +74 -0
  404. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/woo-product-bundle.json +75 -0
  405. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/woocommerce-gift-cards.json +60 -0
  406. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/woocommerce-other-payment-gateway.json +44 -0
  407. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/woocommerce-pdf-invoices-packing-slips.json +57 -0
  408. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/woocommerce-product-addon.json +141 -0
  409. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/woocommerce-progressive-discounts.json +54 -0
  410. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/wordpress-seo.json +158 -0
  411. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/wpc-composite-products.json +97 -0
  412. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/wpforms-lite.json +86 -0
  413. package/skills/wix-replatform/resources/rp-source-wordpress/scripts/capture-store-settings.js +90 -0
  414. package/skills/wix-replatform/resources/rp-source-wordpress/scripts/plugin-knowledge-validate.js +51 -0
  415. package/skills/wix-replatform/resources/rp-source-wordpress/scripts/plugin-knowledge.js +103 -0
  416. package/skills/wix-replatform/resources/rp-source-wordpress/scripts/wp-discovery.js +1668 -33
  417. package/skills/wix-replatform/resources/rp-source-wordpress/scripts/wp-plugin-inventory.js +273 -0
  418. package/skills/wix-replatform/resources/rp-source-wordpress/secret-value-patterns.v1.json +11 -0
  419. package/skills/wix-replatform/resources/rp-source-wordpress/sub-parts.json +13 -0
  420. package/skills/wix-replatform/resources/rp-target-wix/SKILL.md +446 -32
  421. package/skills/wix-replatform/resources/rp-target-wix/app-page-routing-capabilities.json +36 -0
  422. package/skills/wix-replatform/resources/rp-target-wix/domains/README.md +38 -2
  423. package/skills/wix-replatform/resources/rp-target-wix/domains/SERVICE-PLUGINS.md +322 -0
  424. package/skills/wix-replatform/resources/rp-target-wix/domains/blog/docs-survey.json +70 -0
  425. package/skills/wix-replatform/resources/rp-target-wix/domains/blog/domain.json +19 -9
  426. package/skills/wix-replatform/resources/rp-target-wix/domains/blog/entities/category.json +42 -8
  427. package/skills/wix-replatform/resources/rp-target-wix/domains/blog/entities/comment.json +54 -8
  428. package/skills/wix-replatform/resources/rp-target-wix/domains/blog/entities/post.json +66 -10
  429. package/skills/wix-replatform/resources/rp-target-wix/domains/blog/entities/tag.json +38 -7
  430. package/skills/wix-replatform/resources/rp-target-wix/domains/bookings/docs-survey.json +332 -0
  431. package/skills/wix-replatform/resources/rp-target-wix/domains/bookings/domain.json +75 -0
  432. package/skills/wix-replatform/resources/rp-target-wix/domains/bookings/entities/booking.json +181 -0
  433. package/skills/wix-replatform/resources/rp-target-wix/domains/bookings/entities/service-add-on.json +130 -0
  434. package/skills/wix-replatform/resources/rp-target-wix/domains/bookings/entities/service.json +180 -0
  435. package/skills/wix-replatform/resources/rp-target-wix/domains/cms/docs-survey.json +161 -0
  436. package/skills/wix-replatform/resources/rp-target-wix/domains/cms/domain.json +15 -4
  437. package/skills/wix-replatform/resources/rp-target-wix/domains/cms/entities/collection.json +39 -7
  438. package/skills/wix-replatform/resources/rp-target-wix/domains/cms/entities/data-item.json +47 -8
  439. package/skills/wix-replatform/resources/rp-target-wix/domains/cms/entities/reference.json +7 -1
  440. package/skills/wix-replatform/resources/rp-target-wix/domains/crm/docs-survey.json +204 -0
  441. package/skills/wix-replatform/resources/rp-target-wix/domains/crm/domain.json +17 -4
  442. package/skills/wix-replatform/resources/rp-target-wix/domains/crm/entities/contact.json +159 -15
  443. package/skills/wix-replatform/resources/rp-target-wix/domains/crm/entities/email-subscription.json +80 -12
  444. package/skills/wix-replatform/resources/rp-target-wix/domains/crm/entities/label.json +48 -8
  445. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/docs-survey.json +306 -0
  446. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/domain.json +30 -7
  447. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/delivery-profile.json +171 -0
  448. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/discount-rule.json +182 -0
  449. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order-applied-discount.json +129 -0
  450. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order-invoice-document.json +192 -0
  451. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order-line-item-options.json +123 -0
  452. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order-line-item.json +60 -12
  453. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order-merchant-note.json +112 -0
  454. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order-payment.json +191 -0
  455. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order-refund.json +140 -13
  456. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order.json +383 -18
  457. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/pickup-location.json +122 -0
  458. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/shipping-option.json +98 -0
  459. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/wishlist-item.json +86 -0
  460. package/skills/wix-replatform/resources/rp-target-wix/domains/events/docs-survey.json +128 -0
  461. package/skills/wix-replatform/resources/rp-target-wix/domains/events/domain.json +38 -0
  462. package/skills/wix-replatform/resources/rp-target-wix/domains/events/entities/category.json +73 -0
  463. package/skills/wix-replatform/resources/rp-target-wix/domains/events/entities/event.json +107 -0
  464. package/skills/wix-replatform/resources/rp-target-wix/domains/events/entities/registration-form.json +89 -0
  465. package/skills/wix-replatform/resources/rp-target-wix/domains/events/entities/rsvp.json +118 -0
  466. package/skills/wix-replatform/resources/rp-target-wix/domains/events/entities/ticket-definition.json +93 -0
  467. package/skills/wix-replatform/resources/rp-target-wix/domains/forms/docs-survey.json +86 -0
  468. package/skills/wix-replatform/resources/rp-target-wix/domains/forms/domain.json +56 -0
  469. package/skills/wix-replatform/resources/rp-target-wix/domains/forms/entities/form-submission.json +121 -0
  470. package/skills/wix-replatform/resources/rp-target-wix/domains/forms/entities/form.json +134 -0
  471. package/skills/wix-replatform/resources/rp-target-wix/domains/gift-cards/docs-survey.json +41 -0
  472. package/skills/wix-replatform/resources/rp-target-wix/domains/gift-cards/domain.json +50 -0
  473. package/skills/wix-replatform/resources/rp-target-wix/domains/gift-cards/entities/gift-card-product.json +87 -0
  474. package/skills/wix-replatform/resources/rp-target-wix/domains/gift-cards/entities/gift-card.json +130 -0
  475. package/skills/wix-replatform/resources/rp-target-wix/domains/index.json +914 -24
  476. package/skills/wix-replatform/resources/rp-target-wix/domains/media/docs-survey.json +41 -0
  477. package/skills/wix-replatform/resources/rp-target-wix/domains/media/domain.json +14 -4
  478. package/skills/wix-replatform/resources/rp-target-wix/domains/media/entities/media-file.json +45 -8
  479. package/skills/wix-replatform/resources/rp-target-wix/domains/media/entities/media-folder.json +41 -7
  480. package/skills/wix-replatform/resources/rp-target-wix/domains/members/docs-survey.json +119 -0
  481. package/skills/wix-replatform/resources/rp-target-wix/domains/members/domain.json +13 -3
  482. package/skills/wix-replatform/resources/rp-target-wix/domains/members/entities/badge.json +41 -7
  483. package/skills/wix-replatform/resources/rp-target-wix/domains/members/entities/custom-field.json +82 -0
  484. package/skills/wix-replatform/resources/rp-target-wix/domains/members/entities/member-about.json +77 -0
  485. package/skills/wix-replatform/resources/rp-target-wix/domains/members/entities/member.json +165 -13
  486. package/skills/wix-replatform/resources/rp-target-wix/domains/pricing-plans/docs-survey.json +41 -0
  487. package/skills/wix-replatform/resources/rp-target-wix/domains/pricing-plans/domain.json +46 -0
  488. package/skills/wix-replatform/resources/rp-target-wix/domains/pricing-plans/entities/plan-order.json +137 -0
  489. package/skills/wix-replatform/resources/rp-target-wix/domains/pricing-plans/entities/plan.json +133 -0
  490. package/skills/wix-replatform/resources/rp-target-wix/domains/sales-channels/docs-survey.json +7 -0
  491. package/skills/wix-replatform/resources/rp-target-wix/domains/sales-channels/domain.json +36 -0
  492. package/skills/wix-replatform/resources/rp-target-wix/domains/sales-channels/entities/amazon-shop-connect.json +71 -0
  493. package/skills/wix-replatform/resources/rp-target-wix/domains/sales-channels/entities/ebay-shop-connect.json +67 -0
  494. package/skills/wix-replatform/resources/rp-target-wix/domains/sales-channels/entities/google-youtube-connect.json +72 -0
  495. package/skills/wix-replatform/resources/rp-target-wix/domains/sales-channels/entities/meta-catalog-connect.json +74 -0
  496. package/skills/wix-replatform/resources/rp-target-wix/domains/sales-channels/entities/pinterest-catalog-connect.json +69 -0
  497. package/skills/wix-replatform/resources/rp-target-wix/domains/sales-channels/entities/tiktok-catalog-connect.json +61 -0
  498. package/skills/wix-replatform/resources/rp-target-wix/domains/schema.json +28 -1
  499. package/skills/wix-replatform/resources/rp-target-wix/domains/seo/docs-survey.json +109 -0
  500. package/skills/wix-replatform/resources/rp-target-wix/domains/seo/domain.json +73 -0
  501. package/skills/wix-replatform/resources/rp-target-wix/domains/seo/entities/item-seo-tags.json +148 -0
  502. package/skills/wix-replatform/resources/rp-target-wix/domains/seo/entities/seo-pattern.json +91 -0
  503. package/skills/wix-replatform/resources/rp-target-wix/domains/seo/entities/site-seo-tags.json +79 -0
  504. package/skills/wix-replatform/resources/rp-target-wix/domains/site/docs-survey.json +32 -0
  505. package/skills/wix-replatform/resources/rp-target-wix/domains/site/domain.json +49 -0
  506. package/skills/wix-replatform/resources/rp-target-wix/domains/site/entities/business-contact.json +103 -0
  507. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/docs-survey.json +203 -0
  508. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/domain.json +27 -10
  509. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/back-in-stock-request.json +119 -0
  510. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/brand.json +111 -0
  511. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/category.json +52 -8
  512. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/coupon.json +214 -10
  513. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/inventory-item.json +93 -13
  514. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/product-customization.json +111 -0
  515. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/product-tag.json +52 -10
  516. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/product.json +145 -14
  517. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/promotion.json +84 -0
  518. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/review.json +178 -0
  519. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/subscription-product.json +87 -0
  520. package/skills/wix-replatform/resources/rp-target-wix/domains/tax/docs-survey.json +106 -0
  521. package/skills/wix-replatform/resources/rp-target-wix/domains/tax/domain.json +64 -0
  522. package/skills/wix-replatform/resources/rp-target-wix/domains/tax/entities/manual-tax-mapping.json +119 -0
  523. package/skills/wix-replatform/resources/rp-target-wix/domains/tax/entities/tax-group.json +94 -0
  524. package/skills/wix-replatform/resources/rp-target-wix/domains/tax/entities/tax-region.json +113 -0
  525. package/skills/wix-replatform/resources/rp-target-wix/domains/tax/entities/tax-settings.json +65 -0
  526. package/skills/wix-replatform/resources/rp-target-wix/lib/blog-author-attribution.js +165 -0
  527. package/skills/wix-replatform/resources/rp-target-wix/lib/blog-post-build-client.js +60 -0
  528. package/skills/wix-replatform/resources/rp-target-wix/lib/blog-post-build-duplicates.js +201 -0
  529. package/skills/wix-replatform/resources/rp-target-wix/lib/blog-post-build-ledger.js +306 -0
  530. package/skills/wix-replatform/resources/rp-target-wix/lib/blog-post-build-report.js +229 -0
  531. package/skills/wix-replatform/resources/rp-target-wix/lib/blog-post-build-stage.js +55 -0
  532. package/skills/wix-replatform/resources/rp-target-wix/lib/blog-post-build.js +715 -0
  533. package/skills/wix-replatform/resources/rp-target-wix/lib/blog-post-media.js +567 -0
  534. package/skills/wix-replatform/resources/rp-target-wix/lib/bulk-results.js +73 -0
  535. package/skills/wix-replatform/resources/rp-target-wix/lib/contact-extended-fields.js +194 -0
  536. package/skills/wix-replatform/resources/rp-target-wix/lib/contact-import.js +133 -0
  537. package/skills/wix-replatform/resources/rp-target-wix/lib/contract-ledger.js +13 -4
  538. package/skills/wix-replatform/resources/rp-target-wix/lib/coupon-redemption-drift.js +491 -0
  539. package/skills/wix-replatform/resources/rp-target-wix/lib/customer-member.js +104 -0
  540. package/skills/wix-replatform/resources/rp-target-wix/lib/data-extension-schema.js +673 -0
  541. package/skills/wix-replatform/resources/rp-target-wix/lib/domain-knowledge.js +453 -2
  542. package/skills/wix-replatform/resources/rp-target-wix/lib/gift-card-balance-reconciliation.js +119 -0
  543. package/skills/wix-replatform/resources/rp-target-wix/lib/gift-card-build.js +566 -0
  544. package/skills/wix-replatform/resources/rp-target-wix/lib/gift-card-redemption-build.js +249 -0
  545. package/skills/wix-replatform/resources/rp-target-wix/lib/order-applied-discount-build.js +63 -0
  546. package/skills/wix-replatform/resources/rp-target-wix/lib/order-buyer.js +187 -0
  547. package/skills/wix-replatform/resources/rp-target-wix/lib/order-channel-build.js +64 -0
  548. package/skills/wix-replatform/resources/rp-target-wix/lib/order-history.js +1027 -0
  549. package/skills/wix-replatform/resources/rp-target-wix/lib/order-invoice-contract.js +90 -0
  550. package/skills/wix-replatform/resources/rp-target-wix/lib/order-payment-mapping.js +420 -0
  551. package/skills/wix-replatform/resources/rp-target-wix/lib/pricing-plan-definition.js +177 -0
  552. package/skills/wix-replatform/resources/rp-target-wix/lib/product-import.js +151 -0
  553. package/skills/wix-replatform/resources/rp-target-wix/lib/product-seo.js +723 -0
  554. package/skills/wix-replatform/resources/rp-target-wix/lib/seo-redirects.js +353 -0
  555. package/skills/wix-replatform/resources/rp-target-wix/lib/shipping-build.js +1437 -0
  556. package/skills/wix-replatform/resources/rp-target-wix/lib/shipping-option-stage.js +354 -0
  557. package/skills/wix-replatform/resources/rp-target-wix/lib/store-config-build.js +134 -0
  558. package/skills/wix-replatform/resources/rp-target-wix/lib/stores-category-attach.js +221 -0
  559. package/skills/wix-replatform/resources/rp-target-wix/lib/stores-inventory.js +248 -0
  560. package/skills/wix-replatform/resources/rp-target-wix/lib/stores-verification.js +86 -3
  561. package/skills/wix-replatform/resources/rp-target-wix/lib/tax-build.js +231 -0
  562. package/skills/wix-replatform/resources/rp-target-wix/lib/url-mapper-transport.js +28 -0
  563. package/skills/wix-replatform/resources/rp-target-wix/lib/value-utils.js +14 -0
  564. package/skills/wix-replatform/resources/rp-target-wix/lib/variant-correlation.js +34 -0
  565. package/skills/wix-replatform/resources/rp-target-wix/lib/wix-build.js +166 -15
  566. package/skills/wix-replatform/resources/rp-target-wix/lib/wix-target-spec.js +19 -2
  567. package/skills/wix-replatform/resources/rp-target-wix/lib/wix-writers.js +4079 -257
  568. package/skills/wix-replatform/resources/rp-target-wix/lib/write-verification.js +3 -0
  569. package/skills/wix-replatform/resources/rp-target-wix/scripts/docs-survey-sync.js +150 -0
  570. package/skills/wix-replatform/resources/rp-target-wix/scripts/domain-knowledge-validate.js +40 -2
  571. package/skills/wix-replatform/resources/rp-target-wix/scripts/verify-stores.js +6 -1
  572. package/skills/wix-replatform/resources/rp-telemetry/SKILL.md +148 -8
  573. package/skills/wix-replatform/resources/rp-telemetry/lib/bi-sink.js +83 -15
  574. package/skills/wix-replatform/resources/rp-telemetry/lib/telemetry-recorder.js +1119 -215
  575. package/skills/wix-replatform/resources/rp-telemetry/lib/transcript-digest.js +318 -0
  576. package/skills/wix-replatform/resources/rp-telemetry/scripts/meter-from-audit.js +2 -2
  577. package/skills/wix-replatform/resources/rp-telemetry/scripts/rp-telemetry.js +106 -4
  578. package/skills/wix-replatform/resources/rp-website-continuation/SKILL.md +94 -0
  579. package/skills/wix-replatform/scripts/census-reconciliation.js +25 -0
  580. package/skills/wix-replatform/scripts/cms-fallback.js +89 -0
  581. package/skills/wix-replatform/scripts/discovered-census.js +26 -0
  582. package/skills/wix-replatform/scripts/discovered-set-status.js +33 -0
  583. package/skills/wix-replatform/scripts/entity-qa-attestation.js +130 -0
  584. package/skills/wix-replatform/scripts/execution-health-check.js +415 -0
  585. package/skills/wix-replatform/scripts/execution-manifest-validate.js +1 -1
  586. package/skills/wix-replatform/scripts/execution-state-prepare.js +1 -1
  587. package/skills/wix-replatform/scripts/expectations-ledger.js +44 -0
  588. package/skills/wix-replatform/scripts/import-contract-verify.js +183 -0
  589. package/skills/wix-replatform/scripts/internal-link-audit.js +90 -0
  590. package/skills/wix-replatform/scripts/item-seo-tags-verify.js +205 -0
  591. package/skills/wix-replatform/scripts/migration-completion.js +76 -0
  592. package/skills/wix-replatform/scripts/orchestration-preflight.js +21 -2
  593. package/skills/wix-replatform/scripts/orchestration-route.js +32 -1
  594. package/skills/wix-replatform/scripts/orchestration-state.js +146 -10
  595. package/skills/wix-replatform/scripts/read-back-gate.js +175 -0
  596. package/skills/wix-replatform/scripts/replatform-console.js +146 -0
  597. package/skills/wix-replatform/scripts/replatform.js +436 -0
  598. package/skills/wix-replatform/scripts/source-secrets.js +77 -0
  599. package/skills/wix-replatform/scripts/url-redirects.js +286 -0
  600. package/skills/wix-replatform/scripts/user-action.js +58 -0
  601. package/skills/wix-replatform/scripts/website-handoff-generate.js +64 -0
  602. package/skills/wix-replatform/scripts/wix-dashboard-url.js +54 -0
  603. package/skills/wix-replatform/scripts/wix-destination.js +143 -0
  604. package/skills/wix-replatform/scripts/wix-headless-scaffold.js +762 -0
  605. package/skills/wix-vibe-headless/SKILL.md +7 -3
  606. package/skills/wix-vibe-headless/install/deploy.cjs +61 -34
  607. package/skills/wix-vibe-headless/platforms/base44.md +1 -0
  608. package/skills/wix-vibe-headless/references/donations/INSTRUCTIONS.md +88 -0
  609. package/skills/wix-vibe-headless/references/donations/app/rest/wix-donations.js +112 -0
  610. package/skills/wix-vibe-headless/references/donations/seed/SEED.md +11 -0
  611. package/skills/wix-vibe-headless/references/donations/tests/donations.test.mjs +258 -0
  612. package/skills/wix-vibe-headless/references/restaurants/INSTRUCTIONS.md +5 -2
  613. package/skills/wix-vibe-headless/references/restaurants/app/context/OrderCartContext.jsx +4 -1
  614. package/skills/wix-vibe-headless/references/restaurants/app/rest/wix-restaurants-ordering.js +67 -3
  615. package/skills/wix-vibe-headless/references/shared/app/rest/wix-client.js +4 -3
  616. package/skills/wix-replatform/resources/rp-target-wix/SPEC-product-reviews-and-blog-authorship.md +0 -330
@@ -3,6 +3,23 @@
3
3
  const fs = require('node:fs/promises');
4
4
  const path = require('node:path');
5
5
  const { validateArtifacts } = require('./orchestration-state.js');
6
+ const { getDecisionValue, isEditorSiteType, isExplicitUserOneClick, isKnownSourceMode } = require('./orchestration-decisions.js');
7
+ const { destinationGate, publicationRecheckGate } = require('./destination-route.js');
8
+ const { validateWebsiteHandoff } = require('./website-handoff.js');
9
+ const { statEnvKeys, readEnvFile } = require('./config-env.js');
10
+ const { hashArtifact } = require('./artifact-freshness.js');
11
+ const { validatePlanShape, validateSetupRequirementsShape, validateSetupVerification } = require('./setup-verification.js');
12
+ const { validateManifest } = require('./execution-manifest.js');
13
+ const { QUICK_IMPORT_STARTED_MARKER, validateQuickExecutionManifest } = require('../resources/rp-quick-runtime/lib/import-progress.js');
14
+ const { checkCmsFallbackFreshness } = require('./plugin-cms-fallback.js');
15
+ const {
16
+ classifyFinalizedRun,
17
+ loadMigrationCompletionInputs,
18
+ validateFrontendCompletion,
19
+ validateMigrationCompletion,
20
+ } = require('./migration-completion.js');
21
+ const { readReconciliation, censusReconciliationFreshness, mappingApprovalBound, reconcileSourceCoverageForMapping } = require('./census-reconciliation.js');
22
+ const { readCoverageContract, reconcileProject, SourceCoverageError } = require('./source-coverage.js');
6
23
 
7
24
  async function exists(filePath) {
8
25
  try {
@@ -21,7 +38,129 @@ async function readJson(filePath) {
21
38
  }
22
39
  }
23
40
 
24
- async function determineNextStep(projectDir, artifacts) {
41
+ // Rules for the two LLM-assisted outputs: parseable JSON whose top level is a
42
+ // non-array object. Nothing else is read (no versioned contract exists; mapping row shape is
43
+ // owned by the tolerant `readEntityMappings` consumer).
44
+ function validateSourceSchemaShape(value) {
45
+ return value && typeof value === 'object' && !Array.isArray(value)
46
+ ? { ok: true, errors: [] }
47
+ : { ok: false, errors: ['source-schema.json must be a JSON object'] };
48
+ }
49
+
50
+ function validateMappingPlanShape(value) {
51
+ return value && typeof value === 'object' && !Array.isArray(value)
52
+ ? { ok: true, errors: [] }
53
+ : { ok: false, errors: ['mapping/mapping-plan.json must be a JSON object'] };
54
+ }
55
+
56
+ function setupPlanRule(value) {
57
+ const result = validatePlanShape(value);
58
+ return { ok: result.ok, errors: result.reasons };
59
+ }
60
+
61
+ // Reads each gated output at most once per route. `present: false` only for a missing file;
62
+ // anything that exists but cannot be parsed is present with `parseError`.
63
+ function createArtifactReader(projectDir) {
64
+ const cache = new Map();
65
+ return async function readArtifact(relativePath) {
66
+ if (cache.has(relativePath)) return cache.get(relativePath);
67
+ let entry;
68
+ try {
69
+ const raw = await fs.readFile(path.join(projectDir, relativePath), 'utf8');
70
+ try {
71
+ entry = { present: true, value: JSON.parse(raw) };
72
+ } catch (error) {
73
+ entry = { present: true, value: null, parseError: `invalid JSON: ${error.message}` };
74
+ }
75
+ } catch (error) {
76
+ entry = error && error.code === 'ENOENT'
77
+ ? { present: false, value: null }
78
+ : { present: true, value: null, parseError: `unreadable: ${(error && error.code) || error}` };
79
+ }
80
+ cache.set(relativePath, entry);
81
+ return entry;
82
+ };
83
+ }
84
+
85
+ // Missing → `{ present: false }` (caller keeps its existing route). Present but
86
+ // failing its rule → `{ present: true, errors }`. Validation is skipped once backend
87
+ // accounting exists: upstream outputs are history then, and keep existence-only behavior.
88
+ async function checkGatedOutput(readArtifact, relativePath, rule, { validate }) {
89
+ const entry = await readArtifact(relativePath);
90
+ if (!entry.present) return { present: false, errors: null };
91
+ if (!validate) return { present: true, errors: null };
92
+ if (entry.parseError) return { present: true, errors: [entry.parseError] };
93
+ const result = rule(entry.value);
94
+ return { present: true, errors: result.ok ? null : result.errors };
95
+ }
96
+
97
+ function invalidOutputRoute(reason, nextResource, errors) {
98
+ return { ok: true, nextState: 'blocked', nextResource, reason, errors, blocking: true };
99
+ }
100
+
101
+ async function nonEmptyFile(filePath, minBytes = 1) {
102
+ try {
103
+ const stat = await fs.stat(filePath);
104
+ return stat.isFile() && stat.size >= minBytes;
105
+ } catch {
106
+ return false;
107
+ }
108
+ }
109
+
110
+ // Existence/size only — the router never reads or scans these files. Sample
111
+ // journals and a mirror-seeded crosswalk are deliberately not evidence.
112
+ const QUICK_CROSSWALKS = {
113
+ woocommerce: 'state/crosswalk/quick-mode.json',
114
+ shopify: 'state/crosswalk/quick-shopify.json',
115
+ };
116
+
117
+ async function importProgressFields(projectDir, { quickPlatform = null } = {}) {
118
+ const evidence = [];
119
+ if (quickPlatform) {
120
+ if (await exists(path.join(projectDir, QUICK_IMPORT_STARTED_MARKER))) evidence.push(QUICK_IMPORT_STARTED_MARKER);
121
+ const crosswalk = QUICK_CROSSWALKS[quickPlatform];
122
+ // Legacy projects interrupted before the marker shipped: a checkpoint that is not `{}`.
123
+ // The adapters write `{}` as `{}\n` (3 bytes), so the size test is "more than 3 bytes";
124
+ // any checkpoint with one entry is far larger.
125
+ if (crosswalk && await nonEmptyFile(path.join(projectDir, crosswalk), 4)) evidence.push(crosswalk);
126
+ } else {
127
+ for (const relativePath of ['state/attempts/write-attempts.ndjson', 'execution/unresolved-writes.ndjson']) {
128
+ if (await nonEmptyFile(path.join(projectDir, relativePath))) evidence.push(relativePath);
129
+ }
130
+ }
131
+ return evidence.length ? { importProgress: 'interrupted', recoveryArtifacts: evidence } : { importProgress: 'not_started' };
132
+ }
133
+
134
+ // A setup-verification.json that exists but doesn't validate (wrong schema, incomplete
135
+ // plan coverage, or a stale planDigest) is treated identically to one that doesn't exist —
136
+ // no separate router state, no fail-open branch.
137
+ async function isSetupVerified(projectDir, readArtifact) {
138
+ const verificationPath = path.join(projectDir, 'setup', 'setup-verification.json');
139
+ if (!(await exists(verificationPath))) return false;
140
+ const verification = await readJson(verificationPath);
141
+ const plan = (await readArtifact(path.join('setup', 'setup-plan.json'))).value;
142
+ const planDigest = hashArtifact(projectDir, path.join('setup', 'setup-plan.json'));
143
+ return validateSetupVerification({ verification, plan, planDigest }).ok;
144
+ }
145
+
146
+ // A stamped project cannot leave mapping while any source-coverage row lacks
147
+ // exactly one valid disposition. An unstamped (pre-contract) project has no coverage record to
148
+ // check; the completion report carries that instead.
149
+ async function sourceCoverageGate(projectDir) {
150
+ try {
151
+ const contract = await readCoverageContract(projectDir);
152
+ if (!contract.stamped) return { ok: true, failures: [] };
153
+ const result = await reconcileProject(projectDir);
154
+ return { ok: result.ok, failures: result.failures };
155
+ } catch (error) {
156
+ if (error instanceof SourceCoverageError) {
157
+ return { ok: false, failures: error.failures.length ? error.failures : [{ code: 'invalid_coverage', coverageId: null, message: error.message, sources: [] }] };
158
+ }
159
+ throw error;
160
+ }
161
+ }
162
+
163
+ async function determineNextStepUnfiltered(projectDir, artifacts, { reviewOnly = false, ...options } = {}) {
25
164
  const validation = validateArtifacts(artifacts);
26
165
  if (!validation.ok) {
27
166
  return {
@@ -33,62 +172,398 @@ async function determineNextStep(projectDir, artifacts) {
33
172
  };
34
173
  }
35
174
 
175
+ if (artifacts.run.status === 'cancel_requested') {
176
+ return { ok: true, nextState: 'cancel_requested', nextResource: null, reason: 'cancellation_cleanup_required', blocking: true };
177
+ }
178
+ if (artifacts.run.status === 'canceled' || artifacts.run.status === 'interrupted') {
179
+ return { ok: true, nextState: artifacts.run.status, nextResource: null, reason: artifacts.run.status, blocking: true };
180
+ }
181
+
36
182
  const decisions = artifacts.decisions || {};
37
183
  const approvals = artifacts.approvals || {};
38
- const sourceUrl = decisions.sourceUrl && decisions.sourceUrl.value;
39
- const sourceMode = decisions.sourceMode && decisions.sourceMode.value;
40
- const fileInputPaths = decisions.fileInputPaths && decisions.fileInputPaths.value;
184
+ const sourceUrl = getDecisionValue(decisions, 'sourceUrl');
185
+ const sourceMode = getDecisionValue(decisions, 'sourceMode');
186
+ const fileInputPaths = getDecisionValue(decisions, 'fileInputPaths');
41
187
  const hasFileInputs = Array.isArray(fileInputPaths) && fileInputPaths.length > 0;
42
- const deliveryMode = decisions.deliveryMode && decisions.deliveryMode.value;
43
- const targetSiteStrategy = decisions.targetSiteStrategy && decisions.targetSiteStrategy.value;
188
+ const deliveryMode = getDecisionValue(decisions, 'deliveryMode');
189
+ const isOneClick = isExplicitUserOneClick(decisions);
190
+ const websiteScope = getDecisionValue(decisions, 'websiteScope');
191
+ const targetSiteStrategy = getDecisionValue(decisions, 'targetSiteStrategy');
192
+ const managementImportMode = getDecisionValue(decisions, 'managementImportMode') || 'standard';
193
+ const sourcePlatform = getDecisionValue(decisions, 'sourcePlatform');
44
194
  const preflight = artifacts.preflight || null;
195
+ const readArtifact = createArtifactReader(projectDir);
196
+
197
+ if (deliveryMode && !['management', 'website', 'management_and_website'].includes(deliveryMode)) {
198
+ return { ok: false, nextState: 'failed', nextResource: 'resources/rp-project-intake/', reason: 'invalid_delivery_mode' };
199
+ }
200
+
201
+ if (!deliveryMode) {
202
+ return { ok: true, nextState: 'awaiting_destination_strategy', nextResource: 'resources/rp-project-intake/', reason: 'missing_delivery_mode' };
203
+ }
204
+
205
+ if (managementImportMode && !['standard', 'quick'].includes(managementImportMode)) {
206
+ return { ok: false, nextState: 'failed', nextResource: 'resources/rp-project-intake/', reason: 'invalid_management_import_mode' };
207
+ }
208
+
209
+ // Frontend-only work deliberately avoids the backend migration pipeline. The headless
210
+ // skill owns its destination/project and terminal website artifacts in this mode.
211
+ if (deliveryMode === 'website') {
212
+ if (!sourceUrl) {
213
+ return { ok: true, nextState: 'awaiting_source', nextResource: 'resources/rp-source-inputs/', reason: 'missing_source_url' };
214
+ }
215
+ const completionInputs = await loadMigrationCompletionInputs(projectDir);
216
+ const frontend = validateFrontendCompletion(completionInputs.frontendCompletion, null, { requireHandoff: false });
217
+ if (frontend.ok) {
218
+ return { ok: true, nextState: 'completed', nextResource: null, reason: 'website_completion_present' };
219
+ }
220
+ return { ok: true, nextState: 'storefront_running', nextResource: 'resources/rp-website-continuation/', reason: 'website_only_frontend' };
221
+ }
222
+
223
+ if (!targetSiteStrategy) {
224
+ return { ok: true, nextState: 'awaiting_destination_strategy', nextResource: 'resources/rp-destination/', reason: 'missing_target_site_strategy' };
225
+ }
226
+
227
+ // The decision above only records which strategy was CHOSEN — it says nothing about
228
+ // whether the destination actually got provisioned. rp-destination persists the
229
+ // metasite id into config/wix.env on success; if that never happened (a scaffold
230
+ // failure, a 409, anything short of completion), targetSiteStrategy can still be set
231
+ // while no destination exists. Without this check the router falls through toward
232
+ // preflight, which reports the generic "wix.env is missing" — indistinguishable from a
233
+ // run that never started — and there is no route back into destination creation for
234
+ // the rest of the run. Applies to both strategies uniformly: rp-destination
235
+ // is the one module responsible for resolving either, and "persist the metasite id" is
236
+ // its stated postcondition for both, so this only re-verifies that postcondition rather
237
+ // than re-deriving which strategy path was taken.
238
+ //
239
+ // nextState is 'destination_running', NOT 'awaiting_destination_strategy': the
240
+ // decision is already made, so this is the agent actively retrying creation, not a
241
+ // pause for a new user decision. orchestration-state.js requires needsUserInput=true
242
+ // for every 'awaiting_*' state (isAwaitingState) — reusing that prefix here would
243
+ // force a stop for input that was never needed and could wrongly halt 1-click
244
+ // automation on a plain retry. 'destination_running' follows the same naming and
245
+ // needsUserInput=false convention as the other in-progress states here
246
+ // (preflight_running, discovery_running, etc.).
247
+ // WIX_SCAFFOLD_STATUS must be read and classified *before* deciding whether
248
+ // the missing-WIX_SITE_ID case is a clean first attempt or a durable, already-failed
249
+ // one. The wrapper can leave
250
+ // a durable in_progress/ambiguous marker behind with NO WIX_SITE_ID at all (an
251
+ // interrupted or unconfirmed attempt); checking WIX_SITE_ID's presence first and
252
+ // returning immediately, as a prior version of this router did, never looks at that
253
+ // marker — every restart re-classifies it as a fresh, automatically-retryable
254
+ // destination_running, rp-destination invokes the wrapper, the wrapper correctly
255
+ // refuses again, and the router repeats the same non-decision forever. This is exactly
256
+ // the no-progress loop the WIX_SITE_ID-present branch below already exists to prevent
257
+ // for `incomplete` — it just wasn't extended to the no-site-id side.
258
+ const wixEnvPath = path.join(projectDir, 'config', 'wix.env');
259
+ const wixEnv = await statEnvKeys(wixEnvPath, ['WIX_SITE_ID']);
260
+ const wixEnvValues = await readEnvFile(wixEnvPath).catch((error) => {
261
+ if (error && error.code === 'ENOENT') return {};
262
+ throw error;
263
+ });
264
+ const scaffoldStatus = wixEnvValues.WIX_SCAFFOLD_STATUS;
265
+
266
+ // Receipt-backed Editor destinations and the explicit new-site type choice.
267
+ const destinationRoute = await destinationGate(projectDir, decisions, {
268
+ targetSiteStrategy,
269
+ siteIdValue: wixEnv.keys.WIX_SITE_ID === 'present' ? String(wixEnvValues.WIX_SITE_ID).trim() : null,
270
+ scaffoldStatus,
271
+ });
272
+ if (destinationRoute) return destinationRoute;
273
+
274
+ if (wixEnv.keys.WIX_SITE_ID !== 'present') {
275
+ // No confirmed destination yet. Only a genuinely untouched wix.env (no status marker
276
+ // at all) is a clean first attempt — anything the wrapper itself already recorded
277
+ // here is a durable outcome of a real, failed attempt and must not be treated as one.
278
+ if (scaffoldStatus === undefined) {
279
+ return { ok: true, nextState: 'destination_running', nextResource: 'resources/rp-destination/', reason: 'destination_not_provisioned' };
280
+ }
281
+ if (scaffoldStatus === 'in_progress') {
282
+ // An attempt was interrupted before it could record any outcome, and no local
283
+ // receipt exists either — the wrapper itself now refuses to retry through this;
284
+ // the router must not retry around it. 'blocked', not
285
+ // 'destination_running': no repair path exists, so an auto-retryable state here
286
+ // is a no-progress loop, exactly like the incomplete case below.
287
+ return { ok: true, nextState: 'blocked', nextResource: 'resources/rp-destination/', reason: 'destination_scaffold_interrupted' };
288
+ }
289
+ // Any other present value with no WIX_SITE_ID (ambiguous, or corrupted/unexpected
290
+ // text) — the wrapper cannot confirm whether a destination exists in this state
291
+ // either, and this router has no more information than the wrapper does.
292
+ return { ok: true, nextState: 'blocked', nextResource: 'resources/rp-destination/', reason: 'destination_scaffold_ambiguous' };
293
+ }
294
+
295
+ // WIX_SCAFFOLD_STATUS must also be consumed once WIX_SITE_ID is present, not
296
+ // just written by the scaffold wrapper — otherwise a restarted run sees WIX_SITE_ID
297
+ // present, advances past rp-destination, and never re-invokes the wrapper branch that
298
+ // rejects an incomplete scaffold. Routes to 'blocked' (not 'destination_running'): there
299
+ // is no repair path, so an automatically-retryable state here would be a
300
+ // no-progress loop — 'blocked' is the one state orchestration-state.js's own
301
+ // validateRun invariant structurally requires needsUserInput=true for.
302
+ if (scaffoldStatus === 'incomplete') {
303
+ return { ok: true, nextState: 'blocked', nextResource: 'resources/rp-destination/', reason: 'destination_scaffold_incomplete' };
304
+ }
305
+ if (scaffoldStatus !== undefined && scaffoldStatus !== 'complete') {
306
+ return { ok: true, nextState: 'blocked', nextResource: 'resources/rp-destination/', reason: 'destination_scaffold_status_invalid' };
307
+ }
45
308
 
46
309
  // A file-provided run (e.g. platform=csv) has no source URL to probe; its
47
- // input files stand in for one. URL-based runs are unaffected: they never
48
- // carry sourceMode=files_only, so they still fall through to the checks below
49
- // in the original order.
310
+ // input files stand in for one. Destination resolution has already happened,
311
+ // so source readiness can now branch between file and URL inputs.
50
312
  if (sourceMode === 'files_only') {
51
313
  if (!hasFileInputs) {
52
- return { ok: true, nextState: 'awaiting_files', nextResource: null, reason: 'missing_file_inputs' };
314
+ return { ok: true, nextState: 'awaiting_files', nextResource: 'resources/rp-source-inputs/', reason: 'missing_file_inputs' };
53
315
  }
54
316
  } else if (!sourceUrl && !hasFileInputs) {
55
- return { ok: true, nextState: 'awaiting_source', nextResource: null, reason: 'missing_source_url' };
317
+ return { ok: true, nextState: 'awaiting_source', nextResource: 'resources/rp-source-inputs/', reason: 'missing_source_url' };
56
318
  }
57
319
  if (!sourceMode) {
58
- return { ok: true, nextState: 'awaiting_import_scope', nextResource: null, reason: 'missing_source_mode' };
320
+ return { ok: true, nextState: 'awaiting_import_scope', nextResource: 'resources/rp-source-inputs/', reason: 'missing_source_mode' };
59
321
  }
60
- if (!deliveryMode || !targetSiteStrategy) {
61
- return { ok: true, nextState: 'awaiting_destination_strategy', nextResource: null, reason: 'missing_destination_strategy' };
322
+ // A bad value already on disk (a run recorded before `decide` validated it, or a
323
+ // hand-written decisions file) stops here, before any preflight result is read, so a
324
+ // stale passing preflight.json cannot advance the run. Recording a canonical value
325
+ // through `decide` replaces it.
326
+ if (!isKnownSourceMode(sourceMode)) {
327
+ return { ok: true, nextState: 'awaiting_import_scope', nextResource: 'resources/rp-source-inputs/', reason: 'invalid_source_mode' };
62
328
  }
63
329
 
64
330
  if (!preflight || !preflight.status || preflight.status === 'not_started') {
65
- return { ok: true, nextState: 'preflight_running', nextResource: null, reason: 'preflight_missing' };
331
+ return { ok: true, nextState: 'preflight_running', nextResource: 'resources/rp-preflight/', reason: 'preflight_missing' };
66
332
  }
67
333
  if (preflight.status === 'blocked') {
68
- return { ok: true, nextState: 'preflight_blocked', nextResource: null, reason: 'preflight_blocked' };
334
+ return { ok: true, nextState: 'preflight_blocked', nextResource: 'resources/rp-preflight/', reason: 'preflight_blocked' };
69
335
  }
70
336
  if (preflight.status === 'failed') {
71
337
  return { ok: false, nextState: 'failed', nextResource: null, reason: 'preflight_failed', errors: [] };
72
338
  }
73
339
 
74
- if (!(await exists(path.join(projectDir, 'source-schema.json')))) {
75
- return { ok: true, nextState: 'discovery_running', nextResource: 'resources/rp-discovery/', reason: 'missing_source_schema' };
340
+ // Scope boundary: phase-output validation runs only before backend accounting.
341
+ const completionReportPresent = await exists(path.join(projectDir, 'execution', 'completion-report.json'));
342
+ // A recorded rejection is never an approval, in any mode (one-click included).
343
+ const executionRejected = Boolean(approvals.execution && approvals.execution.status === 'rejected');
344
+ const executionRejectedRoute = { ok: true, nextState: 'blocked', nextResource: 'resources/rp-execution-policy/', reason: 'execution_approval_rejected', blocking: true };
345
+
346
+ if (managementImportMode === 'quick') {
347
+ if (!sourcePlatform) {
348
+ return { ok: true, nextState: 'quick_mode_adapter_resolution_required', nextResource: 'resources/rp-source-inputs/', reason: 'quick_mode_platform_not_detected' };
349
+ }
350
+ const quickResources = {
351
+ shopify: 'resources/rp-quick-shopify/',
352
+ woocommerce: 'resources/rp-quick-woocommerce/',
353
+ };
354
+ const quickResource = quickResources[sourcePlatform];
355
+ if (!quickResource) {
356
+ return { ok: true, nextState: 'blocked', nextResource: 'resources/rp-source-inputs/', reason: 'quick_mode_unsupported_platform', errors: [{ platform: sourcePlatform }] };
357
+ }
358
+ const quickPreflight = await readJson(path.join(projectDir, 'quick-mode', 'preflight.json'));
359
+ if (!quickPreflight) {
360
+ return { ok: true, nextState: 'quick_mode_preflight_required', nextResource: quickResource, reason: 'quick_mode_preflight_missing' };
361
+ }
362
+ if (quickPreflight.status !== 'passed') {
363
+ return {
364
+ ok: true,
365
+ nextState: 'blocked',
366
+ nextResource: quickResource,
367
+ reason: 'quick_mode_preflight_blocked',
368
+ errors: [{ status: quickPreflight.status || 'invalid' }],
369
+ };
370
+ }
371
+ if (!(await exists(path.join(projectDir, 'quick-mode', 'plan.json')))) {
372
+ return { ok: true, nextState: 'quick_mode_plan_required', nextResource: quickResource, reason: 'quick_mode_plan_missing' };
373
+ }
374
+
375
+ const quickSetupPlan = await checkGatedOutput(readArtifact, path.join('setup', 'setup-plan.json'), setupPlanRule, { validate: !completionReportPresent });
376
+ const quickSetupRequirements = await checkGatedOutput(readArtifact, path.join('setup', 'setup-requirements.json'), validateSetupRequirementsShape, { validate: !completionReportPresent });
377
+ if (!quickSetupPlan.present || !quickSetupRequirements.present) {
378
+ return { ok: true, nextState: 'setup_discovery_running', nextResource: 'resources/rp-setup-discovery/', reason: 'quick_mode_setup_plan_missing' };
379
+ }
380
+ if (quickSetupPlan.errors) return invalidOutputRoute('setup_plan_invalid', 'resources/rp-setup-discovery/', quickSetupPlan.errors);
381
+ if (quickSetupRequirements.errors) return invalidOutputRoute('setup_requirements_invalid', 'resources/rp-setup-discovery/', quickSetupRequirements.errors);
382
+
383
+ const quickManifest = await checkGatedOutput(readArtifact, path.join('execution', 'execution-manifest.json'), validateQuickExecutionManifest, { validate: !completionReportPresent });
384
+ if (!quickManifest.present) {
385
+ return { ok: true, nextState: 'quick_mode_plan_required', nextResource: quickResource, reason: 'quick_mode_execution_manifest_missing' };
386
+ }
387
+ if (quickManifest.errors) return invalidOutputRoute('execution_manifest_invalid', quickResource, quickManifest.errors);
388
+
389
+ if (executionRejected) return executionRejectedRoute;
390
+ if (!isOneClick && approvals.execution && approvals.execution.status === 'pending') {
391
+ return { ok: true, nextState: 'awaiting_execution_approval', nextResource: 'resources/rp-execution-policy/', reason: 'execution_approval_pending' };
392
+ }
393
+ if (!(await isSetupVerified(projectDir, readArtifact))) {
394
+ return { ok: true, nextState: 'executing_setup', nextResource: 'resources/rp-execute-setup/', reason: 'missing_setup_verification' };
395
+ }
396
+ if (!completionReportPresent) {
397
+ // A capacity blocker is a durable stop. The operator frees
398
+ // categories (or stops); the re-run import rewrites this file as `passed`.
399
+ const capacity = await readJson(path.join(projectDir, 'quick-mode', 'category-capacity.json'));
400
+ if (capacity && capacity.status === 'blocked') {
401
+ return {
402
+ ok: true,
403
+ nextState: 'blocked',
404
+ nextResource: quickResource,
405
+ reason: 'quick_mode_category_capacity_blocked',
406
+ errors: [{ existingCount: capacity.existingCount, toCreate: capacity.toCreate, max: capacity.max }],
407
+ choices: ['free_destination_categories_and_retry', 'stop'],
408
+ };
409
+ }
410
+ return {
411
+ ok: true,
412
+ nextState: 'executing_import',
413
+ nextResource: quickResource,
414
+ reason: 'quick_mode_import_required',
415
+ ...(await importProgressFields(projectDir, { quickPlatform: sourcePlatform })),
416
+ };
417
+ }
418
+ // An operator-requested re-check of written-unverified products.
419
+ // Without a request a partial report never loops back; once the receipt matches the request
420
+ // it never fires again. A staged result for the request keeps the route alive even when the
421
+ // completion report already shows an empty list (a crash between the report and the receipt).
422
+ if (sourcePlatform === 'shopify') {
423
+ const request = await readJson(path.join(projectDir, 'quick-mode', 'reverify-request.json'));
424
+ if (request && request.requestId) {
425
+ const receipt = await readJson(path.join(projectDir, 'quick-mode', 'reverification.json'));
426
+ if (!receipt || receipt.requestId !== request.requestId) {
427
+ const completion = await readJson(path.join(projectDir, 'execution', 'completion-report.json'));
428
+ const listed = completion && completion.writtenUnverified && Array.isArray(completion.writtenUnverified.product) && completion.writtenUnverified.product.length > 0;
429
+ const staged = await readJson(path.join(projectDir, 'quick-mode', 'reverification-staged.json'));
430
+ if (listed || (staged && staged.requestId === request.requestId)) {
431
+ return { ok: true, nextState: 'quick_mode_reverification_required', nextResource: quickResource, reason: 'quick_mode_written_unverified_reverify_requested' };
432
+ }
433
+ }
434
+ }
435
+ }
436
+ }
437
+
438
+ const validateOutputs = reviewOnly || !completionReportPresent;
439
+ if (managementImportMode !== 'quick') {
440
+ const sourceSchema = await checkGatedOutput(readArtifact, 'source-schema.json', validateSourceSchemaShape, { validate: validateOutputs });
441
+ if (!sourceSchema.present) {
442
+ return { ok: true, nextState: 'discovery_running', nextResource: 'resources/rp-discovery/', reason: 'missing_source_schema' };
443
+ }
444
+ if (sourceSchema.errors) return invalidOutputRoute('source_schema_invalid', 'resources/rp-discovery/', sourceSchema.errors);
76
445
  }
77
446
 
78
- if (!(await exists(path.join(projectDir, 'mapping', 'mapping-plan.json')))) {
79
- return { ok: true, nextState: 'mapping_running', nextResource: 'resources/rp-mapper/', reason: 'missing_mapping_plan' };
447
+ // CMS-fallback freshness chain (plugin coverage -> mapping plan -> setup plan). A plan built
448
+ // before a CMS-fallback answer, a register change, or any change to what could resolve the
449
+ // capability natively (target knowledge, the detected plugin's current profile, the other
450
+ // signed registers) is treated as missing. Coverage and mapping are checked here, before the
451
+ // mapping-plan, source-coverage and mapping-approval gates; the setup plan right after the
452
+ // mapping approval (setup discovery requires an accepted mapping) and before every
453
+ // setup/import step. Neither check is skipped for one-click runs.
454
+ const freshness = managementImportMode !== 'quick'
455
+ ? checkCmsFallbackFreshness(projectDir, {
456
+ decisions,
457
+ pluginsRoot: options.pluginsRoot,
458
+ targetKnowledgeRoot: options.targetKnowledgeRoot,
459
+ })
460
+ : null;
461
+ if (freshness && freshness.stale === 'coverage') {
462
+ return { ok: true, nextState: 'discovery_running', nextResource: 'resources/rp-discovery/', reason: 'cms_fallback_inputs_changed' };
463
+ }
464
+ if (freshness && freshness.stale === 'mapping') {
465
+ return { ok: true, nextState: 'mapping_running', nextResource: 'resources/rp-mapper/', reason: 'mapping_plan_stale_cms_fallback' };
80
466
  }
81
467
 
82
- if (approvals.mapping && approvals.mapping.status === 'pending') {
83
- return { ok: true, nextState: 'awaiting_mapping_approval', nextResource: null, reason: 'mapping_approval_pending' };
468
+ if (managementImportMode !== 'quick') {
469
+ const mappingPlan = await checkGatedOutput(readArtifact, path.join('mapping', 'mapping-plan.json'), validateMappingPlanShape, { validate: validateOutputs });
470
+ if (!mappingPlan.present) {
471
+ return { ok: true, nextState: 'mapping_running', nextResource: 'resources/rp-mapper/', reason: 'missing_mapping_plan' };
472
+ }
473
+ if (mappingPlan.errors) return invalidOutputRoute('mapping_plan_invalid', 'resources/rp-mapper/', mappingPlan.errors);
474
+ if (reviewOnly) {
475
+ const gaps = await readArtifact('mapping/review/mapping-gaps.json');
476
+ if (gaps.present && (gaps.parseError || !gaps.value || typeof gaps.value !== 'object')) return invalidOutputRoute('mapping_plan_invalid', 'resources/rp-mapper/', ['mapping/review/mapping-gaps.json is invalid']);
477
+ }
478
+
479
+ // A rejected mapping returns to the mapper, which writes a new plan version
480
+ // and resets mapping approval to pending. One-click does not skip a recorded rejection.
481
+ if (approvals.mapping && approvals.mapping.status === 'rejected') {
482
+ return { ok: true, nextState: 'mapping_running', nextResource: 'resources/rp-mapper/', reason: 'mapping_approval_rejected' };
483
+ }
484
+ }
485
+
486
+ if (managementImportMode !== 'quick') {
487
+ const bound = await mappingApprovalBound(projectDir, approvals.mapping);
488
+ const coverageGate = bound ? await sourceCoverageGate(projectDir) : await reconcileSourceCoverageForMapping(projectDir, { mappingStatus: 'approved' });
489
+ if (!coverageGate.ok) {
490
+ return { ok: true, nextState: 'mapping_running', nextResource: 'resources/rp-mapper/', reason: 'source_coverage_unreconciled', errors: coverageGate.failures };
491
+ }
84
492
  }
85
493
 
86
- if (!(await exists(path.join(projectDir, 'setup', 'setup-plan.json')))) {
494
+ if (managementImportMode !== 'quick') {
495
+ const reconciliation = await readReconciliation(projectDir);
496
+ const route = (reason, detail = {}) => ({ ok: true, nextState: 'mapping_running', nextResource: 'resources/rp-mapper/', reason, ...detail });
497
+ if (!reconciliation) return route('census_reconciliation_missing');
498
+ const freshness = await censusReconciliationFreshness(projectDir, reconciliation);
499
+ if (!freshness.ok) return route('census_reconciliation_stale', { staleInputs: freshness.staleInputs });
500
+ if (reconciliation.errors?.length) return route('census_reconciliation_blocking', { errors: reconciliation.errors });
501
+ if (['approved','provisional'].includes(approvals.mapping?.status)) {
502
+ const ref = approvals.mapping.artifactRefs?.find(ref => ref && typeof ref === 'object' && ref.kind === 'census-reconciliation' && ref.path === 'mapping/review/census-reconciliation.json' && /^[0-9a-f]{64}$/i.test(ref.sha256 || ''));
503
+ if (!ref) return route('mapping_approval_missing_census');
504
+ if (!(await mappingApprovalBound(projectDir, approvals.mapping))) return route('mapping_approval_stale_census');
505
+ }
506
+ }
507
+
508
+ if (managementImportMode !== 'quick' && !isOneClick && approvals.mapping && approvals.mapping.status === 'pending') {
509
+ return { ok: true, nextState: 'awaiting_mapping_approval', nextResource: 'resources/rp-mapper/', reason: 'mapping_approval_pending' };
510
+ }
511
+
512
+ if (freshness && freshness.stale === 'setup') {
513
+ return { ok: true, nextState: 'setup_discovery_running', nextResource: 'resources/rp-setup-discovery/', reason: 'setup_plan_stale_cms_fallback' };
514
+ }
515
+
516
+ const setupPlan = await checkGatedOutput(readArtifact, path.join('setup', 'setup-plan.json'), setupPlanRule, { validate: validateOutputs });
517
+ if (!setupPlan.present) {
87
518
  return { ok: true, nextState: 'setup_discovery_running', nextResource: 'resources/rp-setup-discovery/', reason: 'missing_setup_plan' };
88
519
  }
520
+ if (setupPlan.errors) return invalidOutputRoute('setup_plan_invalid', 'resources/rp-setup-discovery/', setupPlan.errors);
521
+
522
+ const setupRequirements = await checkGatedOutput(readArtifact, path.join('setup', 'setup-requirements.json'), validateSetupRequirementsShape, { validate: validateOutputs });
523
+ if (!setupRequirements.present) {
524
+ return { ok: true, nextState: 'setup_discovery_running', nextResource: 'resources/rp-setup-discovery/', reason: 'missing_setup_requirements' };
525
+ }
526
+ if (setupRequirements.errors) return invalidOutputRoute('setup_requirements_invalid', 'resources/rp-setup-discovery/', setupRequirements.errors);
89
527
 
90
- if (!(await exists(path.join(projectDir, 'execution', 'execution-manifest.json')))) {
91
- return { ok: true, nextState: 'codegen_running', nextResource: 'resources/rp-import-codegen/', reason: 'missing_execution_manifest' };
528
+ if (deliveryMode === 'management_and_website' && !websiteScope && !isOneClick) {
529
+ return { ok: true, nextState: 'awaiting_website_scope', nextResource: 'resources/rp-project-intake/', reason: 'missing_website_scope' };
530
+ }
531
+
532
+ const handoffStatus = await validateWebsiteHandoff(projectDir);
533
+ if (!handoffStatus.present) {
534
+ return {
535
+ ok: true,
536
+ nextState: 'website_handoff_running',
537
+ nextResource: 'resources/rp-website-continuation/',
538
+ reason: 'missing_website_handoff',
539
+ };
540
+ }
541
+ if (handoffStatus.stale) {
542
+ return {
543
+ ok: true,
544
+ nextState: 'website_handoff_running',
545
+ nextResource: 'resources/rp-website-continuation/',
546
+ reason: 'stale_website_handoff',
547
+ changes: handoffStatus.changes,
548
+ };
549
+ }
550
+
551
+ if (!handoffStatus.ok) {
552
+ return {
553
+ ok: true,
554
+ nextState: 'mapping_running',
555
+ nextResource: 'resources/rp-mapper/',
556
+ reason: 'invalid_website_handoff',
557
+ errors: handoffStatus.blockingWarnings,
558
+ };
559
+ }
560
+
561
+ if (managementImportMode !== 'quick') {
562
+ const manifest = await checkGatedOutput(readArtifact, path.join('execution', 'execution-manifest.json'), validateManifest, { validate: validateOutputs });
563
+ if (!manifest.present) {
564
+ return { ok: true, nextState: 'codegen_running', nextResource: 'resources/rp-import-codegen/', reason: 'missing_execution_manifest' };
565
+ }
566
+ if (manifest.errors) return invalidOutputRoute('execution_manifest_invalid', 'resources/rp-import-codegen/', manifest.errors);
92
567
  }
93
568
 
94
569
  // Sample-preview sub-gate: codegen emits the extractor, runs it in sample
@@ -98,25 +573,126 @@ async function determineNextStep(projectDir, artifacts) {
98
573
  // schema change is involved. Projects that do not use the gate simply never
99
574
  // create the file and are unaffected.
100
575
  const previewResult = await readJson(path.join(projectDir, 'preview', 'preview-result.json'));
101
- if (previewResult && previewResult.status === 'pending') {
576
+ if (managementImportMode !== 'quick' && previewResult && previewResult.status === 'pending') {
102
577
  return { ok: true, nextState: 'codegen_running', nextResource: 'resources/rp-import-codegen/', reason: 'sample_preview_pending' };
103
578
  }
104
579
 
105
- if (approvals.execution && approvals.execution.status === 'pending') {
106
- return { ok: true, nextState: 'awaiting_execution_approval', nextResource: null, reason: 'execution_approval_pending' };
580
+ if (executionRejected) return executionRejectedRoute;
581
+ if (!isOneClick && approvals.execution && approvals.execution.status === 'pending') {
582
+ return { ok: true, nextState: 'awaiting_execution_approval', nextResource: 'resources/rp-execution-policy/', reason: 'execution_approval_pending' };
107
583
  }
108
584
 
109
- if (!(await exists(path.join(projectDir, 'setup', 'setup-verification.json')))) {
585
+ if (!(await isSetupVerified(projectDir, readArtifact))) {
110
586
  return { ok: true, nextState: 'executing_setup', nextResource: 'resources/rp-execute-setup/', reason: 'missing_setup_verification' };
111
587
  }
112
588
 
113
- if (!(await exists(path.join(projectDir, 'execution', 'completion-report.json')))) {
114
- return { ok: true, nextState: 'executing_import', nextResource: 'resources/rp-execute-import/', reason: 'missing_completion_report' };
589
+ if (!completionReportPresent) {
590
+ return {
591
+ ok: true,
592
+ nextState: 'executing_import',
593
+ nextResource: 'resources/rp-execute-import/',
594
+ reason: 'missing_completion_report',
595
+ ...(await importProgressFields(projectDir)),
596
+ };
597
+ }
598
+
599
+ const completionInputs = await loadMigrationCompletionInputs(projectDir);
600
+ if (deliveryMode === 'management_and_website') {
601
+ const frontend = validateFrontendCompletion(completionInputs.frontendCompletion, completionInputs.handoff);
602
+ // An Editor destination has no automatic frontend continuation. The website
603
+ // obligation stays outstanding as a handoff; never route into the Headless clone.
604
+ if (!frontend.ok && isEditorSiteType(getDecisionValue(decisions, 'targetSiteType'))) {
605
+ return {
606
+ ok: true,
607
+ nextState: 'blocked',
608
+ nextResource: 'resources/rp-website-continuation/',
609
+ reason: 'editor_website_handoff_outstanding',
610
+ requiredArtifacts: ['website/completion.json'],
611
+ blocking: true,
612
+ };
613
+ }
614
+ if (!frontend.ok) {
615
+ return {
616
+ ok: frontend.reason !== 'frontend_blocked',
617
+ nextState: frontend.reason === 'frontend_blocked' ? 'blocked' : 'storefront_running',
618
+ nextResource: 'resources/rp-website-continuation/',
619
+ reason: frontend.reason,
620
+ requiredArtifacts: ['website/handoff.json', 'website/completion.json'],
621
+ blocking: frontend.reason === 'frontend_blocked',
622
+ };
623
+ }
115
624
  }
116
625
 
117
- return { ok: true, nextState: 'completed', nextResource: null, reason: 'completion_report_present' };
626
+ const aggregate = validateMigrationCompletion(completionInputs.completion, {
627
+ deliveryMode,
628
+ backendCompletion: completionInputs.backendCompletion,
629
+ frontendCompletion: completionInputs.frontendCompletion,
630
+ handoff: completionInputs.handoff,
631
+ // The post-execution handoff and the execution log are part of what "finished" means.
632
+ // This is NOT a new router gate -- it is the existing `validateMigrationCompletion` gate
633
+ // being handed the inputs it now judges on. A gate given half its inputs passes on the half
634
+ // it was given, which is how three required artifacts came to have no writer.
635
+ postExecutionHandoff: completionInputs.postExecutionHandoff,
636
+ executionLogPresent: completionInputs.executionLogPresent,
637
+ // Same pattern again -- the entity-QA attestation gate, and the independent
638
+ // mapped-entity coverage source it is judged against, are more inputs to this same existing
639
+ // call, not a new router branch.
640
+ entityQaAttestation: completionInputs.entityQaAttestation,
641
+ mappedEntities: completionInputs.mappedEntities,
642
+ reportDigest: completionInputs.reportDigest,
643
+ discoveredSetStatus: completionInputs.discoveredSetStatus,
644
+ discoveredSetFreshness: completionInputs.discoveredSetFreshness,
645
+ discoveredSetDigest: completionInputs.discoveredSetDigest,
646
+ completionDiscoveredInputs: completionInputs.completionDiscoveredInputs,
647
+ resolutionsPrefixValid: completionInputs.resolutionsPrefixValid,
648
+ });
649
+ if (!aggregate.ok) {
650
+ return {
651
+ ok: true,
652
+ nextState: 'finalizing',
653
+ nextResource: 'resources/rp-execution-policy/',
654
+ reason: aggregate.reason,
655
+ requiredArtifacts: ['completion/migration-completion.json'],
656
+ blocking: false,
657
+ ...(aggregate.entityQa ? { entityQa: aggregate.entityQa } : {}),
658
+ };
659
+ }
660
+
661
+ return { ok: true, nextState: 'completed', nextResource: null, reason: 'migration_completion_present' };
662
+ }
663
+
664
+ const REVIEW_ONLY_MAPPING_REASONS = new Set(['mapping_approval_rejected', 'census_reconciliation_missing', 'census_reconciliation_stale', 'census_reconciliation_blocking', 'mapping_approval_missing_census', 'mapping_approval_stale_census']);
665
+ function applyReviewOnlyRoute(result) {
666
+ const hold = (reason, detail = {}) => ({ ...result, ok: true, nextState: 'blocked', nextResource: null, reason, blocking: true, reviewOnly: true, ...detail });
667
+ if (['missing_source_schema','source_schema_invalid','missing_mapping_plan','mapping_plan_invalid'].includes(result.reason)) return hold('review_only_input_unavailable', { errors: result.errors || [result.reason] });
668
+ if (result.reason === 'source_coverage_unreconciled') return hold('review_only_source_coverage_unreconciled');
669
+ if (REVIEW_ONLY_MAPPING_REASONS.has(result.reason) || result.reason === 'mapping_approval_pending' || result.nextState === 'finalizing') return { ...result, reviewOnly: true };
670
+ return hold('review_only_unexpected_route', { wouldRoute: result.reason });
671
+ }
672
+ async function determineNextStepForMode(projectDir, artifacts, options, validation) {
673
+ // Classification must precede every resource-bearing route, including intake and quick mode.
674
+ if (!validation.ok || ['cancel_requested','canceled','interrupted'].includes(artifacts.run.status)) return determineNextStepUnfiltered(projectDir, artifacts, options);
675
+ const finalized = await classifyFinalizedRun(projectDir, { decisions: artifacts.decisions || {} });
676
+ if (finalized.kind === 'unverified-v1') return { ok: true, nextState: 'blocked', nextResource: null, reason: 'finalized_receipt_unverified', errors: finalized.errors, reviewOnly: true, blocking: true };
677
+ const reviewOnly = finalized.kind === 'valid-v1';
678
+ const result = await determineNextStepUnfiltered(projectDir, artifacts, { ...options, reviewOnly });
679
+ // A finalized review-only run must never dispatch destination work. Standard runs
680
+ // still require master's fresh Editor publication readback before downstream work.
681
+ return reviewOnly ? applyReviewOnlyRoute(result) : publicationRecheckGate(projectDir, result, options);
682
+ }
683
+
684
+ async function determineNextStep(projectDir, artifacts, options = {}) {
685
+ const validation = validateArtifacts(artifacts);
686
+ const result = await determineNextStepForMode(projectDir, artifacts, options, validation);
687
+ // Preserve master's CMS-decision quarantine diagnostics on every route, including holds.
688
+ return validation.quarantined?.length
689
+ ? { ...result, validation: { quarantined: validation.quarantined } }
690
+ : result;
118
691
  }
119
692
 
120
693
  module.exports = {
694
+ applyReviewOnlyRoute,
121
695
  determineNextStep,
696
+ validateMappingPlanShape,
697
+ validateSourceSchemaShape,
122
698
  };