@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
@@ -0,0 +1,567 @@
1
+ 'use strict';
2
+
3
+ // rp-target-wix — blog post media: the cover (WordPress `featured_media`) and inline images.
4
+ //
5
+ // A blog importer that never resolves a WordPress image reference to a Wix file id ships posts
6
+ // with no cover and inline images still hot-linked to the old site. This module is the one
7
+ // place that does it, so no generated importer re-derives it.
8
+ //
9
+ // FAILURE POLICY (human-approved): when a post's cover or any inline image cannot be imported,
10
+ // THAT POST STAYS PENDING AND RECOVERABLE; other posts continue. Nothing is written to Wix for
11
+ // it — no draft, no publish, no crosswalk row — until every medium is confirmed READY. Do NOT
12
+ // add a partial-post fallback (import the text, drop a failed cover, keep a source URL for a
13
+ // failed inline image): that option was offered and not approved.
14
+ //
15
+ // Why the post waits for READY although a PENDING file id is already referenceable in blog
16
+ // content: that fact (see wix-writers.js, media import section) is true, but the policy needs
17
+ // failure discovery BEFORE the post ships, and only a settled file can say it failed.
18
+ //
19
+ // Caller shape (the generated blog importer):
20
+ //
21
+ // const richContent = await convertHtmlToRichContent(wix, post.contentHtml); // no media option
22
+ // const media = await importAndConfirmPostMedia(wix, { post, richContent, state, fetchFeaturedMedia });
23
+ // if (!media.allReady) continue; // nothing written; the state file already says why
24
+ // applyPostMedia(richContent, media); // rewrites the SAME document: no second conversion
25
+ // // createDraftPost(wix, { ..., richContent, heroImageId: media.heroImageId }), crosswalk row, then
26
+ // await state.markResolved(post.id, { targetPostId, runId, resumed: media.resumed });
27
+ //
28
+ // and on the crosswalk-gate path (the post is already written):
29
+ //
30
+ // await state.closeIfCrosswalked(post.id, { targetPostId, runId });
31
+ //
32
+ // Both close the record AND own the recovery-log entry for a post that had been pending, so
33
+ // no caller ordering can lose it (see "Recovery-log entry" below).
34
+ //
35
+ // Inline identity. rewriteInlineMedia replaces an image only when its `imageData.image.src.url`
36
+ // EXACTLY equals a map key. So keys are collected from the converted Ricos document, never from
37
+ // raw HTML: the collection key and the rewrite key are the same string by construction, with no
38
+ // canonicalizer to drift from the converter's own entity decoding and encoding.
39
+ //
40
+ // Out of scope here: images the converter does not emit as a Ricos image node (lazy-load markup
41
+ // with the URL only in data-src/srcset), and inline video/audio.
42
+
43
+ const crypto = require('node:crypto');
44
+ const fs = require('node:fs/promises');
45
+ const path = require('node:path');
46
+ const writers = require('./wix-writers.js');
47
+ const { resolveImageUrl } = require('../../rp-source-wordpress/lib/wp-image-url.js');
48
+
49
+ const SCHEMA_VERSION = 1;
50
+ const STATE_FILE = 'pending-blog-media.ndjson';
51
+ const OUTCOMES = ['imported', 'ready', 'fetch-failed', 'unresolvable-url', 'import-rejected', 'failed', 'not-ready', 'status-unknown'];
52
+ // A medium whose last row carries a file id in one of these outcomes is resumed, never
53
+ // re-imported: `ready` is reused as-is, the others are polled again.
54
+ const RESUMABLE = new Set(['imported', 'ready', 'not-ready', 'status-unknown']);
55
+
56
+ function postStableKey(postOrId) {
57
+ const id = postOrId && typeof postOrId === 'object' ? postOrId.id : postOrId;
58
+ if (id === undefined || id === null || id === '') throw new Error('blog-post-media: a post id is required');
59
+ return `wordpress:post:${String(id)}`;
60
+ }
61
+
62
+ function postTitle(post) {
63
+ const t = post && post.title;
64
+ if (typeof t === 'string') return t;
65
+ if (t && typeof t.rendered === 'string') return t.rendered;
66
+ return null;
67
+ }
68
+
69
+ // --- collection --------------------------------------------------------------------------
70
+
71
+ function collectRewriteKeys(richContent) {
72
+ const keys = [];
73
+ const visit = (node) => {
74
+ if (!node || typeof node !== 'object') return;
75
+ const url = node.imageData && node.imageData.image && node.imageData.image.src && node.imageData.image.src.url;
76
+ if (typeof url === 'string' && url !== '') keys.push(url);
77
+ (node.nodes || []).forEach(visit);
78
+ };
79
+ ((richContent && richContent.nodes) || []).forEach(visit);
80
+ return keys;
81
+ }
82
+
83
+ // The import URL for one rewrite key: WHATWG resolution against the post's permalink, so
84
+ // relative and protocol-relative sources become absolute. Anything that is not http(s) after
85
+ // that (data:, blob:, a relative key with no permalink, malformed) is unresolvable.
86
+ function resolveImportUrl(key, base) {
87
+ let url;
88
+ try {
89
+ url = base ? new URL(key, base) : new URL(key);
90
+ } catch {
91
+ return null;
92
+ }
93
+ return url.protocol === 'http:' || url.protocol === 'https:' ? url.toString() : null;
94
+ }
95
+
96
+ // What this post needs imported. Inline media are deduped by import URL: every rewrite key that
97
+ // resolves to the same URL (the same string twice, or a relative and an absolute form) shares one
98
+ // import and one file id. An unresolvable key is its own medium, already failed.
99
+ function collectPostMedia({ post, richContent }) {
100
+ const media = [];
101
+ const featuredId = post && post.featured_media;
102
+ if (featuredId !== undefined && featuredId !== null && String(featuredId) !== '' && String(featuredId) !== '0') {
103
+ media.push({ mediaKey: `featured:${String(featuredId)}`, kind: 'featured', wpMediaId: String(featuredId), sourceUrl: null, rewriteKeys: [] });
104
+ }
105
+ const byMediaKey = new Map();
106
+ for (const key of collectRewriteKeys(richContent)) {
107
+ const importUrl = resolveImportUrl(key, post && post.link);
108
+ const mediaKey = `inline:${importUrl || key}`;
109
+ let item = byMediaKey.get(mediaKey);
110
+ if (!item) {
111
+ item = { mediaKey, kind: 'inline', wpMediaId: null, sourceUrl: importUrl, rewriteKeys: [] };
112
+ if (!importUrl) item.unresolvable = true;
113
+ byMediaKey.set(mediaKey, item);
114
+ media.push(item);
115
+ }
116
+ if (!item.rewriteKeys.includes(key)) item.rewriteKeys.push(key);
117
+ }
118
+ return media;
119
+ }
120
+
121
+ // --- pending-media state (append-only, authoritative recovery record) -------------------
122
+ //
123
+ // migrations/<project>/state/crosswalk/pending-blog-media.ndjson. One row per state change; for a
124
+ // (sourceStableKey, mediaKey) the last row wins. A `resolved` row closes the post and later
125
+ // media rows for it are ignored. Crash discipline matches the pending-invoice file: split on the
126
+ // byte; a torn tail is truncated on disk before the next append; a complete unterminated last
127
+ // row is kept and terminated first; an unparsable line anywhere else throws as corruption.
128
+ //
129
+ // Recovery-log entry. A post that a rerun resolves after it had been pending owes one standard
130
+ // recovery-log entry. The `resolved` row records that debt (`recoveryOwed`) with a recoveryId and
131
+ // timestamp fixed at that moment; a later `recoveryLogged` row pays it. Until then every run that
132
+ // meets the post — normally through the crosswalk gate — re-checks the recovery log for that
133
+ // recoveryId and appends only if it is absent, then writes `recoveryLogged`. A crash (or a failed
134
+ // append) anywhere between the crosswalk row and `recoveryLogged` is therefore repaired by the
135
+ // next run, and never produces a second entry.
136
+ //
137
+ // `recovery` defaults to skills/wix-replatform/lib/import-recovery.js; tests may inject one with
138
+ // the same { loadRecoveryLog, appendRecoveryLogEntry } shape.
139
+ function createPendingBlogMediaState({ projectDir, recovery } = {}) {
140
+ if (!projectDir) throw new Error('createPendingBlogMediaState needs the migration projectDir');
141
+ const recoveryApi = () => recovery || require('../../../lib/import-recovery.js');
142
+ const filePath = path.join(projectDir, 'state', 'crosswalk', STATE_FILE);
143
+ let droppedPartialLine = null;
144
+
145
+ async function readRows() {
146
+ let buffer;
147
+ try {
148
+ buffer = await fs.readFile(filePath);
149
+ } catch (error) {
150
+ if (error && error.code === 'ENOENT') return { rows: [], needsTerminator: false };
151
+ throw error;
152
+ }
153
+ const lastNewline = buffer.lastIndexOf(0x0a);
154
+ const completeBytes = lastNewline === -1 ? 0 : lastNewline + 1;
155
+ const complete = completeBytes > 0 ? buffer.subarray(0, completeBytes).toString('utf8').split('\n') : [];
156
+ if (complete.length > 0) complete.pop();
157
+ const rows = [];
158
+ complete.forEach((raw, i) => {
159
+ const line = raw.replace(/\r$/, '').trim();
160
+ if (!line) return;
161
+ try { rows.push(JSON.parse(line)); } catch (error) { throw new Error(`${filePath}:${i + 1} invalid NDJSON: ${error.message}`); }
162
+ });
163
+ const tail = buffer.subarray(completeBytes).toString('utf8');
164
+ let needsTerminator = false;
165
+ if (tail.trim()) {
166
+ let row = null;
167
+ try { row = JSON.parse(tail.trim()); } catch { row = null; }
168
+ if (row) {
169
+ rows.push(row);
170
+ needsTerminator = true;
171
+ } else {
172
+ await fs.truncate(filePath, completeBytes);
173
+ droppedPartialLine = { line: complete.length + 1, length: tail.length };
174
+ }
175
+ }
176
+ return { rows, needsTerminator };
177
+ }
178
+
179
+ async function append(row) {
180
+ const { needsTerminator } = await readRows(); // repair first, so this append starts a clean line
181
+ await fs.mkdir(path.dirname(filePath), { recursive: true });
182
+ if (needsTerminator) await fs.appendFile(filePath, '\n', 'utf8');
183
+ await fs.appendFile(filePath, `${JSON.stringify({ schemaVersion: SCHEMA_VERSION, ...row, updatedAt: new Date().toISOString() })}\n`, 'utf8');
184
+ }
185
+
186
+ // Fold the file into { sourceStableKey -> { title, resolved, targetPostId, media: Map } }.
187
+ async function fold() {
188
+ const { rows } = await readRows();
189
+ const posts = new Map();
190
+ for (const row of rows) {
191
+ if (!row || typeof row.sourceStableKey !== 'string') continue;
192
+ let post = posts.get(row.sourceStableKey);
193
+ if (!post) {
194
+ post = {
195
+ sourceStableKey: row.sourceStableKey, title: null, resolved: false, targetPostId: null, media: new Map(),
196
+ recoveryOwed: false, recoveryId: null, resolvedAt: null, resolvedRunId: null, recoveryLogged: false,
197
+ };
198
+ posts.set(row.sourceStableKey, post);
199
+ }
200
+ if (row.recoveryLogged === true) {
201
+ if (post.resolved && row.recoveryId === post.recoveryId) post.recoveryLogged = true;
202
+ continue;
203
+ }
204
+ if (post.resolved) continue; // closed: later media rows are ignored
205
+ if (row.resolved === true) {
206
+ post.resolved = true;
207
+ post.targetPostId = row.targetPostId || null;
208
+ post.recoveryOwed = row.recoveryOwed === true;
209
+ post.recoveryId = row.recoveryId || null;
210
+ post.resolvedAt = row.resolvedAt || null;
211
+ post.resolvedRunId = row.resolvedRunId || null;
212
+ continue;
213
+ }
214
+ if (typeof row.mediaKey !== 'string') continue;
215
+ if (row.title) post.title = row.title;
216
+ post.media.set(row.mediaKey, row);
217
+ }
218
+ return posts;
219
+ }
220
+
221
+ async function postRecord(postOrId) {
222
+ return (await fold()).get(postStableKey(postOrId)) || null;
223
+ }
224
+
225
+ // Pay an owed recovery-log entry, idempotently: the entry is rebuilt from the `resolved` row,
226
+ // so its recoveryId is stable and an entry already in the log is not appended again.
227
+ async function settleRecoveryLog(record) {
228
+ if (!record || !record.resolved || !record.recoveryOwed || record.recoveryLogged) return false;
229
+ const api = recoveryApi();
230
+ const existing = api.recoveryEntriesOf ? api.recoveryEntriesOf(await api.loadRecoveryLog(projectDir)) : await api.loadRecoveryLog(projectDir);
231
+ if (!existing.some((entry) => entry && entry.recoveryId === record.recoveryId)) {
232
+ await api.appendRecoveryLogEntry(projectDir, buildBlogMediaRecoveryEntry({
233
+ runId: record.resolvedRunId,
234
+ sourceStableKey: record.sourceStableKey,
235
+ targetPostId: record.targetPostId,
236
+ recoveryId: record.recoveryId,
237
+ timestamp: record.resolvedAt,
238
+ }));
239
+ }
240
+ await append({ sourceStableKey: record.sourceStableKey, recoveryLogged: true, recoveryId: record.recoveryId });
241
+ return true;
242
+ }
243
+
244
+ async function close(postOrId, { targetPostId = null, runId = null, recoveryOwed = false } = {}) {
245
+ const key = postStableKey(postOrId);
246
+ let record = await postRecord(postOrId);
247
+ if (!record) return { closed: false, recoveryLogged: false }; // no media: never had a record
248
+ let closed = false;
249
+ if (!record.resolved) {
250
+ if (recoveryOwed && (typeof runId !== 'string' || runId === '')) {
251
+ throw new Error(`blog-post-media: closing ${key} owes a recovery-log entry, so a runId is required`);
252
+ }
253
+ const resolvedAt = new Date().toISOString();
254
+ const recoveryId = recoveryOwed
255
+ ? `recovery-blog-media-${crypto.createHash('sha256').update(`${key}|${resolvedAt}`).digest('hex').slice(0, 12)}`
256
+ : null;
257
+ await append({
258
+ sourceStableKey: key,
259
+ resolved: true,
260
+ targetPostId: targetPostId == null ? null : String(targetPostId),
261
+ recoveryOwed: Boolean(recoveryOwed),
262
+ recoveryId,
263
+ resolvedAt,
264
+ resolvedRunId: recoveryOwed ? runId : null,
265
+ });
266
+ closed = true;
267
+ record = await postRecord(postOrId);
268
+ }
269
+ return { closed, recoveryLogged: await settleRecoveryLog(record) };
270
+ }
271
+
272
+ return {
273
+ path: filePath,
274
+ readRows,
275
+ fold,
276
+ postRecord,
277
+ appendMedia: (row) => append(row),
278
+ // After the post write and its crosswalk row. `resumed` is importAndConfirmPostMedia's flag:
279
+ // a post that had been pending before this run owes a recovery-log entry, appended here.
280
+ markResolved: (postOrId, { targetPostId = null, runId = null, resumed = false } = {}) =>
281
+ close(postOrId, { targetPostId, runId, recoveryOwed: Boolean(resumed) }),
282
+ // The crosswalk gate skipped this post: it is written, but an earlier run stopped before
283
+ // closing its record or before paying its recovery-log entry. No media calls. An open record
284
+ // closed here is a rerun resolving a pending post, so it owes the entry.
285
+ closeIfCrosswalked: (postOrId, { targetPostId = null, runId = null } = {}) =>
286
+ close(postOrId, { targetPostId, runId, recoveryOwed: true }),
287
+ droppedPartialLine: () => droppedPartialLine,
288
+ };
289
+ }
290
+
291
+ // --- import and confirm ------------------------------------------------------------------
292
+
293
+ function mediaRow(post, item, outcome, { fileId = null, reason = null, sizeInBytes = null } = {}) {
294
+ if (!OUTCOMES.includes(outcome)) throw new Error(`blog-post-media: unknown outcome ${outcome}`);
295
+ return {
296
+ sourceStableKey: postStableKey(post),
297
+ title: postTitle(post),
298
+ mediaKey: item.mediaKey,
299
+ kind: item.kind,
300
+ wpMediaId: item.wpMediaId,
301
+ sourceUrl: item.sourceUrl,
302
+ rewriteKeys: item.rewriteKeys,
303
+ fileId: fileId == null ? null : String(fileId),
304
+ ...(sizeInBytes == null ? {} : { sizeInBytes: String(sizeInBytes) }),
305
+ outcome,
306
+ reason: reason == null ? null : String(reason).slice(0, 300),
307
+ };
308
+ }
309
+
310
+ function errorText(error) {
311
+ if (!error) return 'unknown error';
312
+ const status = error.status ? `${error.status} ` : '';
313
+ return `${status}${error.message || String(error)}`;
314
+ }
315
+
316
+ // Import every distinct medium of one post, settle every file in parallel, record each step.
317
+ // Returns { allReady, heroImageId, inlineBySourceUrl, items, resumed }. `resumed` is true when the
318
+ // post already had an open record from an earlier run (the caller's recovery-log trigger).
319
+ //
320
+ // Options: `state` from createPendingBlogMediaState; `fetchFeaturedMedia(id)` returns the
321
+ // WordPress `wp/v2/media/{id}` record (or a URL string, or null); `settle` is passed to
322
+ // waitUntilFileReady as { tries, delayMs }; `displayName` is optional.
323
+ async function importAndConfirmPostMedia(wix, { post, richContent, state, fetchFeaturedMedia, settle } = {}) {
324
+ if (!state) throw new Error('importAndConfirmPostMedia needs the pending-media state');
325
+ if (typeof fetchFeaturedMedia !== 'function') throw new Error('importAndConfirmPostMedia needs fetchFeaturedMedia(id)');
326
+ const record = await state.postRecord(post);
327
+ if (record && record.resolved) {
328
+ // Closed as written to `targetPostId`, yet the caller's crosswalk gate let it through. That is
329
+ // an inconsistency between two state files, not a media failure; guessing would either
330
+ // duplicate the post or write it without media. Stop and let the operator decide.
331
+ throw Object.assign(
332
+ new Error(`${postStableKey(post)} is recorded as written (Wix post ${record.targetPostId}) but is not in the crosswalk; repair the crosswalk before importing it again`),
333
+ { code: 'BLOG_MEDIA_STATE_INCONSISTENT' },
334
+ );
335
+ }
336
+ const prior = record ? record.media : new Map();
337
+ const items = collectPostMedia({ post, richContent });
338
+ const toSettle = [];
339
+
340
+ for (const item of items) {
341
+ const last = prior.get(item.mediaKey);
342
+ if (last && last.fileId && RESUMABLE.has(last.outcome)) {
343
+ if (item.kind === 'featured' && last.sourceUrl) item.sourceUrl = last.sourceUrl;
344
+ item.fileId = last.fileId;
345
+ if (last.outcome === 'ready' && (item.kind !== 'featured' || Number(last.sizeInBytes) > 0)) {
346
+ item.outcome = 'ready'; continue;
347
+ }
348
+ toSettle.push(item);
349
+ continue;
350
+ }
351
+ if (item.unresolvable) {
352
+ item.outcome = 'unresolvable-url';
353
+ item.reason = post && post.link ? 'not an http(s) URL' : 'relative URL and the post has no link to resolve it against';
354
+ await state.appendMedia(mediaRow(post, item, item.outcome, { reason: item.reason }));
355
+ continue;
356
+ }
357
+ if (item.kind === 'featured') {
358
+ let resolved = null;
359
+ try {
360
+ const got = await fetchFeaturedMedia(item.wpMediaId);
361
+ resolved = typeof got === 'string' ? got : (got ? resolveImageUrl(got) : null);
362
+ if (!resolved) item.reason = 'WordPress media record has no usable image URL';
363
+ } catch (error) {
364
+ item.reason = `fetching WordPress media ${item.wpMediaId} failed: ${errorText(error)}`;
365
+ }
366
+ const absolute = resolved ? resolveImportUrl(resolved, post && post.link) : null;
367
+ if (!absolute) {
368
+ item.outcome = 'fetch-failed';
369
+ if (resolved) item.reason = 'WordPress media URL is not an http(s) URL';
370
+ await state.appendMedia(mediaRow(post, item, item.outcome, { reason: item.reason }));
371
+ continue;
372
+ }
373
+ item.sourceUrl = absolute;
374
+ }
375
+ let file;
376
+ try {
377
+ file = await writers.importMedia(wix, {
378
+ sourceUrl: item.sourceUrl,
379
+ displayName: displayNameFor(item.sourceUrl),
380
+ mediaType: 'IMAGE',
381
+ wpId: item.wpMediaId != null ? item.wpMediaId : undefined,
382
+ });
383
+ } catch (error) {
384
+ item.outcome = 'import-rejected';
385
+ item.reason = errorText(error);
386
+ await state.appendMedia(mediaRow(post, item, item.outcome, { reason: item.reason }));
387
+ continue;
388
+ }
389
+ if (!file || !file.id) {
390
+ item.outcome = 'import-rejected';
391
+ item.reason = 'import response carried no file id';
392
+ await state.appendMedia(mediaRow(post, item, item.outcome, { reason: item.reason }));
393
+ continue;
394
+ }
395
+ item.fileId = String(file.id);
396
+ // Checkpoint BEFORE polling: a crash from here on resumes this id instead of importing again.
397
+ await state.appendMedia(mediaRow(post, item, 'imported', { fileId: item.fileId }));
398
+ toSettle.push(item);
399
+ }
400
+
401
+ const settled = await Promise.all(toSettle.map(async (item) => {
402
+ try {
403
+ const ready = await writers.waitUntilFileReady(wix, item.fileId, settle || {});
404
+ if (ready && (item.kind !== 'featured' || Number(ready.sizeInBytes) > 0))
405
+ return { item, outcome: 'ready', sizeInBytes: ready.sizeInBytes };
406
+ if (ready && item.kind === 'featured')
407
+ return { item, outcome: 'not-ready', reason: 'cover is READY but has no non-zero sizeInBytes' };
408
+ return { item, outcome: 'not-ready', reason: 'still PENDING when the settle window ended' };
409
+ } catch (error) {
410
+ if (error && error.code === 'MEDIA_IMPORT_FAILED') return { item, outcome: 'failed', reason: 'Wix reported the import FAILED' };
411
+ return { item, outcome: 'status-unknown', reason: `reading the file status failed: ${errorText(error)}` };
412
+ }
413
+ }));
414
+ for (const { item, outcome, reason, sizeInBytes } of settled) {
415
+ item.outcome = outcome;
416
+ item.reason = reason || null;
417
+ if (outcome === 'failed') item.fileId = null; // a FAILED file is imported afresh next time
418
+ await state.appendMedia(mediaRow(post, item, outcome,
419
+ { fileId: item.fileId, reason: item.reason, sizeInBytes }));
420
+ }
421
+
422
+ const allReady = items.every((item) => item.outcome === 'ready');
423
+ const featured = items.find((item) => item.kind === 'featured');
424
+ const inlineBySourceUrl = new Map();
425
+ for (const item of items) {
426
+ if (item.kind === 'inline' && item.outcome === 'ready') {
427
+ for (const key of item.rewriteKeys) inlineBySourceUrl.set(key, item.fileId);
428
+ }
429
+ }
430
+ return {
431
+ allReady,
432
+ heroImageId: featured && featured.outcome === 'ready' ? featured.fileId : null,
433
+ inlineBySourceUrl,
434
+ items: items.map(({ unresolvable, ...rest }) => ({ ...rest, fileId: rest.fileId || null, reason: rest.reason || null })),
435
+ resumed: Boolean(record),
436
+ };
437
+ }
438
+
439
+ function displayNameFor(url) {
440
+ try {
441
+ const last = new URL(url).pathname.split('/').filter(Boolean).pop();
442
+ return last ? decodeURIComponent(last) : undefined;
443
+ } catch {
444
+ return undefined;
445
+ }
446
+ }
447
+
448
+ // Rewrite the inline images of the SAME converted document. Only for an allReady result: a
449
+ // partial rewrite is the unapproved fallback.
450
+ function applyPostMedia(richContent, result) {
451
+ if (!result || !result.allReady) throw new Error('applyPostMedia: only an allReady media result may be applied to a post');
452
+ return writers.rewriteInlineMedia(richContent, result.inlineBySourceUrl);
453
+ }
454
+
455
+ // Crosswalk hits must still enter the build runner for legacy reconciliation, but
456
+ // must not re-import media or close pending state before Wix identity is checked.
457
+ // Prefer the existing media ledger; a pre-ledger import supplies its local media
458
+ // crosswalk through resolveFromCrosswalk without making a new Wix media write.
459
+ async function existingPostMedia({ post, richContent, state, resolveFromCrosswalk } = {}) {
460
+ if (!state) throw new Error('existingPostMedia needs pending-media state');
461
+ const needed = collectPostMedia({ post, richContent });
462
+ if (!needed.length) return { allReady: true, heroImageId: null,
463
+ inlineBySourceUrl: new Map(), resumed: false, items: [] };
464
+ const record = await state.postRecord(post);
465
+ const local = record?.media;
466
+ const resolved = [];
467
+ for (const item of needed) {
468
+ let row = local?.get(item.mediaKey);
469
+ if ((!row || row.outcome !== 'ready' || !row.fileId ||
470
+ item.kind === 'featured' && !(Number(row.sizeInBytes) > 0)) &&
471
+ typeof resolveFromCrosswalk === 'function') row = await resolveFromCrosswalk(post, item);
472
+ if (!row || row.outcome !== 'ready' || !row.fileId ||
473
+ item.kind === 'featured' && !(Number(row.sizeInBytes) > 0)) {
474
+ throw Object.assign(
475
+ new Error(`blog legacy crosswalk ${postStableKey(post)} lacks confirmed READY media ${item.mediaKey}`),
476
+ { code: 'BLOG_LEGACY_MEDIA_UNRESOLVED' });
477
+ }
478
+ resolved.push({ ...item, fileId: String(row.fileId), outcome: 'ready' });
479
+ }
480
+ const inlineBySourceUrl = new Map();
481
+ for (const item of resolved.filter(value => value.kind === 'inline'))
482
+ for (const key of item.rewriteKeys) inlineBySourceUrl.set(key, item.fileId);
483
+ return { allReady: true,
484
+ heroImageId: resolved.find(item => item.kind === 'featured')?.fileId || null,
485
+ inlineBySourceUrl, resumed: Boolean(record && !record.resolved), items: resolved };
486
+ }
487
+
488
+ // --- report ------------------------------------------------------------------------------
489
+
490
+ function isCrosswalked(crosswalk, key) {
491
+ if (!crosswalk) return false;
492
+ if (typeof crosswalk === 'function') return Boolean(crosswalk(key));
493
+ if (typeof crosswalk.has === 'function') return crosswalk.has(key);
494
+ return false;
495
+ }
496
+
497
+ // Derived from the state file, never kept as a separate list. A post is pending when its record
498
+ // is open and it is not in the crosswalk — including when every medium is already READY but the
499
+ // post write was never recorded (`awaitingWrite`: a run stopped between the last READY row and
500
+ // the crosswalk row). `recoveryLogOwed` lists written posts whose recovery-log entry is not yet
501
+ // confirmed; the next run's crosswalk gate pays it. `crosswalk` is a Set/Map of sourceStableKeys
502
+ // or a function(sourceStableKey) -> truthy.
503
+ async function summarizePendingBlogMedia({ state, crosswalk } = {}) {
504
+ if (!state) throw new Error('summarizePendingBlogMedia needs the pending-media state');
505
+ const pending = [];
506
+ const recoveryLogOwed = [];
507
+ for (const post of (await state.fold()).values()) {
508
+ if (post.resolved) {
509
+ if (post.recoveryOwed && !post.recoveryLogged) recoveryLogOwed.push({ sourceStableKey: post.sourceStableKey, targetPostId: post.targetPostId, recoveryId: post.recoveryId });
510
+ continue;
511
+ }
512
+ if (isCrosswalked(crosswalk, post.sourceStableKey)) continue;
513
+ const media = [...post.media.values()]
514
+ .filter((row) => row.outcome !== 'ready')
515
+ .map((row) => ({ mediaKey: row.mediaKey, kind: row.kind, outcome: row.outcome, reason: row.reason || null, wpMediaId: row.wpMediaId || null, sourceUrl: row.sourceUrl || null, fileId: row.fileId || null }));
516
+ const awaitingWrite = media.length === 0;
517
+ pending.push({
518
+ sourceStableKey: post.sourceStableKey,
519
+ title: post.title,
520
+ awaitingWrite,
521
+ reason: awaitingWrite ? 'every medium is READY; the post write was not recorded — the next run writes it' : null,
522
+ media,
523
+ });
524
+ }
525
+ return { pendingMedia: pending.length, pending, recoveryLogOwed, statePath: 'state/crosswalk/pending-blog-media.ndjson' };
526
+ }
527
+
528
+ // The standard recovery-log entry for a post a rerun resolved after it had been pending. The
529
+ // state's markResolved / closeIfCrosswalked append it; callers do not.
530
+ function buildBlogMediaRecoveryEntry({ runId, post, sourceStableKey, targetPostId, recoveryId, timestamp, crosswalkChanges = { added: 1, updated: 0 } }) {
531
+ const key = sourceStableKey || postStableKey(post);
532
+ return {
533
+ ...(recoveryId ? { recoveryId } : {}),
534
+ ...(timestamp ? { timestamp } : {}),
535
+ runId,
536
+ mode: 'resumed',
537
+ status: 'complete',
538
+ reason: 'blog_post_media_resolved',
539
+ selectionFilters: { entity: 'blog-post', sourceStableKey: key },
540
+ recordsSelected: 1,
541
+ recordsAttempted: 1,
542
+ imported: 1,
543
+ alreadyPresent: 0,
544
+ failed: 0,
545
+ deferred: 0,
546
+ unresolved: 0,
547
+ crosswalkChanges,
548
+ summaryChanges: { blogPostsPendingMedia: -1, blogPostsImported: 1 },
549
+ outcome: `blog post ${key} resolved as Wix post ${targetPostId} after its media reached READY`,
550
+ logs: ['state/crosswalk/pending-blog-media.ndjson'],
551
+ };
552
+ }
553
+
554
+ module.exports = {
555
+ SCHEMA_VERSION,
556
+ STATE_FILE,
557
+ OUTCOMES,
558
+ postStableKey,
559
+ collectPostMedia,
560
+ resolveImportUrl,
561
+ createPendingBlogMediaState,
562
+ importAndConfirmPostMedia,
563
+ applyPostMedia,
564
+ existingPostMedia,
565
+ summarizePendingBlogMedia,
566
+ buildBlogMediaRecoveryEntry,
567
+ };
@@ -0,0 +1,73 @@
1
+ 'use strict';
2
+
3
+ const { opaqueId, contactId } = require('../../../lib/entity-verification');
4
+ // These selectors belong to inspected endpoint contracts, not to bulk APIs in general.
5
+ const selectors = { index: r => r?.itemMetadata?.originalIndex, success: r => r?.itemMetadata?.success };
6
+ const adapters = Object.freeze({
7
+ contacts: { ...selectors, envelope: r => r, validId: contactId },
8
+ products: { ...selectors, envelope: r => r?.productResults, validId: opaqueId },
9
+ inventory: { ...selectors, envelope: r => r, validId: null },
10
+ });
11
+
12
+ function correlateBulk(response, inputs, adapter) {
13
+ if (!adapter || !Object.values(adapters).includes(adapter)) throw new Error('An inspected endpoint adapter is required');
14
+ const envelope = adapter.envelope(response);
15
+ const defects = [];
16
+ const raw = Array.isArray(envelope?.results) ? envelope.results : [];
17
+ if (!Array.isArray(envelope?.results)) defects.push('invalid-envelope');
18
+ const meta = envelope?.bulkActionMetadata;
19
+ if (meta != null && (typeof meta !== 'object' || Array.isArray(meta))) defects.push('invalid-metadata');
20
+ const indexes = new Map(), ids = new Map();
21
+ for (const r of raw) {
22
+ const index = adapter.index(r);
23
+ indexes.set(index, (indexes.get(index) || 0) + 1);
24
+ if (adapter.success(r) === true && r?.itemMetadata?.id) ids.set(r.itemMetadata.id, (ids.get(r.itemMetadata.id) || 0) + 1);
25
+ }
26
+ const reportedSuccesses = raw.filter(r => adapter.success(r) === true).length;
27
+ const reportedFailures = raw.filter(r => adapter.success(r) === false).length;
28
+ for (const key of ['totalSuccesses', 'totalFailures', 'undetailedFailures']) {
29
+ if (meta?.[key] !== undefined && (!Number.isInteger(meta[key]) || meta[key] < 0 || meta[key] > inputs.length)) defects.push(`invalid-${key}`);
30
+ }
31
+ const undetailedFailures = Number.isInteger(meta?.undetailedFailures) && meta.undetailedFailures >= 0 ? meta.undetailedFailures : 0;
32
+ if (meta?.totalSuccesses !== undefined && meta.totalSuccesses !== reportedSuccesses) defects.push('inconsistent-successes');
33
+ if (meta?.totalFailures !== undefined && meta.totalFailures !== reportedFailures + undetailedFailures) defects.push('inconsistent-failures');
34
+ if (raw.length + undetailedFailures > inputs.length) defects.push('excess-results');
35
+ const globalInvalid = defects.length > 0;
36
+ const results = raw.map(r => {
37
+ const index = adapter.index(r), metadata = r?.itemMetadata || {};
38
+ const errors = [];
39
+ if (!Number.isInteger(index) || index < 0 || index >= inputs.length) errors.push('invalid-index');
40
+ else if (indexes.get(index) !== 1) errors.push('duplicate-index');
41
+ if (typeof adapter.success(r) !== 'boolean') errors.push('invalid-success');
42
+ if (adapter.validId && adapter.success(r) === true) {
43
+ if (!adapter.validId(metadata.id) || r?.item?._dryRunPlaceholder) errors.push('invalid-id');
44
+ if (r?.item?.id !== undefined && r.item.id !== metadata.id) errors.push('conflicting-id');
45
+ if (ids.get(metadata.id) > 1) errors.push('duplicate-target-id');
46
+ }
47
+ const correlated = !globalInvalid && errors.length === 0;
48
+ defects.push(...errors.map(code => `${code}:${String(index)}`));
49
+ return { index, input: Number.isInteger(index) ? inputs[index] : undefined, raw: r,
50
+ correlated, success: correlated && adapter.success(r) === true,
51
+ errorCode: errors[0] || (globalInvalid ? 'invalid-bulk-metadata' : metadata.error?.code) || null,
52
+ errorDescription: metadata.error?.description || null };
53
+ });
54
+ const accounted = new Set(results.filter(r => r.correlated).map(r => r.index));
55
+ const unresolvedIndexes = inputs.map((_, i) => i).filter(i => !accounted.has(i));
56
+ return { results, defects, unresolvedIndexes, unaccounted: unresolvedIndexes.length, undetailedFailures,
57
+ totalSuccesses: reportedSuccesses, totalFailures: reportedFailures + undetailedFailures };
58
+ }
59
+
60
+ function normalizeBulk(response, inputs, kind) {
61
+ const out = correlateBulk(response, inputs, adapters[kind]);
62
+ const contact = kind === 'contacts';
63
+ out.results = out.results.map(({ raw, input, ...r }) => ({ ...r,
64
+ [contact ? 'inputContact' : 'inputProduct']: input,
65
+ [contact ? 'contactId' : 'productId']: raw?.itemMetadata?.id || null,
66
+ [contact ? 'contact' : 'product']: raw?.item || null,
67
+ ...(contact ? { action: raw?.action || null } : { revision: raw?.item?.revision || null }),
68
+ }));
69
+ out.succeeded = out.results.filter(r => r.success);
70
+ out.failed = out.results.filter(r => !r.success);
71
+ return out;
72
+ }
73
+ module.exports = { adapters, correlateBulk, normalizeBulk, opaqueId, contactId };