@wix/agent-skills 1.35.1 → 1.36.1

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 (820) hide show
  1. package/package.json +8 -3
  2. package/skills/wix-app/references/CODE_QUALITY.md +1 -1
  3. package/skills/wix-app/references/EDITOR_REACT_COMPONENT.md +27 -29
  4. package/skills/wix-app/references/editor-react-component/ANIMATED-COMPONENTS.md +1 -1
  5. package/skills/wix-app/references/editor-react-component/COMPONENT-CONTRACT.md +26 -25
  6. package/skills/wix-app/references/editor-react-component/CSS-GUIDELINES.md +12 -42
  7. package/skills/wix-app/references/editor-react-component/DESIGN-STATES.md +9 -20
  8. package/skills/wix-app/references/editor-react-component/MANIFEST-ERRORS.md +5 -4
  9. package/skills/wix-app/references/editor-react-component/PARTS.md +1 -1
  10. package/skills/wix-app/references/editor-react-component/PROPS-VS-CSS.md +1 -1
  11. package/skills/wix-app/references/editor-react-component/VECTOR-ART.md +95 -0
  12. package/skills/wix-app/references/editor-react-component/VISUAL-QUALITY.md +39 -0
  13. package/skills/wix-docs/references/CALLING.md +1 -1
  14. package/skills/wix-headless-kit/guides/api-run.md +1 -1
  15. package/skills/wix-headless-kit/install/pins.json +1 -1
  16. package/skills/wix-headless-templates/blog/seed/seed-blog.mjs +1 -1
  17. package/skills/wix-headless-templates/donations/app/wix/donations/campaigns.ts +0 -1
  18. package/skills/wix-headless-templates/donations/app/wix/donations/donate.ts +1 -1
  19. package/skills/wix-headless-templates/donations/project/src/wix/donations/campaigns.ts +0 -1
  20. package/skills/wix-headless-templates/donations/project/src/wix/donations/donate.ts +1 -1
  21. package/skills/wix-headless-templates/donations/rest/campaigns.ts +0 -1
  22. package/skills/wix-headless-templates/donations/rest/donate.ts +1 -1
  23. package/skills/wix-headless-templates/events/seed/seed-events.mjs +1 -1
  24. package/skills/wix-headless-templates/faq/INSTRUCTIONS.md +1 -1
  25. package/skills/wix-headless-templates/faq/app/wix/faq/faq.ts +2 -2
  26. package/skills/wix-headless-templates/faq/project/src/wix/faq/faq.ts +2 -2
  27. package/skills/wix-headless-templates/faq/rest/faq.ts +2 -2
  28. package/skills/wix-headless-templates/faq/seed/SEED.md +1 -1
  29. package/skills/wix-headless-templates/faq/seed/read-site.mjs +1 -1
  30. package/skills/wix-headless-templates/faq/seed/seed-faq.mjs +5 -5
  31. package/skills/wix-headless-templates/forms/app/wix/forms/forms.ts +2 -2
  32. package/skills/wix-headless-templates/forms/app/wix/forms/submissions.ts +2 -2
  33. package/skills/wix-headless-templates/forms/project/src/wix/forms/forms.ts +2 -2
  34. package/skills/wix-headless-templates/forms/project/src/wix/forms/submissions.ts +2 -2
  35. package/skills/wix-headless-templates/members/seed/read-site.mjs +1 -1
  36. package/skills/wix-headless-templates/pricing-plans/app/wix/pricing-plans/plan-access.ts +1 -1
  37. package/skills/wix-headless-templates/pricing-plans/project/src/wix/pricing-plans/plan-access.ts +1 -1
  38. package/skills/wix-headless-templates/pricing-plans/rest/plan-access.ts +1 -1
  39. package/skills/wix-headless-templates/restaurants/app/wix/restaurants/menu.ts +0 -1
  40. package/skills/wix-headless-templates/restaurants/project/src/wix/restaurants/menu.ts +0 -1
  41. package/skills/wix-headless-templates/restaurants/rest/menu.ts +0 -1
  42. package/skills/wix-headless-templates/shared/rest/client.ts +1 -1
  43. package/skills/wix-headless-templates/shared/seed/site.mjs +2 -1
  44. package/skills/wix-manage/SKILL.md +3 -3
  45. package/skills/wix-manage/references/cms/cms-data-items-crud.md +78 -1
  46. package/skills/wix-manage/references/google-ads/create-performance-max-campaign.md +11 -11
  47. package/skills/wix-manage/references/google-ads/get-campaign-suggestions.md +0 -1
  48. package/skills/wix-manage/references/google-ads/install-and-create-account.md +0 -1
  49. package/skills/wix-manage/references/marketing/create-and-publish-social-post.md +20 -51
  50. package/skills/wix-manage/references/marketing/generate-and-publish-marketing-plan.md +4 -4
  51. package/skills/wix-manage/references/rich-content/ricos-converter-service.md +1 -1
  52. package/skills/wix-base44-connector/SKILL.md +0 -437
  53. package/skills/wix-base44-connector/references/CAPABILITY_MAP.md +0 -78
  54. package/skills/wix-base44-connector/scripts/utils.cjs +0 -466
  55. package/skills/wix-export/SKILL.md +0 -83
  56. package/skills/wix-harmony-editor/.publish-manifest.json +0 -8
  57. package/skills/wix-harmony-editor/COPY-SITE.md +0 -494
  58. package/skills/wix-harmony-editor/SKILL.md +0 -317
  59. package/skills/wix-harmony-editor/scripts/copy/build-description.mjs +0 -249
  60. package/skills/wix-harmony-editor/scripts/copy/check-description.mjs +0 -225
  61. package/skills/wix-harmony-editor/scripts/copy/check-mirror.mjs +0 -89
  62. package/skills/wix-harmony-editor/scripts/copy/compare-preview.mjs +0 -76
  63. package/skills/wix-harmony-editor/scripts/copy/deploy-description.mjs +0 -212
  64. package/skills/wix-harmony-editor/scripts/copy/desc-hash.mjs +0 -44
  65. package/skills/wix-harmony-editor/scripts/copy/editor-run.mjs +0 -45
  66. package/skills/wix-harmony-editor/scripts/copy/export-page.mjs +0 -53
  67. package/skills/wix-harmony-editor/scripts/copy/find-interactions.mjs +0 -76
  68. package/skills/wix-harmony-editor/scripts/copy/hide-scrollbars.mjs +0 -16
  69. package/skills/wix-harmony-editor/scripts/copy/import-media.mjs +0 -150
  70. package/skills/wix-harmony-editor/scripts/copy/link-url.mjs +0 -27
  71. package/skills/wix-harmony-editor/scripts/copy/lint-api.mjs +0 -56
  72. package/skills/wix-harmony-editor/scripts/copy/measure-source.mjs +0 -211
  73. package/skills/wix-harmony-editor/scripts/copy/merge-mirrors.mjs +0 -29
  74. package/skills/wix-harmony-editor/scripts/copy/mirror-site.mjs +0 -92
  75. package/skills/wix-harmony-editor/scripts/copy/mobile-stage.mjs +0 -56
  76. package/skills/wix-harmony-editor/scripts/copy/preview-widths.mjs +0 -73
  77. package/skills/wix-harmony-editor/scripts/copy/render-plate.mjs +0 -67
  78. package/skills/wix-harmony-editor/scripts/copy/serve-mirror.mjs +0 -102
  79. package/skills/wix-harmony-editor/scripts/copy/snapshot-capabilities.mjs +0 -40
  80. package/skills/wix-harmony-editor/scripts/copy/split-sections.mjs +0 -191
  81. package/skills/wix-harmony-editor/scripts/copy/upload-media-manager.mjs +0 -61
  82. package/skills/wix-harmony-editor/scripts/launch.sh +0 -359
  83. package/skills/wix-headless/SKILL.md +0 -151
  84. package/skills/wix-headless/references/AI_FEATURES.md +0 -178
  85. package/skills/wix-headless/references/CAPABILITIES.md +0 -117
  86. package/skills/wix-headless/references/CONTENT.md +0 -36
  87. package/skills/wix-headless/references/DESIGN.md +0 -55
  88. package/skills/wix-headless/references/DISCOVERY.md +0 -80
  89. package/skills/wix-headless/references/DOC_DISCOVERY.md +0 -43
  90. package/skills/wix-headless/references/FEEDBACK.md +0 -129
  91. package/skills/wix-headless/references/IMAGE_GENERATION.md +0 -80
  92. package/skills/wix-headless/references/SDK_HANDOFF.md +0 -108
  93. package/skills/wix-headless/references/SEED.md +0 -74
  94. package/skills/wix-headless/references/SETUP.md +0 -60
  95. package/skills/wix-headless/references/astro.md +0 -98
  96. package/skills/wix-headless/references/inline-recipes/experience-donations.md +0 -102
  97. package/skills/wix-headless/references/inline-recipes/experience-store.md +0 -49
  98. package/skills/wix-headless/references/inline-recipes/how-to-code-a-blog.md +0 -196
  99. package/skills/wix-headless/references/inline-recipes/how-to-code-a-store.md +0 -590
  100. package/skills/wix-headless/references/inline-recipes/how-to-code-bookings.md +0 -279
  101. package/skills/wix-headless/references/inline-recipes/how-to-code-cms.md +0 -163
  102. package/skills/wix-headless/references/inline-recipes/how-to-code-donations.md +0 -146
  103. package/skills/wix-headless/references/inline-recipes/how-to-code-events.md +0 -203
  104. package/skills/wix-headless/references/inline-recipes/how-to-code-forms.md +0 -696
  105. package/skills/wix-headless/references/inline-recipes/how-to-code-members-astro.md +0 -124
  106. package/skills/wix-headless/references/inline-recipes/how-to-code-members-custom-login.md +0 -160
  107. package/skills/wix-headless/references/inline-recipes/how-to-code-members-non-astro.md +0 -118
  108. package/skills/wix-headless/references/inline-recipes/how-to-code-portfolio.md +0 -132
  109. package/skills/wix-headless/references/inline-recipes/how-to-code-pricing-plans.md +0 -126
  110. package/skills/wix-headless/references/inline-recipes/how-to-code-rentals.md +0 -254
  111. package/skills/wix-headless/references/inline-recipes/how-to-code-restaurant-orders.md +0 -191
  112. package/skills/wix-headless/references/inline-recipes/how-to-code-restaurant-reservations.md +0 -213
  113. package/skills/wix-headless/references/inline-recipes/how-to-code-restaurants.md +0 -161
  114. package/skills/wix-headless/references/inline-recipes/setup-blog.md +0 -175
  115. package/skills/wix-headless/references/inline-recipes/setup-bookings.md +0 -232
  116. package/skills/wix-headless/references/inline-recipes/setup-cms.md +0 -200
  117. package/skills/wix-headless/references/inline-recipes/setup-donations.md +0 -15
  118. package/skills/wix-headless/references/inline-recipes/setup-events.md +0 -196
  119. package/skills/wix-headless/references/inline-recipes/setup-forms.md +0 -288
  120. package/skills/wix-headless/references/inline-recipes/setup-online-store.md +0 -214
  121. package/skills/wix-headless/references/inline-recipes/setup-portfolio.md +0 -155
  122. package/skills/wix-headless/references/inline-recipes/setup-pricing-plans.md +0 -229
  123. package/skills/wix-headless/references/inline-recipes/setup-rentals.md +0 -254
  124. package/skills/wix-headless/references/inline-recipes/setup-restaurant-experiences.md +0 -73
  125. package/skills/wix-headless/references/inline-recipes/setup-restaurant-orders.md +0 -197
  126. package/skills/wix-headless/references/inline-recipes/setup-restaurant-reservations.md +0 -136
  127. package/skills/wix-headless/references/inline-recipes/setup-restaurants.md +0 -152
  128. package/skills/wix-headless/references/managed/AUTHENTICATION.md +0 -71
  129. package/skills/wix-headless/references/managed/CONNECT.md +0 -74
  130. package/skills/wix-headless/references/managed/CREATE.md +0 -149
  131. package/skills/wix-headless/references/managed/DEPLOYMENT.md +0 -104
  132. package/skills/wix-headless/references/non-astro.md +0 -59
  133. package/skills/wix-headless/references/self-managed/AUTHENTICATION.md +0 -22
  134. package/skills/wix-headless/references/self-managed/DEPLOYMENT.md +0 -15
  135. package/skills/wix-headless/references/stripe/AUTHENTICATION.md +0 -55
  136. package/skills/wix-headless/references/stripe/DEPLOYMENT.md +0 -71
  137. package/skills/wix-headless/scripts/bootstrap.mjs +0 -156
  138. package/skills/wix-headless-replatform/.publish-manifest.json +0 -8
  139. package/skills/wix-headless-replatform/SKILL.md +0 -116
  140. package/skills/wix-headless-replatform/agents/openai.yaml +0 -6
  141. package/skills/wix-headless-replatform/references/control-and-visual-fidelity-contract.md +0 -43
  142. package/skills/wix-headless-replatform/references/extraction-schema.md +0 -187
  143. package/skills/wix-headless-replatform/references/interaction-runtime-contract.md +0 -137
  144. package/skills/wix-headless-replatform/references/layout-blueprint-contract.md +0 -41
  145. package/skills/wix-headless-replatform/references/output-contract.md +0 -93
  146. package/skills/wix-headless-replatform/references/post-build-gap-contract.md +0 -125
  147. package/skills/wix-headless-replatform/references/qa-checklist.md +0 -83
  148. package/skills/wix-headless-replatform/references/safety.md +0 -19
  149. package/skills/wix-headless-replatform/references/ui-normalization-contract.md +0 -70
  150. package/skills/wix-headless-replatform/references/workflow.md +0 -157
  151. package/skills/wix-headless-replatform/registry/README.md +0 -20
  152. package/skills/wix-headless-replatform/registry/approvals/button/shadcn-default-ac60ef5.json +0 -28
  153. package/skills/wix-headless-replatform/registry/items/button/shadcn-default-ac60ef5/button.tsx +0 -54
  154. package/skills/wix-headless-replatform/registry/items/button/shadcn-default-ac60ef5/capabilities.json +0 -60
  155. package/skills/wix-headless-replatform/registry/items/button/shadcn-default-ac60ef5/contract.md +0 -48
  156. package/skills/wix-headless-replatform/registry/licenses/shadcn-ui-ac60ef5-MIT.txt +0 -21
  157. package/skills/wix-headless-replatform/registry/registry.json +0 -36
  158. package/skills/wix-headless-replatform/resources/rp-facelift/SKILL.md +0 -32
  159. package/skills/wix-headless-replatform/resources/rp-project-context/SKILL.md +0 -62
  160. package/skills/wix-headless-replatform/resources/rp-qa-gap-loop/SKILL.md +0 -64
  161. package/skills/wix-headless-replatform/resources/rp-source-evidence/SKILL.md +0 -42
  162. package/skills/wix-headless-replatform/resources/rp-ui-implementation/SKILL.md +0 -73
  163. package/skills/wix-headless-replatform/schemas/build-plan.schema.json +0 -10
  164. package/skills/wix-headless-replatform/schemas/candidate.schema.json +0 -19
  165. package/skills/wix-headless-replatform/schemas/common.schema.json +0 -33
  166. package/skills/wix-headless-replatform/schemas/decision-patch.schema.json +0 -10
  167. package/skills/wix-headless-replatform/schemas/decision-request.schema.json +0 -10
  168. package/skills/wix-headless-replatform/schemas/extraction-gap.schema.json +0 -28
  169. package/skills/wix-headless-replatform/schemas/extraction-manifest.schema.json +0 -34
  170. package/skills/wix-headless-replatform/schemas/final-report.schema.json +0 -10
  171. package/skills/wix-headless-replatform/schemas/foundation.schema.json +0 -11
  172. package/skills/wix-headless-replatform/schemas/metadata.schema.json +0 -11
  173. package/skills/wix-headless-replatform/schemas/observation-packet.schema.json +0 -17
  174. package/skills/wix-headless-replatform/schemas/page-capture.schema.json +0 -11
  175. package/skills/wix-headless-replatform/schemas/page-resolution.schema.json +0 -33
  176. package/skills/wix-headless-replatform/schemas/shared-chrome.schema.json +0 -11
  177. package/skills/wix-headless-replatform/schemas/unit.schema.json +0 -40
  178. package/skills/wix-headless-replatform/scripts/assemble-extraction.mjs +0 -844
  179. package/skills/wix-headless-replatform/scripts/benchmark-extraction.mjs +0 -163
  180. package/skills/wix-headless-replatform/scripts/browser-extraction-preflight.mjs +0 -42
  181. package/skills/wix-headless-replatform/scripts/build-extracted-homepage.mjs +0 -228
  182. package/skills/wix-headless-replatform/scripts/clear-wix-starter.mjs +0 -87
  183. package/skills/wix-headless-replatform/scripts/create-wix-project.mjs +0 -505
  184. package/skills/wix-headless-replatform/scripts/discover-urls.mjs +0 -142
  185. package/skills/wix-headless-replatform/scripts/extract-assets.mjs +0 -140
  186. package/skills/wix-headless-replatform/scripts/extract-design-system.mjs +0 -637
  187. package/skills/wix-headless-replatform/scripts/extract-interactions.mjs +0 -1903
  188. package/skills/wix-headless-replatform/scripts/extract-page.mjs +0 -2461
  189. package/skills/wix-headless-replatform/scripts/extract-seo.mjs +0 -25
  190. package/skills/wix-headless-replatform/scripts/extract-tokens.mjs +0 -63
  191. package/skills/wix-headless-replatform/scripts/finalize-extraction-report.mjs +0 -126
  192. package/skills/wix-headless-replatform/scripts/finalize-gap-review.mjs +0 -180
  193. package/skills/wix-headless-replatform/scripts/finalize-gap-review.test.mjs +0 -98
  194. package/skills/wix-headless-replatform/scripts/finalize-migration-website.mjs +0 -103
  195. package/skills/wix-headless-replatform/scripts/generate-control-state-contract.mjs +0 -176
  196. package/skills/wix-headless-replatform/scripts/generate-design-md.mjs +0 -261
  197. package/skills/wix-headless-replatform/scripts/generate-extraction-validators.mjs +0 -25
  198. package/skills/wix-headless-replatform/scripts/generate-invoice-download-backend.mjs +0 -342
  199. package/skills/wix-headless-replatform/scripts/generate-layout-blueprint.mjs +0 -140
  200. package/skills/wix-headless-replatform/scripts/generate-repeater-cms.mjs +0 -22
  201. package/skills/wix-headless-replatform/scripts/generate-route-plan.mjs +0 -143
  202. package/skills/wix-headless-replatform/scripts/generate-scene-contract.mjs +0 -288
  203. package/skills/wix-headless-replatform/scripts/generate-ui-normalization.mjs +0 -266
  204. package/skills/wix-headless-replatform/scripts/generate-visual-assets.mjs +0 -111
  205. package/skills/wix-headless-replatform/scripts/lib/browser-tooling.mjs +0 -570
  206. package/skills/wix-headless-replatform/scripts/lib/common.mjs +0 -329
  207. package/skills/wix-headless-replatform/scripts/lib/component-capabilities.mjs +0 -121
  208. package/skills/wix-headless-replatform/scripts/lib/component-registry.mjs +0 -282
  209. package/skills/wix-headless-replatform/scripts/lib/content-boundary.mjs +0 -61
  210. package/skills/wix-headless-replatform/scripts/lib/extraction-contract.mjs +0 -374
  211. package/skills/wix-headless-replatform/scripts/lib/extraction-detectors.mjs +0 -243
  212. package/skills/wix-headless-replatform/scripts/lib/extraction-validators.generated.mjs +0 -1139
  213. package/skills/wix-headless-replatform/scripts/lib/font-contract.mjs +0 -326
  214. package/skills/wix-headless-replatform/scripts/lib/frontend-automation-state.mjs +0 -184
  215. package/skills/wix-headless-replatform/scripts/lib/gap-analysis.mjs +0 -396
  216. package/skills/wix-headless-replatform/scripts/lib/html-extract.mjs +0 -168
  217. package/skills/wix-headless-replatform/scripts/lib/interaction-bootstrap.mjs +0 -10
  218. package/skills/wix-headless-replatform/scripts/lib/interaction-runtime.mjs +0 -194
  219. package/skills/wix-headless-replatform/scripts/lib/interaction-timeline.mjs +0 -348
  220. package/skills/wix-headless-replatform/scripts/lib/layout-blueprint/classifiers.mjs +0 -141
  221. package/skills/wix-headless-replatform/scripts/lib/layout-blueprint/geometry.mjs +0 -43
  222. package/skills/wix-headless-replatform/scripts/lib/layout-blueprint/vocabulary.mjs +0 -18
  223. package/skills/wix-headless-replatform/scripts/lib/ui-normalization.css +0 -64
  224. package/skills/wix-headless-replatform/scripts/optimize-svg.mjs +0 -31
  225. package/skills/wix-headless-replatform/scripts/post-build-gap.mjs +0 -358
  226. package/skills/wix-headless-replatform/scripts/provision-repeater-cms.mjs +0 -25
  227. package/skills/wix-headless-replatform/scripts/record-gap-decision.mjs +0 -39
  228. package/skills/wix-headless-replatform/scripts/replay-extraction.mjs +0 -107
  229. package/skills/wix-headless-replatform/scripts/resolve-home-page.mjs +0 -96
  230. package/skills/wix-headless-replatform/scripts/site-clone.mjs +0 -658
  231. package/skills/wix-headless-replatform/scripts/validate-font-contract.mjs +0 -29
  232. package/skills/wix-headless-replatform/scripts/verify-interactions.mjs +0 -669
  233. package/skills/wix-headless-replatform/scripts/visual-qa.mjs +0 -370
  234. package/skills/wix-import/SKILL.md +0 -90
  235. package/skills/wix-replatform/.publish-manifest.json +0 -8
  236. package/skills/wix-replatform/CLI.md +0 -162
  237. package/skills/wix-replatform/README.md +0 -52
  238. package/skills/wix-replatform/SKILL.md +0 -238
  239. package/skills/wix-replatform/console/account.css +0 -1
  240. package/skills/wix-replatform/console/app.css +0 -1
  241. package/skills/wix-replatform/console/app.js +0 -117
  242. package/skills/wix-replatform/console/index.html +0 -4
  243. package/skills/wix-replatform/console/json.css +0 -11
  244. package/skills/wix-replatform/lib/agent-adapters/index.js +0 -71
  245. package/skills/wix-replatform/lib/app-page-routing.js +0 -75
  246. package/skills/wix-replatform/lib/artifact-freshness.js +0 -225
  247. package/skills/wix-replatform/lib/blocked-data-requests.js +0 -427
  248. package/skills/wix-replatform/lib/census-reconciliation.js +0 -426
  249. package/skills/wix-replatform/lib/completion-report.js +0 -1580
  250. package/skills/wix-replatform/lib/config-env.js +0 -133
  251. package/skills/wix-replatform/lib/confirmed-pictures.js +0 -212
  252. package/skills/wix-replatform/lib/dependency-readiness.js +0 -423
  253. package/skills/wix-replatform/lib/dependency-recovery.js +0 -21
  254. package/skills/wix-replatform/lib/destination-choice.js +0 -163
  255. package/skills/wix-replatform/lib/destination-handoff.js +0 -62
  256. package/skills/wix-replatform/lib/destination-http.js +0 -81
  257. package/skills/wix-replatform/lib/destination-route.js +0 -98
  258. package/skills/wix-replatform/lib/destination.js +0 -919
  259. package/skills/wix-replatform/lib/discovered-census.js +0 -231
  260. package/skills/wix-replatform/lib/discovered-set-status.js +0 -255
  261. package/skills/wix-replatform/lib/document-url-guard.js +0 -203
  262. package/skills/wix-replatform/lib/entity-qa-attestation.js +0 -339
  263. package/skills/wix-replatform/lib/entity-verification.js +0 -18
  264. package/skills/wix-replatform/lib/execution-capability.js +0 -120
  265. package/skills/wix-replatform/lib/execution-log.js +0 -170
  266. package/skills/wix-replatform/lib/execution-manifest.js +0 -203
  267. package/skills/wix-replatform/lib/execution-state.js +0 -195
  268. package/skills/wix-replatform/lib/expectations-ledger.js +0 -96
  269. package/skills/wix-replatform/lib/generated-plugin-handoff.js +0 -140
  270. package/skills/wix-replatform/lib/import-readiness-contract.js +0 -23
  271. package/skills/wix-replatform/lib/import-recovery.js +0 -1107
  272. package/skills/wix-replatform/lib/imported-redirect-targets.js +0 -608
  273. package/skills/wix-replatform/lib/internal-link-reconciliation.js +0 -166
  274. package/skills/wix-replatform/lib/link-audit.js +0 -173
  275. package/skills/wix-replatform/lib/link-census.js +0 -194
  276. package/skills/wix-replatform/lib/link-plan.js +0 -148
  277. package/skills/wix-replatform/lib/link-verification.js +0 -274
  278. package/skills/wix-replatform/lib/link-write-journal.js +0 -42
  279. package/skills/wix-replatform/lib/local-state.js +0 -1481
  280. package/skills/wix-replatform/lib/member-completion.js +0 -658
  281. package/skills/wix-replatform/lib/member-crosswalk.js +0 -69
  282. package/skills/wix-replatform/lib/member-outcome-registry.js +0 -265
  283. package/skills/wix-replatform/lib/migration-completion.js +0 -311
  284. package/skills/wix-replatform/lib/operator-identity.js +0 -47
  285. package/skills/wix-replatform/lib/orchestration-decisions.js +0 -248
  286. package/skills/wix-replatform/lib/orchestration-preflight.js +0 -525
  287. package/skills/wix-replatform/lib/orchestration-router.js +0 -698
  288. package/skills/wix-replatform/lib/orchestration-state.js +0 -631
  289. package/skills/wix-replatform/lib/order-reference-readiness.js +0 -30
  290. package/skills/wix-replatform/lib/payments-outcome-registry.js +0 -200
  291. package/skills/wix-replatform/lib/plugin-cms-fallback.js +0 -618
  292. package/skills/wix-replatform/lib/preservation-approval-stamp.js +0 -54
  293. package/skills/wix-replatform/lib/product-media-deferral.js +0 -96
  294. package/skills/wix-replatform/lib/progress-log.js +0 -240
  295. package/skills/wix-replatform/lib/progress-log.sh +0 -140
  296. package/skills/wix-replatform/lib/read-back-approval.js +0 -184
  297. package/skills/wix-replatform/lib/read-back-comparison.js +0 -136
  298. package/skills/wix-replatform/lib/read-back-contract.js +0 -243
  299. package/skills/wix-replatform/lib/read-back-extract.js +0 -118
  300. package/skills/wix-replatform/lib/read-back-gate.js +0 -734
  301. package/skills/wix-replatform/lib/read-back-reads.js +0 -94
  302. package/skills/wix-replatform/lib/read-back-state.js +0 -107
  303. package/skills/wix-replatform/lib/read-back-summary.js +0 -81
  304. package/skills/wix-replatform/lib/rerun-conflicts.js +0 -334
  305. package/skills/wix-replatform/lib/run-controller.js +0 -401
  306. package/skills/wix-replatform/lib/seo-outcome-registry.js +0 -45
  307. package/skills/wix-replatform/lib/setup-verification.js +0 -148
  308. package/skills/wix-replatform/lib/source-access.js +0 -231
  309. package/skills/wix-replatform/lib/source-coverage.js +0 -1130
  310. package/skills/wix-replatform/lib/source-secrets.js +0 -277
  311. package/skills/wix-replatform/lib/structured-link-patch.js +0 -59
  312. package/skills/wix-replatform/lib/task-state.js +0 -110
  313. package/skills/wix-replatform/lib/url-preservation-report.js +0 -319
  314. package/skills/wix-replatform/lib/url-preservation-state.js +0 -739
  315. package/skills/wix-replatform/lib/url-redirect-plan.js +0 -728
  316. package/skills/wix-replatform/lib/url-verification.js +0 -315
  317. package/skills/wix-replatform/lib/user-action-effects.js +0 -42
  318. package/skills/wix-replatform/lib/user-actions.js +0 -264
  319. package/skills/wix-replatform/lib/website-handoff.js +0 -1220
  320. package/skills/wix-replatform/lib/wix-client-callers.js +0 -54
  321. package/skills/wix-replatform/lib/wix-dashboard-url.js +0 -35
  322. package/skills/wix-replatform/lib/write-verification-state.js +0 -92
  323. package/skills/wix-replatform/lib/write-verification.js +0 -274
  324. package/skills/wix-replatform/resources/rp-destination/SKILL.md +0 -137
  325. package/skills/wix-replatform/resources/rp-discovery/SKILL.md +0 -357
  326. package/skills/wix-replatform/resources/rp-discovery/scripts/promote-source-coverage.js +0 -47
  327. package/skills/wix-replatform/resources/rp-execute-import/SKILL.md +0 -1369
  328. package/skills/wix-replatform/resources/rp-execute-import/scripts/shipping-estimate-audit.js +0 -70
  329. package/skills/wix-replatform/resources/rp-execute-setup/SKILL.md +0 -482
  330. package/skills/wix-replatform/resources/rp-execute-setup/scripts/execute-setup.js +0 -442
  331. package/skills/wix-replatform/resources/rp-execute-setup/scripts/mint-token.sh +0 -64
  332. package/skills/wix-replatform/resources/rp-execution-policy/SKILL.md +0 -112
  333. package/skills/wix-replatform/resources/rp-execution-policy/lib/coupon-currency-plan-report.js +0 -143
  334. package/skills/wix-replatform/resources/rp-execution-policy/lib/payments-report.js +0 -244
  335. package/skills/wix-replatform/resources/rp-import-codegen/SKILL.md +0 -3158
  336. package/skills/wix-replatform/resources/rp-mapper/SKILL.md +0 -947
  337. package/skills/wix-replatform/resources/rp-mapper/lib/mapping-resolve.js +0 -217
  338. package/skills/wix-replatform/resources/rp-mapper/lib/structure-bridge-planning.js +0 -303
  339. package/skills/wix-replatform/resources/rp-mapper/scripts/coverage-reconcile.js +0 -88
  340. package/skills/wix-replatform/resources/rp-mapper/scripts/resolve-mapping.js +0 -148
  341. package/skills/wix-replatform/resources/rp-mapper/wix-business-solutions-taxonomy.md +0 -378
  342. package/skills/wix-replatform/resources/rp-preflight/SKILL.md +0 -40
  343. package/skills/wix-replatform/resources/rp-project-intake/SKILL.md +0 -55
  344. package/skills/wix-replatform/resources/rp-quick-runtime/SKILL.md +0 -60
  345. package/skills/wix-replatform/resources/rp-quick-runtime/lib/import-progress.js +0 -89
  346. package/skills/wix-replatform/resources/rp-quick-runtime/lib/limit-recovery.js +0 -36
  347. package/skills/wix-replatform/resources/rp-quick-shopify/SKILL.md +0 -123
  348. package/skills/wix-replatform/resources/rp-quick-shopify/quick-mode.json +0 -124
  349. package/skills/wix-replatform/resources/rp-quick-shopify/scripts/quick-mode.js +0 -522
  350. package/skills/wix-replatform/resources/rp-quick-woocommerce/SKILL.md +0 -56
  351. package/skills/wix-replatform/resources/rp-quick-woocommerce/quick-mode.json +0 -91
  352. package/skills/wix-replatform/resources/rp-quick-woocommerce/scripts/quick-mode.js +0 -255
  353. package/skills/wix-replatform/resources/rp-setup-discovery/SKILL.md +0 -253
  354. package/skills/wix-replatform/resources/rp-setup-discovery/scripts/quick-setup-plan.js +0 -44
  355. package/skills/wix-replatform/resources/rp-source-csv/SKILL.md +0 -481
  356. package/skills/wix-replatform/resources/rp-source-csv/lib/canonical-record.js +0 -136
  357. package/skills/wix-replatform/resources/rp-source-csv/lib/csv-fileset.js +0 -0
  358. package/skills/wix-replatform/resources/rp-source-csv/lib/csv-fingerprint.js +0 -310
  359. package/skills/wix-replatform/resources/rp-source-csv/lib/csv-layout.js +0 -1081
  360. package/skills/wix-replatform/resources/rp-source-csv/lib/csv-parse.js +0 -618
  361. package/skills/wix-replatform/resources/rp-source-csv/scripts/csv-discovery.js +0 -969
  362. package/skills/wix-replatform/resources/rp-source-csv/source-schema.example.json +0 -196
  363. package/skills/wix-replatform/resources/rp-source-csv/vendors/bigcommerce.json +0 -66
  364. package/skills/wix-replatform/resources/rp-source-csv/vendors/magento.json +0 -60
  365. package/skills/wix-replatform/resources/rp-source-csv/vendors/shopify.json +0 -95
  366. package/skills/wix-replatform/resources/rp-source-csv/vendors/woocommerce.json +0 -82
  367. package/skills/wix-replatform/resources/rp-source-inputs/SKILL.md +0 -66
  368. package/skills/wix-replatform/resources/rp-source-sfcc/SKILL.md +0 -153
  369. package/skills/wix-replatform/resources/rp-source-shopify/SKILL.md +0 -394
  370. package/skills/wix-replatform/resources/rp-source-shopify/lib/discovery-reads.js +0 -200
  371. package/skills/wix-replatform/resources/rp-source-shopify/lib/import-findings.js +0 -34
  372. package/skills/wix-replatform/resources/rp-source-shopify/lib/shopify-bulk-sqlite-worker.js +0 -44
  373. package/skills/wix-replatform/resources/rp-source-shopify/lib/shopify-bulk.js +0 -1470
  374. package/skills/wix-replatform/resources/rp-source-shopify/lib/shopify-cli.js +0 -446
  375. package/skills/wix-replatform/resources/rp-source-shopify/lib/shopify-gift-cards.js +0 -474
  376. package/skills/wix-replatform/resources/rp-source-shopify/lib/shopify-protected-fields.js +0 -879
  377. package/skills/wix-replatform/resources/rp-source-shopify/lib/shopify-session.js +0 -426
  378. package/skills/wix-replatform/resources/rp-source-shopify/queries/articles.graphql +0 -24
  379. package/skills/wix-replatform/resources/rp-source-shopify/queries/blogs.graphql +0 -18
  380. package/skills/wix-replatform/resources/rp-source-shopify/queries/collections.graphql +0 -40
  381. package/skills/wix-replatform/resources/rp-source-shopify/queries/customers.graphql +0 -76
  382. package/skills/wix-replatform/resources/rp-source-shopify/queries/delivery-profiles.graphql +0 -51
  383. package/skills/wix-replatform/resources/rp-source-shopify/queries/discounts.graphql +0 -35
  384. package/skills/wix-replatform/resources/rp-source-shopify/queries/files.graphql +0 -20
  385. package/skills/wix-replatform/resources/rp-source-shopify/queries/gift-cards.graphql +0 -18
  386. package/skills/wix-replatform/resources/rp-source-shopify/queries/inventory.graphql +0 -31
  387. package/skills/wix-replatform/resources/rp-source-shopify/queries/locations.graphql +0 -21
  388. package/skills/wix-replatform/resources/rp-source-shopify/queries/menus.graphql +0 -21
  389. package/skills/wix-replatform/resources/rp-source-shopify/queries/metaobjects.graphql +0 -30
  390. package/skills/wix-replatform/resources/rp-source-shopify/queries/orders-core.graphql +0 -150
  391. package/skills/wix-replatform/resources/rp-source-shopify/queries/orders-fulfillments.graphql +0 -36
  392. package/skills/wix-replatform/resources/rp-source-shopify/queries/orders-refunds.graphql +0 -48
  393. package/skills/wix-replatform/resources/rp-source-shopify/queries/pages.graphql +0 -20
  394. package/skills/wix-replatform/resources/rp-source-shopify/queries/probe-customers-address.graphql +0 -8
  395. package/skills/wix-replatform/resources/rp-source-shopify/queries/probe-customers-email.graphql +0 -6
  396. package/skills/wix-replatform/resources/rp-source-shopify/queries/probe-customers-name.graphql +0 -8
  397. package/skills/wix-replatform/resources/rp-source-shopify/queries/probe-customers-phone.graphql +0 -8
  398. package/skills/wix-replatform/resources/rp-source-shopify/queries/probe-orders-address.graphql +0 -12
  399. package/skills/wix-replatform/resources/rp-source-shopify/queries/probe-orders-email.graphql +0 -6
  400. package/skills/wix-replatform/resources/rp-source-shopify/queries/probe-orders-name.graphql +0 -13
  401. package/skills/wix-replatform/resources/rp-source-shopify/queries/probe-orders-phone.graphql +0 -13
  402. package/skills/wix-replatform/resources/rp-source-shopify/queries/products.graphql +0 -73
  403. package/skills/wix-replatform/resources/rp-source-shopify/queries/url-redirects.graphql +0 -13
  404. package/skills/wix-replatform/resources/rp-source-shopify/scripts/shopify-discovery.js +0 -693
  405. package/skills/wix-replatform/resources/rp-source-shopify/scripts/shopify-extract.js +0 -283
  406. package/skills/wix-replatform/resources/rp-source-shopify/scripts/shopify-gift-card-remedy.js +0 -191
  407. package/skills/wix-replatform/resources/rp-source-shopify/scripts/shopify-session-check.js +0 -115
  408. package/skills/wix-replatform/resources/rp-source-shopify/source-schema.example.json +0 -201
  409. package/skills/wix-replatform/resources/rp-source-wordpress/PLUGIN-READ-PLANS.md +0 -146
  410. package/skills/wix-replatform/resources/rp-source-wordpress/SKILL.md +0 -970
  411. package/skills/wix-replatform/resources/rp-source-wordpress/lib/blocked-data-handlers.js +0 -73
  412. package/skills/wix-replatform/resources/rp-source-wordpress/lib/checkout-field-csv-parser.js +0 -115
  413. package/skills/wix-replatform/resources/rp-source-wordpress/lib/checkout-field-csv-parser.test-fixture.js +0 -91
  414. package/skills/wix-replatform/resources/rp-source-wordpress/lib/coupon-discovery.js +0 -440
  415. package/skills/wix-replatform/resources/rp-source-wordpress/lib/currency-gate.js +0 -125
  416. package/skills/wix-replatform/resources/rp-source-wordpress/lib/gateway-source-keys.js +0 -252
  417. package/skills/wix-replatform/resources/rp-source-wordpress/lib/gateway-source-keys.json +0 -183
  418. package/skills/wix-replatform/resources/rp-source-wordpress/lib/gateway-summary.mjs +0 -333
  419. package/skills/wix-replatform/resources/rp-source-wordpress/lib/invoice-discovery.js +0 -426
  420. package/skills/wix-replatform/resources/rp-source-wordpress/lib/plugin-disposition.js +0 -400
  421. package/skills/wix-replatform/resources/rp-source-wordpress/lib/plugin-entity-read-plan.js +0 -633
  422. package/skills/wix-replatform/resources/rp-source-wordpress/lib/plugin-knowledge.js +0 -1127
  423. package/skills/wix-replatform/resources/rp-source-wordpress/lib/refund-corroboration.js +0 -194
  424. package/skills/wix-replatform/resources/rp-source-wordpress/lib/refund-corroboration.json +0 -100
  425. package/skills/wix-replatform/resources/rp-source-wordpress/lib/sampled-ids-batch.js +0 -157
  426. package/skills/wix-replatform/resources/rp-source-wordpress/lib/secret-value-guard.js +0 -234
  427. package/skills/wix-replatform/resources/rp-source-wordpress/lib/store-currency.js +0 -101
  428. package/skills/wix-replatform/resources/rp-source-wordpress/lib/structure-bridge-reader.js +0 -755
  429. package/skills/wix-replatform/resources/rp-source-wordpress/lib/wix-wp-plugin-v2-client.js +0 -1074
  430. package/skills/wix-replatform/resources/rp-source-wordpress/lib/wix-wp-plugin-v2-client.test-fixture.js +0 -149
  431. package/skills/wix-replatform/resources/rp-source-wordpress/lib/woo-inventory.js +0 -25
  432. package/skills/wix-replatform/resources/rp-source-wordpress/lib/wp-http.js +0 -444
  433. package/skills/wix-replatform/resources/rp-source-wordpress/lib/wp-image-url.js +0 -186
  434. package/skills/wix-replatform/resources/rp-source-wordpress/lib/wp-plugin-detect.js +0 -1422
  435. package/skills/wix-replatform/resources/rp-source-wordpress/lib/wp-redirect-sources.js +0 -343
  436. package/skills/wix-replatform/resources/rp-source-wordpress/lib/wp-route-classifier.js +0 -680
  437. package/skills/wix-replatform/resources/rp-source-wordpress/lib/yoast-product-seo-evidence.js +0 -272
  438. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/README.md +0 -373
  439. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/advanced-custom-fields.json +0 -101
  440. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/back-in-stock-notifier-for-woocommerce.json +0 -81
  441. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/capabilities-pending-decision.json +0 -128
  442. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/cms-fallback-eligible.json +0 -18
  443. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/contact-form-7.json +0 -104
  444. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/facebook-for-woocommerce.json +0 -44
  445. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/fingerprint-aliases.json +0 -49
  446. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/free-gifts-for-woocommerce.json +0 -94
  447. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/index.json +0 -863
  448. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/mailpoet.json +0 -52
  449. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/membership-for-woocommerce.json +0 -161
  450. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/mwb-bookings-for-woocommerce.json +0 -180
  451. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/no-migration-needed.json +0 -286
  452. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/pricing-deals-for-woocommerce.json +0 -79
  453. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/product-extras-for-woocommerce.json +0 -120
  454. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/pw-woocommerce-gift-cards.json +0 -128
  455. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/requires-development.json +0 -88
  456. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/seo-by-rank-math.json +0 -80
  457. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/seriously-simple-podcasting.json +0 -46
  458. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/strong-testimonials.json +0 -55
  459. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/subscriptions-for-woocommerce.json +0 -99
  460. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/tablepress.json +0 -55
  461. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/the-events-calendar.json +0 -160
  462. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/ti-woocommerce-wishlist.json +0 -81
  463. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/woo-checkout-field-editor-pro.json +0 -60
  464. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/woo-discount-rules.json +0 -74
  465. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/woo-product-bundle.json +0 -75
  466. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/woocommerce-gift-cards.json +0 -60
  467. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/woocommerce-other-payment-gateway.json +0 -44
  468. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/woocommerce-pdf-invoices-packing-slips.json +0 -57
  469. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/woocommerce-product-addon.json +0 -141
  470. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/woocommerce-progressive-discounts.json +0 -54
  471. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/wordpress-seo.json +0 -158
  472. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/wpc-composite-products.json +0 -97
  473. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/wpforms-lite.json +0 -86
  474. package/skills/wix-replatform/resources/rp-source-wordpress/scripts/capture-store-settings.js +0 -90
  475. package/skills/wix-replatform/resources/rp-source-wordpress/scripts/plugin-knowledge-validate.js +0 -51
  476. package/skills/wix-replatform/resources/rp-source-wordpress/scripts/plugin-knowledge.js +0 -103
  477. package/skills/wix-replatform/resources/rp-source-wordpress/scripts/wp-discovery.js +0 -2409
  478. package/skills/wix-replatform/resources/rp-source-wordpress/scripts/wp-plugin-inventory.js +0 -273
  479. package/skills/wix-replatform/resources/rp-source-wordpress/secret-value-patterns.v1.json +0 -11
  480. package/skills/wix-replatform/resources/rp-source-wordpress/source-schema.example.json +0 -71
  481. package/skills/wix-replatform/resources/rp-source-wordpress/sub-parts.json +0 -13
  482. package/skills/wix-replatform/resources/rp-target-wix/SKILL.md +0 -1046
  483. package/skills/wix-replatform/resources/rp-target-wix/app-page-routing-capabilities.json +0 -36
  484. package/skills/wix-replatform/resources/rp-target-wix/domains/README.md +0 -57
  485. package/skills/wix-replatform/resources/rp-target-wix/domains/SERVICE-PLUGINS.md +0 -322
  486. package/skills/wix-replatform/resources/rp-target-wix/domains/blog/docs-survey.json +0 -70
  487. package/skills/wix-replatform/resources/rp-target-wix/domains/blog/domain.json +0 -29
  488. package/skills/wix-replatform/resources/rp-target-wix/domains/blog/entities/category.json +0 -71
  489. package/skills/wix-replatform/resources/rp-target-wix/domains/blog/entities/comment.json +0 -83
  490. package/skills/wix-replatform/resources/rp-target-wix/domains/blog/entities/post.json +0 -95
  491. package/skills/wix-replatform/resources/rp-target-wix/domains/blog/entities/tag.json +0 -66
  492. package/skills/wix-replatform/resources/rp-target-wix/domains/bookings/docs-survey.json +0 -332
  493. package/skills/wix-replatform/resources/rp-target-wix/domains/bookings/domain.json +0 -75
  494. package/skills/wix-replatform/resources/rp-target-wix/domains/bookings/entities/booking.json +0 -181
  495. package/skills/wix-replatform/resources/rp-target-wix/domains/bookings/entities/service-add-on.json +0 -130
  496. package/skills/wix-replatform/resources/rp-target-wix/domains/bookings/entities/service.json +0 -180
  497. package/skills/wix-replatform/resources/rp-target-wix/domains/cms/docs-survey.json +0 -161
  498. package/skills/wix-replatform/resources/rp-target-wix/domains/cms/domain.json +0 -25
  499. package/skills/wix-replatform/resources/rp-target-wix/domains/cms/entities/collection.json +0 -67
  500. package/skills/wix-replatform/resources/rp-target-wix/domains/cms/entities/data-item.json +0 -75
  501. package/skills/wix-replatform/resources/rp-target-wix/domains/cms/entities/reference.json +0 -41
  502. package/skills/wix-replatform/resources/rp-target-wix/domains/crm/docs-survey.json +0 -204
  503. package/skills/wix-replatform/resources/rp-target-wix/domains/crm/domain.json +0 -27
  504. package/skills/wix-replatform/resources/rp-target-wix/domains/crm/entities/contact.json +0 -275
  505. package/skills/wix-replatform/resources/rp-target-wix/domains/crm/entities/email-subscription.json +0 -105
  506. package/skills/wix-replatform/resources/rp-target-wix/domains/crm/entities/label.json +0 -77
  507. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/docs-survey.json +0 -306
  508. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/domain.json +0 -44
  509. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/delivery-profile.json +0 -171
  510. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/discount-rule.json +0 -182
  511. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order-applied-discount.json +0 -129
  512. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order-invoice-document.json +0 -192
  513. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order-line-item-options.json +0 -123
  514. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order-line-item.json +0 -85
  515. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order-merchant-note.json +0 -112
  516. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order-payment.json +0 -191
  517. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order-refund.json +0 -164
  518. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order.json +0 -462
  519. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/pickup-location.json +0 -122
  520. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/shipping-option.json +0 -98
  521. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/wishlist-item.json +0 -86
  522. package/skills/wix-replatform/resources/rp-target-wix/domains/events/docs-survey.json +0 -128
  523. package/skills/wix-replatform/resources/rp-target-wix/domains/events/domain.json +0 -38
  524. package/skills/wix-replatform/resources/rp-target-wix/domains/events/entities/category.json +0 -73
  525. package/skills/wix-replatform/resources/rp-target-wix/domains/events/entities/event.json +0 -107
  526. package/skills/wix-replatform/resources/rp-target-wix/domains/events/entities/registration-form.json +0 -89
  527. package/skills/wix-replatform/resources/rp-target-wix/domains/events/entities/rsvp.json +0 -118
  528. package/skills/wix-replatform/resources/rp-target-wix/domains/events/entities/ticket-definition.json +0 -93
  529. package/skills/wix-replatform/resources/rp-target-wix/domains/forms/docs-survey.json +0 -86
  530. package/skills/wix-replatform/resources/rp-target-wix/domains/forms/domain.json +0 -56
  531. package/skills/wix-replatform/resources/rp-target-wix/domains/forms/entities/form-submission.json +0 -121
  532. package/skills/wix-replatform/resources/rp-target-wix/domains/forms/entities/form.json +0 -134
  533. package/skills/wix-replatform/resources/rp-target-wix/domains/gift-cards/docs-survey.json +0 -41
  534. package/skills/wix-replatform/resources/rp-target-wix/domains/gift-cards/domain.json +0 -50
  535. package/skills/wix-replatform/resources/rp-target-wix/domains/gift-cards/entities/gift-card-product.json +0 -87
  536. package/skills/wix-replatform/resources/rp-target-wix/domains/gift-cards/entities/gift-card.json +0 -130
  537. package/skills/wix-replatform/resources/rp-target-wix/domains/index.json +0 -1418
  538. package/skills/wix-replatform/resources/rp-target-wix/domains/media/docs-survey.json +0 -41
  539. package/skills/wix-replatform/resources/rp-target-wix/domains/media/domain.json +0 -24
  540. package/skills/wix-replatform/resources/rp-target-wix/domains/media/entities/media-file.json +0 -75
  541. package/skills/wix-replatform/resources/rp-target-wix/domains/media/entities/media-folder.json +0 -71
  542. package/skills/wix-replatform/resources/rp-target-wix/domains/members/docs-survey.json +0 -119
  543. package/skills/wix-replatform/resources/rp-target-wix/domains/members/domain.json +0 -23
  544. package/skills/wix-replatform/resources/rp-target-wix/domains/members/entities/badge.json +0 -71
  545. package/skills/wix-replatform/resources/rp-target-wix/domains/members/entities/custom-field.json +0 -82
  546. package/skills/wix-replatform/resources/rp-target-wix/domains/members/entities/member-about.json +0 -77
  547. package/skills/wix-replatform/resources/rp-target-wix/domains/members/entities/member.json +0 -205
  548. package/skills/wix-replatform/resources/rp-target-wix/domains/pricing-plans/docs-survey.json +0 -41
  549. package/skills/wix-replatform/resources/rp-target-wix/domains/pricing-plans/domain.json +0 -46
  550. package/skills/wix-replatform/resources/rp-target-wix/domains/pricing-plans/entities/plan-order.json +0 -137
  551. package/skills/wix-replatform/resources/rp-target-wix/domains/pricing-plans/entities/plan.json +0 -133
  552. package/skills/wix-replatform/resources/rp-target-wix/domains/sales-channels/docs-survey.json +0 -7
  553. package/skills/wix-replatform/resources/rp-target-wix/domains/sales-channels/domain.json +0 -36
  554. package/skills/wix-replatform/resources/rp-target-wix/domains/sales-channels/entities/amazon-shop-connect.json +0 -71
  555. package/skills/wix-replatform/resources/rp-target-wix/domains/sales-channels/entities/ebay-shop-connect.json +0 -67
  556. package/skills/wix-replatform/resources/rp-target-wix/domains/sales-channels/entities/google-youtube-connect.json +0 -72
  557. package/skills/wix-replatform/resources/rp-target-wix/domains/sales-channels/entities/meta-catalog-connect.json +0 -74
  558. package/skills/wix-replatform/resources/rp-target-wix/domains/sales-channels/entities/pinterest-catalog-connect.json +0 -69
  559. package/skills/wix-replatform/resources/rp-target-wix/domains/sales-channels/entities/tiktok-catalog-connect.json +0 -61
  560. package/skills/wix-replatform/resources/rp-target-wix/domains/schema.json +0 -111
  561. package/skills/wix-replatform/resources/rp-target-wix/domains/seo/docs-survey.json +0 -109
  562. package/skills/wix-replatform/resources/rp-target-wix/domains/seo/domain.json +0 -73
  563. package/skills/wix-replatform/resources/rp-target-wix/domains/seo/entities/item-seo-tags.json +0 -148
  564. package/skills/wix-replatform/resources/rp-target-wix/domains/seo/entities/seo-pattern.json +0 -91
  565. package/skills/wix-replatform/resources/rp-target-wix/domains/seo/entities/site-seo-tags.json +0 -79
  566. package/skills/wix-replatform/resources/rp-target-wix/domains/site/docs-survey.json +0 -32
  567. package/skills/wix-replatform/resources/rp-target-wix/domains/site/domain.json +0 -49
  568. package/skills/wix-replatform/resources/rp-target-wix/domains/site/entities/business-contact.json +0 -103
  569. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/docs-survey.json +0 -203
  570. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/domain.json +0 -42
  571. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/back-in-stock-request.json +0 -119
  572. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/brand.json +0 -111
  573. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/category.json +0 -81
  574. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/coupon.json +0 -241
  575. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/inventory-item.json +0 -118
  576. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/product-customization.json +0 -111
  577. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/product-tag.json +0 -79
  578. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/product.json +0 -221
  579. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/promotion.json +0 -84
  580. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/review.json +0 -178
  581. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/subscription-product.json +0 -87
  582. package/skills/wix-replatform/resources/rp-target-wix/domains/tax/docs-survey.json +0 -106
  583. package/skills/wix-replatform/resources/rp-target-wix/domains/tax/domain.json +0 -64
  584. package/skills/wix-replatform/resources/rp-target-wix/domains/tax/entities/manual-tax-mapping.json +0 -119
  585. package/skills/wix-replatform/resources/rp-target-wix/domains/tax/entities/tax-group.json +0 -94
  586. package/skills/wix-replatform/resources/rp-target-wix/domains/tax/entities/tax-region.json +0 -113
  587. package/skills/wix-replatform/resources/rp-target-wix/domains/tax/entities/tax-settings.json +0 -65
  588. package/skills/wix-replatform/resources/rp-target-wix/lib/audit-summary.js +0 -64
  589. package/skills/wix-replatform/resources/rp-target-wix/lib/blog-author-attribution.js +0 -165
  590. package/skills/wix-replatform/resources/rp-target-wix/lib/blog-post-build-client.js +0 -60
  591. package/skills/wix-replatform/resources/rp-target-wix/lib/blog-post-build-duplicates.js +0 -201
  592. package/skills/wix-replatform/resources/rp-target-wix/lib/blog-post-build-ledger.js +0 -306
  593. package/skills/wix-replatform/resources/rp-target-wix/lib/blog-post-build-report.js +0 -229
  594. package/skills/wix-replatform/resources/rp-target-wix/lib/blog-post-build-stage.js +0 -55
  595. package/skills/wix-replatform/resources/rp-target-wix/lib/blog-post-build.js +0 -715
  596. package/skills/wix-replatform/resources/rp-target-wix/lib/blog-post-media.js +0 -567
  597. package/skills/wix-replatform/resources/rp-target-wix/lib/bulk-results.js +0 -73
  598. package/skills/wix-replatform/resources/rp-target-wix/lib/contact-extended-fields.js +0 -194
  599. package/skills/wix-replatform/resources/rp-target-wix/lib/contact-import.js +0 -133
  600. package/skills/wix-replatform/resources/rp-target-wix/lib/contract-ledger.js +0 -150
  601. package/skills/wix-replatform/resources/rp-target-wix/lib/coupon-redemption-drift.js +0 -491
  602. package/skills/wix-replatform/resources/rp-target-wix/lib/customer-member.js +0 -104
  603. package/skills/wix-replatform/resources/rp-target-wix/lib/data-extension-schema.js +0 -673
  604. package/skills/wix-replatform/resources/rp-target-wix/lib/domain-knowledge.js +0 -835
  605. package/skills/wix-replatform/resources/rp-target-wix/lib/gift-card-balance-reconciliation.js +0 -119
  606. package/skills/wix-replatform/resources/rp-target-wix/lib/gift-card-build.js +0 -566
  607. package/skills/wix-replatform/resources/rp-target-wix/lib/gift-card-redemption-build.js +0 -249
  608. package/skills/wix-replatform/resources/rp-target-wix/lib/ndjson.js +0 -260
  609. package/skills/wix-replatform/resources/rp-target-wix/lib/order-applied-discount-build.js +0 -63
  610. package/skills/wix-replatform/resources/rp-target-wix/lib/order-buyer.js +0 -187
  611. package/skills/wix-replatform/resources/rp-target-wix/lib/order-channel-build.js +0 -64
  612. package/skills/wix-replatform/resources/rp-target-wix/lib/order-history.js +0 -1027
  613. package/skills/wix-replatform/resources/rp-target-wix/lib/order-invoice-contract.js +0 -90
  614. package/skills/wix-replatform/resources/rp-target-wix/lib/order-payment-mapping.js +0 -420
  615. package/skills/wix-replatform/resources/rp-target-wix/lib/pricing-plan-definition.js +0 -177
  616. package/skills/wix-replatform/resources/rp-target-wix/lib/product-import.js +0 -151
  617. package/skills/wix-replatform/resources/rp-target-wix/lib/product-seo.js +0 -723
  618. package/skills/wix-replatform/resources/rp-target-wix/lib/seo-redirects.js +0 -353
  619. package/skills/wix-replatform/resources/rp-target-wix/lib/shipping-build.js +0 -1437
  620. package/skills/wix-replatform/resources/rp-target-wix/lib/shipping-option-stage.js +0 -354
  621. package/skills/wix-replatform/resources/rp-target-wix/lib/store-config-build.js +0 -134
  622. package/skills/wix-replatform/resources/rp-target-wix/lib/stores-category-attach.js +0 -221
  623. package/skills/wix-replatform/resources/rp-target-wix/lib/stores-inventory.js +0 -248
  624. package/skills/wix-replatform/resources/rp-target-wix/lib/stores-verification.js +0 -321
  625. package/skills/wix-replatform/resources/rp-target-wix/lib/tax-build.js +0 -231
  626. package/skills/wix-replatform/resources/rp-target-wix/lib/url-mapper-transport.js +0 -28
  627. package/skills/wix-replatform/resources/rp-target-wix/lib/value-utils.js +0 -14
  628. package/skills/wix-replatform/resources/rp-target-wix/lib/variant-correlation.js +0 -34
  629. package/skills/wix-replatform/resources/rp-target-wix/lib/wix-build.js +0 -388
  630. package/skills/wix-replatform/resources/rp-target-wix/lib/wix-target-spec.js +0 -255
  631. package/skills/wix-replatform/resources/rp-target-wix/lib/wix-writers.js +0 -6041
  632. package/skills/wix-replatform/resources/rp-target-wix/lib/write-verification.js +0 -3
  633. package/skills/wix-replatform/resources/rp-target-wix/scripts/docs-survey-sync.js +0 -150
  634. package/skills/wix-replatform/resources/rp-target-wix/scripts/domain-knowledge-validate.js +0 -69
  635. package/skills/wix-replatform/resources/rp-target-wix/scripts/domain-knowledge.js +0 -100
  636. package/skills/wix-replatform/resources/rp-target-wix/scripts/verify-stores.js +0 -112
  637. package/skills/wix-replatform/resources/rp-telemetry/SKILL.md +0 -484
  638. package/skills/wix-replatform/resources/rp-telemetry/lib/bi-sink.js +0 -318
  639. package/skills/wix-replatform/resources/rp-telemetry/lib/telemetry-recorder.js +0 -2831
  640. package/skills/wix-replatform/resources/rp-telemetry/lib/transcript-digest.js +0 -318
  641. package/skills/wix-replatform/resources/rp-telemetry/scripts/meter-from-audit.js +0 -83
  642. package/skills/wix-replatform/resources/rp-telemetry/scripts/rp-telemetry.js +0 -243
  643. package/skills/wix-replatform/resources/rp-website-continuation/SKILL.md +0 -94
  644. package/skills/wix-replatform/scripts/artifact-freshness.js +0 -76
  645. package/skills/wix-replatform/scripts/census-reconciliation.js +0 -25
  646. package/skills/wix-replatform/scripts/cms-fallback.js +0 -89
  647. package/skills/wix-replatform/scripts/discovered-census.js +0 -26
  648. package/skills/wix-replatform/scripts/discovered-set-status.js +0 -33
  649. package/skills/wix-replatform/scripts/entity-qa-attestation.js +0 -130
  650. package/skills/wix-replatform/scripts/execution-health-check.js +0 -415
  651. package/skills/wix-replatform/scripts/execution-manifest-validate.js +0 -43
  652. package/skills/wix-replatform/scripts/execution-state-prepare.js +0 -128
  653. package/skills/wix-replatform/scripts/expectations-ledger.js +0 -44
  654. package/skills/wix-replatform/scripts/import-contract-verify.js +0 -183
  655. package/skills/wix-replatform/scripts/internal-link-audit.js +0 -90
  656. package/skills/wix-replatform/scripts/item-seo-tags-verify.js +0 -205
  657. package/skills/wix-replatform/scripts/migration-completion.js +0 -76
  658. package/skills/wix-replatform/scripts/orchestration-preflight.js +0 -67
  659. package/skills/wix-replatform/scripts/orchestration-route.js +0 -77
  660. package/skills/wix-replatform/scripts/orchestration-state.js +0 -381
  661. package/skills/wix-replatform/scripts/read-back-gate.js +0 -175
  662. package/skills/wix-replatform/scripts/replatform-console.js +0 -146
  663. package/skills/wix-replatform/scripts/replatform.js +0 -436
  664. package/skills/wix-replatform/scripts/source-secrets.js +0 -77
  665. package/skills/wix-replatform/scripts/url-redirects.js +0 -286
  666. package/skills/wix-replatform/scripts/user-action.js +0 -58
  667. package/skills/wix-replatform/scripts/website-handoff-generate.js +0 -64
  668. package/skills/wix-replatform/scripts/wix-dashboard-url.js +0 -54
  669. package/skills/wix-replatform/scripts/wix-destination.js +0 -143
  670. package/skills/wix-replatform/scripts/wix-headless-scaffold.js +0 -762
  671. package/skills/wix-vibe-headless/SKILL.md +0 -183
  672. package/skills/wix-vibe-headless/install/deploy.cjs +0 -221
  673. package/skills/wix-vibe-headless/install/pin-agents-md.cjs +0 -35
  674. package/skills/wix-vibe-headless/platforms/README.md +0 -26
  675. package/skills/wix-vibe-headless/platforms/base44-ecom-light-seed-with-install.md +0 -127
  676. package/skills/wix-vibe-headless/platforms/base44-ecom-light-seed.md +0 -121
  677. package/skills/wix-vibe-headless/platforms/base44-ecom-light.md +0 -87
  678. package/skills/wix-vibe-headless/platforms/base44.md +0 -148
  679. package/skills/wix-vibe-headless/platforms/generic.md +0 -132
  680. package/skills/wix-vibe-headless/references/_shared/nav/nav.tanstack.js +0 -30
  681. package/skills/wix-vibe-headless/references/_shared/routing.md +0 -86
  682. package/skills/wix-vibe-headless/references/blog/INSTRUCTIONS.md +0 -270
  683. package/skills/wix-vibe-headless/references/blog/app/components/PostCard.jsx +0 -43
  684. package/skills/wix-vibe-headless/references/blog/app/components/PostChips.jsx +0 -25
  685. package/skills/wix-vibe-headless/references/blog/app/components/PostGrid.jsx +0 -15
  686. package/skills/wix-vibe-headless/references/blog/app/context/TaxonomyContext.jsx +0 -35
  687. package/skills/wix-vibe-headless/references/blog/app/hooks/usePostDetail.js +0 -38
  688. package/skills/wix-vibe-headless/references/blog/app/pages/Blog.jsx +0 -40
  689. package/skills/wix-vibe-headless/references/blog/app/pages/CategoryPage.jsx +0 -54
  690. package/skills/wix-vibe-headless/references/blog/app/pages/PostDetail.jsx +0 -65
  691. package/skills/wix-vibe-headless/references/blog/app/pages/TagPage.jsx +0 -50
  692. package/skills/wix-vibe-headless/references/blog/app/rest/wix-blog.js +0 -217
  693. package/skills/wix-vibe-headless/references/blog/seed/SEED.md +0 -99
  694. package/skills/wix-vibe-headless/references/blog/seed/seed-blog.cjs +0 -269
  695. package/skills/wix-vibe-headless/references/bookings/INSTRUCTIONS.md +0 -342
  696. package/skills/wix-vibe-headless/references/bookings/app/components/BookingForm.jsx +0 -65
  697. package/skills/wix-vibe-headless/references/bookings/app/components/RentalDurationPicker.jsx +0 -67
  698. package/skills/wix-vibe-headless/references/bookings/app/components/ServiceCard.jsx +0 -47
  699. package/skills/wix-vibe-headless/references/bookings/app/components/ServiceGrid.jsx +0 -13
  700. package/skills/wix-vibe-headless/references/bookings/app/components/SlotPicker.jsx +0 -126
  701. package/skills/wix-vibe-headless/references/bookings/app/hooks/useRentalDuration.js +0 -128
  702. package/skills/wix-vibe-headless/references/bookings/app/hooks/useServiceDetail.js +0 -110
  703. package/skills/wix-vibe-headless/references/bookings/app/hooks/useServices.js +0 -58
  704. package/skills/wix-vibe-headless/references/bookings/app/lib/serviceFacts.js +0 -95
  705. package/skills/wix-vibe-headless/references/bookings/app/pages/ServiceDetail.jsx +0 -94
  706. package/skills/wix-vibe-headless/references/bookings/app/pages/Services.jsx +0 -89
  707. package/skills/wix-vibe-headless/references/bookings/app/rest/wix-bookings-checkout.js +0 -148
  708. package/skills/wix-vibe-headless/references/bookings/app/rest/wix-bookings-rentals.js +0 -250
  709. package/skills/wix-vibe-headless/references/bookings/app/rest/wix-bookings-services.js +0 -300
  710. package/skills/wix-vibe-headless/references/bookings/seed/SEED.md +0 -154
  711. package/skills/wix-vibe-headless/references/bookings/seed/seed-bookings.cjs +0 -333
  712. package/skills/wix-vibe-headless/references/bookings/seed/seed-rentals.cjs +0 -267
  713. package/skills/wix-vibe-headless/references/cms/INSTRUCTIONS.md +0 -178
  714. package/skills/wix-vibe-headless/references/cms/app/collection.config.js +0 -31
  715. package/skills/wix-vibe-headless/references/cms/app/lib/wixImage.js +0 -18
  716. package/skills/wix-vibe-headless/references/cms/app/rest/wix-cms.js +0 -231
  717. package/skills/wix-vibe-headless/references/cms/seed/SEED.md +0 -145
  718. package/skills/wix-vibe-headless/references/donations/INSTRUCTIONS.md +0 -88
  719. package/skills/wix-vibe-headless/references/donations/app/rest/wix-donations.js +0 -112
  720. package/skills/wix-vibe-headless/references/donations/seed/SEED.md +0 -11
  721. package/skills/wix-vibe-headless/references/donations/tests/donations.test.mjs +0 -258
  722. package/skills/wix-vibe-headless/references/events/INSTRUCTIONS.md +0 -267
  723. package/skills/wix-vibe-headless/references/events/app/components/CategoryFilter.jsx +0 -23
  724. package/skills/wix-vibe-headless/references/events/app/components/EventCard.jsx +0 -43
  725. package/skills/wix-vibe-headless/references/events/app/components/EventGrid.jsx +0 -13
  726. package/skills/wix-vibe-headless/references/events/app/components/EventRegistration.jsx +0 -29
  727. package/skills/wix-vibe-headless/references/events/app/components/RsvpForm.jsx +0 -57
  728. package/skills/wix-vibe-headless/references/events/app/components/TicketPicker.jsx +0 -78
  729. package/skills/wix-vibe-headless/references/events/app/hooks/useEventDetail.js +0 -27
  730. package/skills/wix-vibe-headless/references/events/app/hooks/useEventsList.js +0 -54
  731. package/skills/wix-vibe-headless/references/events/app/hooks/useRsvpForm.js +0 -40
  732. package/skills/wix-vibe-headless/references/events/app/hooks/useTicketing.js +0 -81
  733. package/skills/wix-vibe-headless/references/events/app/pages/EventDetail.jsx +0 -48
  734. package/skills/wix-vibe-headless/references/events/app/pages/Events.jsx +0 -36
  735. package/skills/wix-vibe-headless/references/events/app/rest/wix-events-browse.js +0 -136
  736. package/skills/wix-vibe-headless/references/events/app/rest/wix-events-registration.js +0 -187
  737. package/skills/wix-vibe-headless/references/events/seed/SEED.md +0 -103
  738. package/skills/wix-vibe-headless/references/events/seed/seed-events.cjs +0 -251
  739. package/skills/wix-vibe-headless/references/forms/INSTRUCTIONS.md +0 -487
  740. package/skills/wix-vibe-headless/references/forms/app/hooks/useWixForm.js +0 -425
  741. package/skills/wix-vibe-headless/references/forms/app/lib/wix-form-schema-utils.js +0 -187
  742. package/skills/wix-vibe-headless/references/forms/app/rest/wix-forms-submissions.js +0 -238
  743. package/skills/wix-vibe-headless/references/forms/app/rest/wix-forms.js +0 -108
  744. package/skills/wix-vibe-headless/references/forms/seed/SEED.md +0 -1836
  745. package/skills/wix-vibe-headless/references/members/INSTRUCTIONS.md +0 -328
  746. package/skills/wix-vibe-headless/references/members/app/components/LoginForm.jsx +0 -101
  747. package/skills/wix-vibe-headless/references/members/app/components/MemberMenu.jsx +0 -33
  748. package/skills/wix-vibe-headless/references/members/app/components/RequireAuth.jsx +0 -21
  749. package/skills/wix-vibe-headless/references/members/app/components/SocialButtons.jsx +0 -29
  750. package/skills/wix-vibe-headless/references/members/app/context/MemberContext.jsx +0 -54
  751. package/skills/wix-vibe-headless/references/members/app/hooks/useLoginForm.js +0 -77
  752. package/skills/wix-vibe-headless/references/members/app/pages/Account.jsx +0 -36
  753. package/skills/wix-vibe-headless/references/members/app/pages/Callback.jsx +0 -32
  754. package/skills/wix-vibe-headless/references/members/app/pages/Login.jsx +0 -35
  755. package/skills/wix-vibe-headless/references/members/app/rest/wix-members-auth.js +0 -390
  756. package/skills/wix-vibe-headless/references/members/install/Register.jsx +0 -22
  757. package/skills/wix-vibe-headless/references/members/seed/SEED.md +0 -21
  758. package/skills/wix-vibe-headless/references/portfolio/INSTRUCTIONS.md +0 -270
  759. package/skills/wix-vibe-headless/references/portfolio/app/components/CollectionCard.jsx +0 -31
  760. package/skills/wix-vibe-headless/references/portfolio/app/components/CollectionGrid.jsx +0 -15
  761. package/skills/wix-vibe-headless/references/portfolio/app/components/ProjectCard.jsx +0 -39
  762. package/skills/wix-vibe-headless/references/portfolio/app/components/ProjectGrid.jsx +0 -15
  763. package/skills/wix-vibe-headless/references/portfolio/app/components/ProjectMedia.jsx +0 -29
  764. package/skills/wix-vibe-headless/references/portfolio/app/hooks/useCollectionProjects.js +0 -35
  765. package/skills/wix-vibe-headless/references/portfolio/app/hooks/usePortfolioGallery.js +0 -27
  766. package/skills/wix-vibe-headless/references/portfolio/app/hooks/useProjectDetail.js +0 -25
  767. package/skills/wix-vibe-headless/references/portfolio/app/pages/CollectionPage.jsx +0 -39
  768. package/skills/wix-vibe-headless/references/portfolio/app/pages/Portfolio.jsx +0 -27
  769. package/skills/wix-vibe-headless/references/portfolio/app/pages/ProjectDetail.jsx +0 -60
  770. package/skills/wix-vibe-headless/references/portfolio/app/rest/wix-portfolio.js +0 -223
  771. package/skills/wix-vibe-headless/references/portfolio/seed/SEED.md +0 -90
  772. package/skills/wix-vibe-headless/references/portfolio/seed/seed-portfolio.cjs +0 -236
  773. package/skills/wix-vibe-headless/references/pricing-plans/INSTRUCTIONS.md +0 -280
  774. package/skills/wix-vibe-headless/references/pricing-plans/app/components/OrderCard.jsx +0 -35
  775. package/skills/wix-vibe-headless/references/pricing-plans/app/components/PlanCard.jsx +0 -48
  776. package/skills/wix-vibe-headless/references/pricing-plans/app/components/PlanGrid.jsx +0 -16
  777. package/skills/wix-vibe-headless/references/pricing-plans/app/components/PlanPrice.jsx +0 -35
  778. package/skills/wix-vibe-headless/references/pricing-plans/app/hooks/useMyPlans.js +0 -25
  779. package/skills/wix-vibe-headless/references/pricing-plans/app/hooks/usePlanDetail.js +0 -28
  780. package/skills/wix-vibe-headless/references/pricing-plans/app/hooks/usePlans.js +0 -30
  781. package/skills/wix-vibe-headless/references/pricing-plans/app/pages/MyPlans.jsx +0 -30
  782. package/skills/wix-vibe-headless/references/pricing-plans/app/pages/PlanDetail.jsx +0 -53
  783. package/skills/wix-vibe-headless/references/pricing-plans/app/pages/Plans.jsx +0 -28
  784. package/skills/wix-vibe-headless/references/pricing-plans/app/rest/wix-pricing-plans.js +0 -157
  785. package/skills/wix-vibe-headless/references/pricing-plans/seed/SEED.md +0 -82
  786. package/skills/wix-vibe-headless/references/pricing-plans/seed/seed-pricing-plans.cjs +0 -251
  787. package/skills/wix-vibe-headless/references/rentals/INSTRUCTIONS.md +0 -13
  788. package/skills/wix-vibe-headless/references/restaurants/INSTRUCTIONS.md +0 -290
  789. package/skills/wix-vibe-headless/references/restaurants/app/components/ItemDialog.jsx +0 -81
  790. package/skills/wix-vibe-headless/references/restaurants/app/components/MenuItemCard.jsx +0 -71
  791. package/skills/wix-vibe-headless/references/restaurants/app/components/MenuList.jsx +0 -43
  792. package/skills/wix-vibe-headless/references/restaurants/app/components/OrderCartButton.jsx +0 -21
  793. package/skills/wix-vibe-headless/references/restaurants/app/components/OrderCartDrawer.jsx +0 -72
  794. package/skills/wix-vibe-headless/references/restaurants/app/context/OrderCartContext.jsx +0 -66
  795. package/skills/wix-vibe-headless/references/restaurants/app/hooks/useItemOrder.js +0 -32
  796. package/skills/wix-vibe-headless/references/restaurants/app/hooks/useReservation.js +0 -73
  797. package/skills/wix-vibe-headless/references/restaurants/app/pages/Menu.jsx +0 -28
  798. package/skills/wix-vibe-headless/references/restaurants/app/pages/Reservations.jsx +0 -102
  799. package/skills/wix-vibe-headless/references/restaurants/app/rest/wix-restaurants-menu.js +0 -224
  800. package/skills/wix-vibe-headless/references/restaurants/app/rest/wix-restaurants-ordering.js +0 -218
  801. package/skills/wix-vibe-headless/references/restaurants/app/rest/wix-restaurants-reservations.js +0 -107
  802. package/skills/wix-vibe-headless/references/restaurants/seed/SEED.md +0 -176
  803. package/skills/wix-vibe-headless/references/restaurants/seed/seed-restaurants.cjs +0 -452
  804. package/skills/wix-vibe-headless/references/shared/app/components/WixManageBanner.jsx +0 -56
  805. package/skills/wix-vibe-headless/references/shared/app/lib/nav.js +0 -9
  806. package/skills/wix-vibe-headless/references/shared/app/rest/wix-client.js +0 -185
  807. package/skills/wix-vibe-headless/references/shared/app/rest/wix-config.js +0 -8
  808. package/skills/wix-vibe-headless/references/storefront/INSTRUCTIONS.md +0 -471
  809. package/skills/wix-vibe-headless/references/storefront/app/components/CartButton.jsx +0 -20
  810. package/skills/wix-vibe-headless/references/storefront/app/components/CartDrawer.jsx +0 -167
  811. package/skills/wix-vibe-headless/references/storefront/app/context/CartContext.jsx +0 -83
  812. package/skills/wix-vibe-headless/references/storefront/app/hooks/useProductCard.js +0 -104
  813. package/skills/wix-vibe-headless/references/storefront/app/hooks/useProductDetail.js +0 -163
  814. package/skills/wix-vibe-headless/references/storefront/app/hooks/useShop.js +0 -83
  815. package/skills/wix-vibe-headless/references/storefront/app/hooks/useVariantOptions.js +0 -76
  816. package/skills/wix-vibe-headless/references/storefront/app/lib/storeImage.js +0 -64
  817. package/skills/wix-vibe-headless/references/storefront/app/rest/wix-store-cart.js +0 -176
  818. package/skills/wix-vibe-headless/references/storefront/app/rest/wix-store-catalog.js +0 -218
  819. package/skills/wix-vibe-headless/references/storefront/seed/SEED.md +0 -174
  820. package/skills/wix-vibe-headless/references/storefront/seed/seed-store.cjs +0 -546
@@ -1,1074 +0,0 @@
1
- 'use strict';
2
-
3
- // Client for wix-wp-plugin-v2 -- the ONLY bridge-plugin-style mechanism this
4
- // skill uses for data with no REST route at all (db-only, or admin-page-only with an
5
- // underlying table). There is no per-capability fixed adapter any more: any db-only
6
- // entity's fulfillment can point at this SAME handler with a different `table`, because
7
- // wix-wp-plugin-v2 itself has no per-capability code -- see plugins/wix-wp-plugin-v2/README.md.
8
- //
9
- // Two capabilities, matching the plugin's own two routes:
10
- // - discoverStructure(): schema only (columns, types, key hints). Safe to call before a
11
- // human has decided anything about a table -- no row data leaves the site.
12
- // - queryStructure(): real row data, via one bounded, parameterized SELECT (select
13
- // columns/aggregates, optional where/groupBy, required orderBy, cursor pagination).
14
- // Pulling real data through this for a specific entity is a per-entity decision, not
15
- // implied by schema-discoverability -- e.g. gift-card-activity's balance/redemption
16
- // ledger still needs its own masking/correlation call even though its
17
- // schema is freely discoverable.
18
-
19
- const { createHash, createHmac, randomUUID, timingSafeEqual } = require('node:crypto');
20
-
21
- const SHARED_CORE_TABLES_REQUIRING_WHERE = new Set(['posts', 'terms', 'term_taxonomy', 'term_relationships', 'comments']);
22
- const MAX_IN_VALUES = 100;
23
- const MAX_WHERE_CONDITIONS = 20;
24
- const HANDLER_VERSION = '1.3.0'; // 1.3.0: signed migration-key transport plus strict response-envelope validation.
25
-
26
- function bodyOf(response) {
27
- return response && response.data !== undefined ? response.data : response;
28
- }
29
-
30
- function assertColumn(column, table) {
31
- if (!column || typeof column.name !== 'string' || column.name.length === 0) {
32
- throw new Error(`table ${table}: column name is required`);
33
- }
34
- if (typeof column.type !== 'string' || column.type.length === 0) {
35
- throw new Error(`table ${table}: column ${column.name} is missing a type`);
36
- }
37
- if (typeof column.nullable !== 'boolean') {
38
- throw new Error(`table ${table}: column ${column.name} is missing nullable`);
39
- }
40
- if (column.key !== null && !['primary', 'unique', 'index'].includes(column.key)) {
41
- throw new Error(`table ${table}: column ${column.name} has an invalid key hint ${JSON.stringify(column.key)}`);
42
- }
43
- }
44
-
45
- const EAV_TIERS = ['key-discovery', 'key-scoped'];
46
-
47
- /**
48
- * `redactionMetadata`, required on every response and validated against the
49
- * schema's actual contract: a NON-NEGATIVE INTEGER count and an array of STRINGS.
50
- *
51
- * The loose version accepted `-1.5` and `[7]`, which was not merely untidy. Those values flow
52
- * straight into `sourceReadCounts()` and on to rp-telemetry, whose validator correctly rejects
53
- * them -- so a malformed count silently discarded the whole accumulated telemetry batch, far
54
- * from the response that caused it. Validate at the boundary, where the error can still name
55
- * the table.
56
- */
57
- function assertRedactionMetadata(redactionMetadata, table) {
58
- if (!redactionMetadata || typeof redactionMetadata !== 'object' || Array.isArray(redactionMetadata)) {
59
- throw new Error(
60
- `table ${table}: response is missing redactionMetadata, which is required on every `
61
- + 'query-structure response. The source site is running a wix-wp-plugin-v2 older than 0.4.0, which has no '
62
- + 'secret-value guard -- upgrade the plugin rather than treating this as an empty redaction set.',
63
- );
64
- }
65
- const { redactedValueCount, redactedColumns } = redactionMetadata;
66
- if (!Number.isInteger(redactedValueCount) || redactedValueCount < 0) {
67
- throw new Error(`table ${table}: redactionMetadata.redactedValueCount must be a non-negative integer (got ${JSON.stringify(redactedValueCount)})`);
68
- }
69
- if (!Array.isArray(redactedColumns) || redactedColumns.some((c) => typeof c !== 'string')) {
70
- throw new Error(`table ${table}: redactionMetadata.redactedColumns must be an array of column names`);
71
- }
72
- if (redactedValueCount > 0 && redactedColumns.length === 0) {
73
- throw new Error(`table ${table}: redactionMetadata reports ${redactedValueCount} redaction(s) but names no column -- a count with no column is not actionable`);
74
- }
75
- return { redactedValueCount, redactedColumns: [...redactedColumns] };
76
- }
77
-
78
- /** A {keyColumn, valueColumn} pair, as reported by either route. */
79
- function assertPairShape(pair, table, where) {
80
- if (!pair || typeof pair.keyColumn !== 'string' || typeof pair.valueColumn !== 'string') {
81
- throw new Error(`table ${table}: ${where} must carry string keyColumn and valueColumn`);
82
- }
83
- return { keyColumn: pair.keyColumn, valueColumn: pair.valueColumn };
84
- }
85
-
86
- /**
87
- * discover-structure's `eavPair`. Absent for an ordinary table; when present it names the
88
- * column a query must pin. `additionalPairs` appears only for the rare schema carrying more
89
- * than one recognized pair -- and it is propagated rather than dropped, because every one of
90
- * those value columns is independently guarded and a caller that saw only the first would
91
- * build a request the plugin refuses.
92
- */
93
- function assertEavPair(eavPair, table) {
94
- if (eavPair === undefined || eavPair === null) return null;
95
- const pair = assertPairShape(eavPair, table, 'eavPair');
96
- if (eavPair.additionalPairs !== undefined) {
97
- if (!Array.isArray(eavPair.additionalPairs)) throw new Error(`table ${table}: eavPair.additionalPairs must be an array`);
98
- pair.additionalPairs = eavPair.additionalPairs.map((p) => assertPairShape(p, table, 'eavPair.additionalPairs[]'));
99
- }
100
- return pair;
101
- }
102
-
103
- /**
104
- * query-structure's `eavAccess`. Absent for a table with no key/value pair; present with a
105
- * tier and the key names the request pinned otherwise. Validated rather than passed through
106
- * so a caller can branch on `tier` without re-checking the shape.
107
- */
108
- function assertAccessPair(pair, table, where) {
109
- const shape = assertPairShape(pair, table, where);
110
- if (!EAV_TIERS.includes(pair.tier)) {
111
- throw new Error(`table ${table}: ${where}.tier ${JSON.stringify(pair.tier)} is not one of ${EAV_TIERS.join(', ')}`);
112
- }
113
- if (!Array.isArray(pair.pinnedKeys) || pair.pinnedKeys.some((k) => typeof k !== 'string')) {
114
- throw new Error(`table ${table}: ${where}.pinnedKeys must be an array of key names`);
115
- }
116
- return { ...shape, tier: pair.tier, pinnedKeys: [...pair.pinnedKeys] };
117
- }
118
-
119
- /**
120
- * query-structure's `eavAccess`. Absent for a table with no key/value pair.
121
- *
122
- * EVERY pair goes through the SAME validation, primary and additional alike. An earlier
123
- * version validated the primary strictly and then copied an additional pair's `tier`
124
- * unchecked while coercing a malformed `pinnedKeys` to `[]` — so a response claiming
125
- * `tier: "full"` on a second pair was accepted, and a caller branching on tier could conclude
126
- * a guarded column was freely readable. Validating one of N is not validating.
127
- */
128
- function assertEavAccess(eavAccess, table) {
129
- if (eavAccess === undefined || eavAccess === null) return null;
130
- const access = assertAccessPair(eavAccess, table, 'eavAccess');
131
- if (eavAccess.additionalPairs !== undefined) {
132
- if (!Array.isArray(eavAccess.additionalPairs)) throw new Error(`table ${table}: eavAccess.additionalPairs must be an array`);
133
- access.additionalPairs = eavAccess.additionalPairs.map((p) => assertAccessPair(p, table, 'eavAccess.additionalPairs[]'));
134
- }
135
- return access;
136
- }
137
-
138
- /** Every pair in an eavAccess, primary first — what any per-pair reasoning should iterate. */
139
- function eavAccessPairs(eavAccess) {
140
- if (!eavAccess) return [];
141
- const { keyColumn, valueColumn, tier, pinnedKeys } = eavAccess;
142
- return [{ keyColumn, valueColumn, tier, pinnedKeys }, ...(eavAccess.additionalPairs || [])];
143
- }
144
-
145
- /**
146
- * Every value column this table guards -- the primary pair's plus any additional ones. What
147
- * a caller needs to build a legal request: these columns are unreachable unless the matching
148
- * key column is pinned.
149
- */
150
- function guardedValueColumns(pairOrAccess) {
151
- if (!pairOrAccess) return [];
152
- return [pairOrAccess.valueColumn, ...(pairOrAccess.additionalPairs || []).map((p) => p.valueColumn)];
153
- }
154
-
155
- /**
156
- * Reports the live column list for one bare table name. Structure only, never row data --
157
- * see modules/class-wmh2-structure-discovery.php's own contract. Throws on any
158
- * malformed/incomplete response rather than returning a partial result silently.
159
- *
160
- * Two credential modes, matching the plugin's own two route registrations for
161
- * `/structure`: the default is the WordPress Application Password path (GET, via the
162
- * caller-supplied `httpClient`). Pass `auth: { type: 'migration-key', migrationKey, siteId,
163
- * migrationId, timeoutMs }` to use the signed-JWT path instead -- required on a source site
164
- * with no WooCommerce, where the Application Password routes are `manage_woocommerce`-gated
165
- * and therefore unusable by any user at all (see "Signed migration-key path" below). That
166
- * mode calls the plugin directly over `fetch` and does not use `httpClient`.
167
- */
168
- async function discoverStructure({ httpClient, siteBaseUrl, auth, table } = {}) {
169
- if (!siteBaseUrl || typeof siteBaseUrl !== 'string') throw new Error('siteBaseUrl is required');
170
- if (!table || typeof table !== 'string' || !/^[A-Za-z0-9_]+$/.test(table)) {
171
- throw new Error('table is required and must be a bare identifier (^[A-Za-z0-9_]+$)');
172
- }
173
-
174
- let body;
175
- if (auth && auth.type === 'migration-key') {
176
- if (!auth.migrationKey || typeof auth.migrationKey !== 'string') {
177
- throw new Error('auth.migrationKey is required for the migration-key credential path');
178
- }
179
- body = await callSignedOperation({
180
- siteBaseUrl,
181
- migrationKey: auth.migrationKey,
182
- operation: 'discover-structure',
183
- route: '/wix-wp-plugin/v2/structure',
184
- siteId: auth.siteId || DEFAULT_MIGRATION_KEY_SITE_ID,
185
- migrationId: auth.migrationId || randomUUID(),
186
- operationClaims: { table },
187
- timeoutMs: auth.timeoutMs,
188
- });
189
- } else {
190
- if (!httpClient || typeof httpClient.get !== 'function') throw new Error('httpClient.get is required');
191
- const base = siteBaseUrl.replace(/\/$/, '');
192
- const response = await httpClient.get(`${base}/wp-json/wix-wp-plugin/v2/structure`, {
193
- params: { table },
194
- auth,
195
- });
196
- body = bodyOf(response);
197
- }
198
- if (!body || body.table !== table || !Array.isArray(body.columns)) {
199
- throw new Error(`table ${table}: response did not match discover-structure's response-payload contract`);
200
- }
201
- for (const column of body.columns) assertColumn(column, table);
202
-
203
- // `eavPair` MUST be propagated. Dropping it here was a real bug: it is the
204
- // caller's only advance warning that this table is key-scoped, so without it a caller
205
- // builds an unscoped "select every column" request and gets a 400 it cannot interpret.
206
- return { table: body.table, columns: body.columns, eavPair: assertEavPair(body.eavPair, table) };
207
- }
208
-
209
- /**
210
- * Runs one structure request. Returns one page of rows plus pagingMetadata -- the caller
211
- * is responsible for looping on `hasNext`/`cursors.next` until a full read completes, same
212
- * cursor-paging contract as any other WordPress source route this skill reads. This client
213
- * does not re-validate the structure request's own shape (table/select/where/groupBy/orderBy)
214
- * beyond requiring a `table` -- the plugin itself re-validates every identifier against a
215
- * live DESCRIBE on every request, so duplicating that here would only create a second copy
216
- * to keep in sync.
217
- *
218
- * Two credential modes, matching the plugin's own two route registrations: the default is
219
- * the WordPress Application Password path (POST /query/admin-key, plain JSON, via the
220
- * caller-supplied `httpClient`). Pass `auth: { type: 'migration-key', migrationKey, siteId,
221
- * migrationId, timeoutMs }` to use the signed-JWT path instead (POST /query, no `/admin-key`
222
- * suffix, JWT body) -- required on a source site with no WooCommerce, where the Application
223
- * Password routes are `manage_woocommerce`-gated and therefore unusable by any user at all.
224
- * That mode calls the plugin directly over `fetch` and does not use `httpClient`; it also
225
- * requires an integer `cursorPaging.limit` on every request (the admin-key path lets the
226
- * server default it), so an omitted `limit` falls back to this module's mirror of
227
- * `WMH2_Contract::DEFAULT_LIMIT`.
228
- *
229
- * `onSourceRead` is the telemetry hook: called once per successful read with the
230
- * counts for THAT read, for the caller to pass to rp-telemetry's `sourceRead()`. Optional, so
231
- * a unit test or a one-off script need not wire telemetry, but every real reader should.
232
- */
233
- async function queryStructure({ httpClient, siteBaseUrl, auth, structureRequest, cursor, limit, onSourceRead } = {}) {
234
- if (!siteBaseUrl || typeof siteBaseUrl !== 'string') throw new Error('siteBaseUrl is required');
235
- if (!structureRequest || typeof structureRequest !== 'object' || typeof structureRequest.table !== 'string') {
236
- throw new Error('structureRequest with a table is required');
237
- }
238
-
239
- let body;
240
- if (auth && auth.type === 'migration-key') {
241
- if (!auth.migrationKey || typeof auth.migrationKey !== 'string') {
242
- throw new Error('auth.migrationKey is required for the migration-key credential path');
243
- }
244
- const cursorPaging = { cursor: cursor === undefined ? null : cursor, limit: limit === undefined ? DEFAULT_QUERY_LIMIT : limit };
245
- body = await callSignedOperation({
246
- siteBaseUrl,
247
- migrationKey: auth.migrationKey,
248
- operation: 'query-structure',
249
- route: '/wix-wp-plugin/v2/query',
250
- siteId: auth.siteId || DEFAULT_MIGRATION_KEY_SITE_ID,
251
- migrationId: auth.migrationId || randomUUID(),
252
- operationClaims: { structureRequest, cursorPaging },
253
- timeoutMs: auth.timeoutMs,
254
- });
255
- } else {
256
- if (!httpClient || typeof httpClient.post !== 'function') throw new Error('httpClient.post is required');
257
- const base = siteBaseUrl.replace(/\/$/, '');
258
- const requestBody = { structureRequest };
259
- if (cursor !== undefined) requestBody.cursor = cursor;
260
- if (limit !== undefined) requestBody.limit = limit;
261
- const response = await httpClient.post(`${base}/wp-json/wix-wp-plugin/v2/query/admin-key`, {
262
- body: JSON.stringify(requestBody),
263
- auth,
264
- });
265
- body = bodyOf(response);
266
- }
267
- if (!body || !Array.isArray(body.rows) || !body.pagingMetadata) {
268
- throw new Error(`table ${structureRequest.table}: response did not match query-structure's response-payload contract`);
269
- }
270
- const { pagingMetadata } = body;
271
- if (typeof pagingMetadata.hasNext !== 'boolean' || typeof pagingMetadata.total !== 'number'
272
- || !pagingMetadata.cursors || !('next' in pagingMetadata.cursors)) {
273
- throw new Error(`table ${structureRequest.table}: pagingMetadata does not match query-structure's response-payload contract`);
274
- }
275
-
276
- // REQUIRED on every response, so its absence is a hard error rather than a
277
- // defaulted zero. A plugin old enough not to send it is a plugin without the value guard
278
- // at all, and silently treating that as "nothing was redacted" would report a guarded read
279
- // that never happened. Refusing names the real problem: upgrade the plugin.
280
- const redactionMetadata = assertRedactionMetadata(body.redactionMetadata, structureRequest.table);
281
-
282
- const eavAccess = assertEavAccess(body.eavAccess, structureRequest.table);
283
- if (onSourceRead) onSourceRead(sourceReadCounts(structureRequest.table, eavAccess, redactionMetadata));
284
- return { rows: body.rows, pagingMetadata, redactionMetadata, eavAccess };
285
- }
286
-
287
- // --- Signed migration-key path ("signed request/response" model, contract version 2) ---------
288
- //
289
- // A WordPress site with no `wc/*` REST namespace has no `manage_woocommerce` capability for
290
- // ANYONE, including an administrator -- the Application Password routes above are then
291
- // structurally unusable, for every user on that site, not just a permissions edge case. The
292
- // signed migration-key path is the only credential the plugin's own connection page ever
293
- // issues that does not depend on that capability: `WMH2_Request_Auth::verify_operation()`
294
- // checks a JWT signature and request-binding claims, never a WordPress capability.
295
- //
296
- // This is a DIFFERENT wire shape from the Application Password routes above, not a header
297
- // swap on the same request: POST only (both operations), a distinct un-suffixed route
298
- // (`/structure`, `/query` -- never `/query/admin-key`), `Content-Type: application/jwt` with
299
- // the compact JWT as the entire raw body (never a JSON envelope), and a signed JWT string
300
- // back rather than a plain JSON object. That is why this path calls `fetch` directly instead
301
- // of going through the caller-supplied `httpClient` the Application Password functions take --
302
- // an httpClient built for "send this JSON, get back that JSON" has no seam for "the body IS
303
- // the credential-bearing artifact". `plugins/wix-wp-plugin-v2/examples/jwt-smoke-test.mjs` is
304
- // the reference implementation this mirrors; reuse its claim set and response validation
305
- // rather than inventing a second one that can drift from the plugin's own contract test
306
- // (`tests/source-wordpress/wix-wp-plugin-v2-jwt-contract-v2-test.js`).
307
-
308
- const JWT_REQUEST_ISSUER = 'wix-siteImportService';
309
- const JWT_REQUEST_AUDIENCE = 'wix-wp-plugin-v2';
310
- const JWT_RESPONSE_ISSUER = 'wix-wp-plugin-v2';
311
- const JWT_RESPONSE_AUDIENCE = 'wix-siteImportService';
312
- const JWT_CONTRACT_VERSION = 2;
313
- const JWT_REQUEST_LIFETIME_SECONDS = 60; // must stay under the plugin's MAX_REQUEST_TOKEN_LIFETIME_SECONDS (120)
314
- const DEFAULT_MIGRATION_KEY_SITE_ID = 'rp-source-wordpress';
315
- const DEFAULT_QUERY_LIMIT = 50; // mirrors WMH2_Contract::DEFAULT_LIMIT; cursorPaging.limit is a required int on this path
316
- const DEFAULT_SIGNED_TIMEOUT_MS = 60000;
317
-
318
- function base64url(value) {
319
- return (Buffer.isBuffer(value) ? value : Buffer.from(value, 'utf8')).toString('base64url');
320
- }
321
-
322
- function base64urlDecode(value) {
323
- return Buffer.from(value, 'base64url');
324
- }
325
-
326
- /** Signs one operation's claims with the migration key. Returns the compact JWT plus the claims, so the caller can bind the response back to this exact request via `jti`. */
327
- function signMigrationKeyRequest({ migrationKey, operation, route, siteId, migrationId, operationClaims }) {
328
- const now = Math.floor(Date.now() / 1000);
329
- const claims = {
330
- iss: JWT_REQUEST_ISSUER,
331
- aud: JWT_REQUEST_AUDIENCE,
332
- site_id: siteId,
333
- migration_id: migrationId,
334
- operation,
335
- contract_version: JWT_CONTRACT_VERSION,
336
- method: 'POST',
337
- route,
338
- ...operationClaims,
339
- iat: now,
340
- nbf: now,
341
- exp: now + JWT_REQUEST_LIFETIME_SECONDS,
342
- jti: randomUUID(),
343
- };
344
- const signingInput = [{ alg: 'HS256', typ: 'JWT' }, claims].map((part) => base64url(JSON.stringify(part))).join('.');
345
- const signature = createHmac('sha256', migrationKey).update(signingInput).digest();
346
- return { token: `${signingInput}.${base64url(signature)}`, requestClaims: claims };
347
- }
348
-
349
- /** Verifies a signed response's signature and every request-binding claim before trusting its payload. Never returns an unverified payload. */
350
- function verifyMigrationKeyResponse({ migrationKey, jwt, requestClaims, operation, siteId, migrationId }) {
351
- const parts = String(jwt).split('.');
352
- if (parts.length !== 3) {
353
- throw new Error(`${operation}: response is not a compact three-part JWT`);
354
- }
355
- const [encodedHeader, encodedPayload, encodedSignature] = parts;
356
- const header = JSON.parse(base64urlDecode(encodedHeader).toString('utf8'));
357
- if (header.alg !== 'HS256') {
358
- throw new Error(`${operation}: unexpected response JWT algorithm ${header.alg}`);
359
- }
360
- const expectedSignature = createHmac('sha256', migrationKey).update(`${encodedHeader}.${encodedPayload}`).digest();
361
- const actualSignature = base64urlDecode(encodedSignature);
362
- if (expectedSignature.length !== actualSignature.length || !timingSafeEqual(expectedSignature, actualSignature)) {
363
- throw new Error(`${operation}: response JWT signature is invalid`);
364
- }
365
- const claims = JSON.parse(base64urlDecode(encodedPayload).toString('utf8'));
366
- if (!claims || typeof claims !== 'object' || Array.isArray(claims)) {
367
- throw new Error(`${operation}: response JWT claims must be an object`);
368
- }
369
- const now = Math.floor(Date.now() / 1000);
370
- const requiredClaims = [
371
- 'iss', 'aud', 'site_id', 'migration_id', 'request_jti', 'operation',
372
- 'contract_version', 'snapshot_id', 'payload', 'iat', 'exp', 'jti',
373
- ];
374
- const allowedClaims = new Set([...requiredClaims, 'wp_installation_id']);
375
- const unknownClaims = Object.keys(claims).filter((name) => !allowedClaims.has(name));
376
- if (unknownClaims.length > 0) {
377
- throw new Error(`${operation}: response JWT contains unknown claim(s): ${unknownClaims.join(', ')}`);
378
- }
379
- const missingClaims = requiredClaims.filter((name) => !Object.prototype.hasOwnProperty.call(claims, name));
380
- if (missingClaims.length > 0) {
381
- throw new Error(`${operation}: response JWT is missing required claim(s): ${missingClaims.join(', ')}`);
382
- }
383
- const expectedClaims = {
384
- iss: JWT_RESPONSE_ISSUER,
385
- aud: JWT_RESPONSE_AUDIENCE,
386
- site_id: siteId,
387
- migration_id: migrationId,
388
- request_jti: requestClaims.jti,
389
- operation,
390
- contract_version: JWT_CONTRACT_VERSION,
391
- };
392
- for (const [name, value] of Object.entries(expectedClaims)) {
393
- if (claims[name] !== value) {
394
- throw new Error(`${operation}: unexpected response claim ${name} (expected ${JSON.stringify(value)}, got ${JSON.stringify(claims[name])})`);
395
- }
396
- }
397
- if (!Number.isInteger(claims.iat)) {
398
- throw new Error(`${operation}: response JWT has no integer iat claim`);
399
- }
400
- if (!Number.isInteger(claims.exp) || claims.exp < now) {
401
- throw new Error(`${operation}: response JWT is expired or has no integer exp claim`);
402
- }
403
- for (const name of ['snapshot_id', 'jti']) {
404
- if (typeof claims[name] !== 'string' || claims[name] === '') {
405
- throw new Error(`${operation}: response JWT claim ${name} must be a non-empty string`);
406
- }
407
- }
408
- if (Object.prototype.hasOwnProperty.call(claims, 'wp_installation_id')
409
- && (typeof claims.wp_installation_id !== 'string' || claims.wp_installation_id === '')) {
410
- throw new Error(`${operation}: response JWT claim wp_installation_id must be a non-empty string when present`);
411
- }
412
- if (!claims.payload || typeof claims.payload !== 'object' || Array.isArray(claims.payload)) {
413
- throw new Error(`${operation}: response JWT has no object payload claim`);
414
- }
415
- return claims.payload;
416
- }
417
-
418
- /** POSTs one signed operation and returns its verified payload. Refuses redirects: a 301/302 can rewrite the physical POST into a GET, which the plugin's own method binding then correctly rejects -- surfacing that as a redirect error is more actionable than the resulting 400. */
419
- async function callSignedOperation({ siteBaseUrl, migrationKey, operation, route, siteId, migrationId, operationClaims, timeoutMs }) {
420
- const base = siteBaseUrl.replace(/\/$/, '');
421
- const { token, requestClaims } = signMigrationKeyRequest({ migrationKey, operation, route, siteId, migrationId, operationClaims });
422
- const effectiveTimeoutMs = Number.isFinite(timeoutMs) && timeoutMs > 0 ? timeoutMs : DEFAULT_SIGNED_TIMEOUT_MS;
423
- const controller = new AbortController();
424
- const timer = setTimeout(() => controller.abort(), effectiveTimeoutMs);
425
- let response;
426
- try {
427
- response = await fetch(`${base}/wp-json${route}`, {
428
- method: 'POST',
429
- redirect: 'manual',
430
- headers: { accept: 'application/json', 'content-type': 'application/jwt' },
431
- body: token,
432
- signal: controller.signal,
433
- });
434
- } finally {
435
- clearTimeout(timer);
436
- }
437
- if (response.status >= 300 && response.status < 400) {
438
- throw new Error(`${operation}: redirected to ${response.headers.get('location') || '(unknown location)'} -- use the site's canonical HTTPS URL`);
439
- }
440
- const responseText = await response.text();
441
- if (!response.ok) {
442
- const error = new Error(`${operation}: HTTP ${response.status}: ${responseText}`);
443
- error.status = response.status;
444
- throw error;
445
- }
446
- let responseJwt;
447
- try {
448
- responseJwt = JSON.parse(responseText);
449
- } catch {
450
- responseJwt = responseText;
451
- }
452
- if (typeof responseJwt !== 'string') {
453
- throw new Error(`${operation}: response body is not a signed JWT string`);
454
- }
455
- return verifyMigrationKeyResponse({ migrationKey, jwt: responseJwt, requestClaims, operation, siteId, migrationId });
456
- }
457
-
458
- /**
459
- * The per-read telemetry counts, derived HERE because this client is the single point every
460
- * bridge read passes through -- deriving them at any call site would mean every future caller
461
- * has to remember, and the one that forgets makes the run's total quietly wrong.
462
- *
463
- * Note what is NOT in here: key names. A run's own artifacts hold those. `redacted_values` is
464
- * the field worth aggregating across runs, because a non-zero total means some site keeps a
465
- * credential where nobody expected one.
466
- */
467
- function sourceReadCounts(table, eavAccess, redactionMetadata) {
468
- const counts = { redacted_values: redactionMetadata.redactedValueCount };
469
- const pairs = eavAccessPairs(eavAccess);
470
- if (pairs.length > 0) {
471
- // MIXED-TIER RULE, stated rather than left to whichever pair happens to be first: a
472
- // request counts as SCOPED if ANY pair was pinned. The counts answer "how many reads
473
- // returned key/value DATA versus only key names", and one pinned pair means values came
474
- // back — so classifying by the primary pair alone would file a read that returned values
475
- // as a name-only discovery read. Reading the first pair's tier was the earlier behaviour
476
- // and it misclassified exactly this case.
477
- const anyPinned = pairs.some((p) => p.tier === 'key-scoped');
478
- counts[anyPinned ? 'scoped_queries' : 'discovery_queries'] = 1;
479
- counts[anyPinned ? 'scoped_tables' : 'discovery_tables'] = [table];
480
- }
481
- return counts;
482
- }
483
-
484
- /**
485
- * Would this request violate the tier rule -- i.e. does it name a guarded value column without
486
- * pinning that pair's key with `eq`/`in`?
487
- *
488
- * Decided from the request and the schema, NOT from the response, because the plugin answers a
489
- * tier violation with the same 400 as a nonexistent column, a malformed request, or a bad
490
- * cursor -- deliberately, so a refusal never discloses which column holds values. Treating
491
- * every 400 on a key/value table as a tier refusal was the earlier behaviour and it
492
- * misclassified the common case: a profile naming a column the site has since dropped is an
493
- * outdated profile, and filing it as a security-control refusal makes the one number that
494
- * should mean "something tried to reach values it had not named" mean nothing.
495
- *
496
- * Mirrors the plugin's own predicate, which is why it lives beside the client
497
- * rather than at a call site.
498
- *
499
- * @param eavPair discover-structure's `eavPair` (with any `additionalPairs`), or null.
500
- */
501
- function violatesTierRule(structureRequest, eavPair) {
502
- if (!eavPair) return false;
503
- const pairs = [{ keyColumn: eavPair.keyColumn, valueColumn: eavPair.valueColumn }, ...(eavPair.additionalPairs || [])];
504
- const where = Array.isArray(structureRequest.where) ? structureRequest.where : [];
505
- const names = new Set([
506
- ...(structureRequest.select || []).map((item) => item && item.column),
507
- ...where.map((condition) => condition && condition.column),
508
- ...(structureRequest.groupBy || []),
509
- ...(structureRequest.orderBy || []).map((item) => item && item.column),
510
- ]);
511
- return pairs.some(({ keyColumn, valueColumn }) => {
512
- if (!names.has(valueColumn)) return false;
513
- const pinned = where.some((c) => c && c.column === keyColumn && (c.op === 'eq' || c.op === 'in'));
514
- return !pinned;
515
- });
516
- }
517
-
518
- /** A tier-rule refusal, counted separately once `violatesTierRule` has established it is one. */
519
- function recordTierRefusal(onSourceRead) {
520
- if (onSourceRead) onSourceRead({ tier_refusals: 1 });
521
- }
522
-
523
- // Two caps, both the plugin's, both load-bearing here.
524
- const MAX_PINNED_KEYS = 50; // per scoped request
525
- const MAX_PAGE_LIMIT = 200; // per page, WMH2_Contract::MAX_LIMIT
526
- const MAX_SELECT_COLUMNS = 50; // WMH2_Structure_Query::MAX_SELECT_COLUMNS
527
-
528
- /**
529
- * Page the discovery tier to exhaustion and return EVERY distinct key.
530
- *
531
- * Exhaustion is the whole contract. A truncated key list reads as "these are all the keys" and
532
- * sends a mapper down a wrong path, so this either returns a complete list or says plainly that
533
- * it did not: `truncated` is true when `maxKeys` was hit, and a caller must treat that as an
534
- * incomplete extraction rather than a slightly-short one. There is no silent cap.
535
- */
536
- function validateStructureRequest(request) {
537
- const identifier = (value) => typeof value === 'string' && /^[A-Za-z0-9_]+$/.test(value);
538
- const keys = (value, allowed) => value && typeof value === 'object' && !Array.isArray(value) && Object.keys(value).every((key) => allowed.includes(key));
539
- if (!keys(request, ['table', 'select', 'where', 'groupBy', 'orderBy']) || !identifier(request.table)) throw new Error('invalid structure request/table');
540
- if (!Array.isArray(request.select) || !request.select.length || request.select.length > MAX_SELECT_COLUMNS) throw new Error('structure select must contain 1..50 columns');
541
- for (const field of request.select) {
542
- if (!keys(field, ['column', 'aggregate', 'as']) || !identifier(field.column)
543
- || (field.aggregate !== undefined && !['sum', 'count', 'avg', 'min', 'max'].includes(field.aggregate))
544
- || (field.as !== undefined && (typeof field.as !== 'string' || !field.as))) throw new Error('invalid structure select field');
545
- }
546
- if (request.where !== undefined && !Array.isArray(request.where)) throw new Error('structure where must be an array');
547
- validateEavScope(request.where || []);
548
- if (request.groupBy !== undefined && (!Array.isArray(request.groupBy) || request.groupBy.some((column) => !identifier(column)))) throw new Error('invalid structure groupBy');
549
- if (request.groupBy?.length && request.select.some((field) => !field.aggregate && !request.groupBy.includes(field.column))) throw new Error('nonaggregate fields must be grouped');
550
- if (!Array.isArray(request.orderBy) || !request.orderBy.length || request.orderBy.some((item) => !keys(item, ['column', 'direction']) || !identifier(item.column) || !['asc', 'desc'].includes(item.direction))) throw new Error('structure orderBy is required');
551
- return request;
552
- }
553
-
554
- function validateEavScope(scope, reserved = 0) {
555
- if (!Array.isArray(scope) || scope.length + reserved > MAX_WHERE_CONDITIONS) throw new Error('EAV scope exceeds where limit');
556
- const scalar = (value, nullable) => (nullable && value === null) || ['string', 'boolean'].includes(typeof value) || (typeof value === 'number' && Number.isFinite(value));
557
- for (const condition of scope) {
558
- if (!condition || Object.keys(condition).some((key) => !['column', 'op', 'value'].includes(key)) || !Object.hasOwn(condition, 'value')) throw new Error('invalid EAV scope condition');
559
- if (!condition || !/^[A-Za-z0-9_]+$/.test(condition.column)
560
- || !['eq', 'neq', 'gt', 'gte', 'lt', 'lte', 'in'].includes(condition.op)) throw new Error('invalid EAV scope');
561
- if (condition.op === 'in' && (!Array.isArray(condition.value) || condition.value.length < 1 || condition.value.length > MAX_IN_VALUES || condition.value.some((value) => !scalar(value, false)))) throw new Error('EAV scope IN must contain 1..100 scalar values');
562
- if (condition.op !== 'in' && !scalar(condition.value, true)) throw new Error('EAV scope comparison must use a scalar');
563
- }
564
- return scope;
565
- }
566
-
567
- async function discoverEavKeys({ httpClient, siteBaseUrl, auth, table, keyColumn, maxKeys = 10000, onSourceRead, scope = [] } = {}) {
568
- // `maxKeys` bounds how many more PAGES we will fetch, not the exact list length: the check
569
- // runs after exhaustion, so a sweep can return up to one page beyond the cap while still
570
- // being complete. That is the right trade -- the alternative reported a table with exactly
571
- // `maxKeys` keys as truncated and blocked a complete extraction.
572
- const keys = [];
573
- const keyCounts = {};
574
- let cursor = null;
575
- let pages = 0;
576
- let truncated = false;
577
- for (;;) {
578
- // eslint-disable-next-line no-await-in-loop
579
- const page = await queryStructure({
580
- httpClient,
581
- siteBaseUrl,
582
- auth,
583
- structureRequest: {
584
- table,
585
- // The COUNT is not decoration. It is what lets the plan state how many 200-row pages
586
- // each batch will need, so "how expensive is this extraction" is answerable before
587
- // running it rather than discovered while running it.
588
- select: [{ column: keyColumn }, { column: keyColumn, aggregate: 'count', as: 'n' }],
589
- ...(scope.length ? { where: validateEavScope(scope) } : {}),
590
- groupBy: [keyColumn],
591
- orderBy: [{ column: keyColumn, direction: 'asc' }],
592
- },
593
- cursor,
594
- limit: MAX_PAGE_LIMIT,
595
- onSourceRead,
596
- });
597
- pages += 1;
598
- for (const row of page.rows) {
599
- if (typeof row[keyColumn] !== 'string') continue;
600
- keys.push(row[keyColumn]);
601
- const count = Number(row.n);
602
- keyCounts[row[keyColumn]] = Number.isFinite(count) ? count : null;
603
- }
604
- cursor = page.pagingMetadata.cursors.next;
605
- // Exhausted: complete, whatever the count. Checking the cap FIRST reported a table with
606
- // exactly `maxKeys` keys as truncated and blocked a complete extraction from promotion.
607
- if (!cursor) break;
608
- if (keys.length >= maxKeys) { truncated = true; break; }
609
- }
610
- return { keys: [...new Set(keys)], keyCounts, pages, truncated };
611
- }
612
-
613
- /**
614
- * Turn discovered key lists into the exact requests a generated reader runs to extract VALUES.
615
- *
616
- * This exists because "discover the keys, then read them" is two steps, and only the first was
617
- * ever executable from a persisted artifact. Discovery's `structure-request.json` for a
618
- * key/value table deliberately omits the guarded value columns, so a reader that runs it
619
- * verbatim extracts key NAMES and nothing else. The values are the whole point, so the second
620
- * step has to be an artifact too, not a paragraph telling a generator to improvise one.
621
- *
622
- * Three things this has to get right, each of which produced a broken plan when it did not:
623
- *
624
- * 1. **Carry the record identity.** A `postmeta` row is `{meta_key, meta_value}` plus the
625
- * `post_id` it belongs to. Without that column the extraction is a bag of values that cannot
626
- * be attributed to an order, which is worse than no extraction because it looks like data.
627
- * Every non-key, non-value column rides along; once a key is pinned they are all readable.
628
- * 2. **One pair at a time.** Selecting a second pair's value column while pinning only the
629
- * first pair's key is a request the plugin REFUSES (each value answers only to its own key).
630
- * So each pair gets its own key list, its own batches and its own select.
631
- * 3. **Order by something unique.** Pagination here is offset-based, so ordering by a
632
- * non-unique column (the key column, which repeats once per record) lets rows shift between
633
- * pages. Prefer the primary key, then a unique column; fall back to the key column only when
634
- * the table offers nothing better, and say so in the plan.
635
- *
636
- * @param keysByPair { [keyColumn]: string[] } — one discovered key list per pair.
637
- */
638
- function buildEavReadPlan({ table, eavPair, schemaColumns = [], keysByPair, countsByPair = null, batchSize = MAX_PINNED_KEYS, truncated = false, scope = [] }) {
639
- if (!eavPair) throw new Error(`table ${table}: buildEavReadPlan needs the eavPair from discover-structure`);
640
- if (!keysByPair || typeof keysByPair !== 'object') throw new Error(`table ${table}: keysByPair must be an object of keyColumn -> keys[]`);
641
- if (batchSize < 1 || batchSize > MAX_PINNED_KEYS) {
642
- throw new Error(`table ${table}: batchSize must be 1..${MAX_PINNED_KEYS} (the plugin's pinned-key cap)`);
643
- }
644
-
645
- const pairs = [{ keyColumn: eavPair.keyColumn, valueColumn: eavPair.valueColumn }, ...(eavPair.additionalPairs || [])];
646
- const keyColumns = new Set(pairs.map((pair) => pair.keyColumn));
647
- const valueColumns = new Set(pairs.map((pair) => pair.valueColumn));
648
-
649
- const named = schemaColumns.map((column) => (typeof column === 'string' ? { name: column, key: null } : column));
650
- const allIdentity = named.filter((column) => !keyColumns.has(column.name) && !valueColumns.has(column.name));
651
-
652
- // Offset pagination needs a stable, unique sort. Anything else lets a row move between pages.
653
- // ⚠️ MySQL permits MANY NULLs in a unique index, so a NULLABLE unique column can tie and is
654
- // not a stable sort. Only a primary key, or a unique column the schema reports as NOT NULL,
655
- // earns orderByIsUnique. A column whose nullability is unknown does not get the benefit of
656
- // the doubt -- claiming stable pagination and not having it is the failure being avoided.
657
- const uniqueColumn = named.find((c) => c.key === 'primary')
658
- || named.find((c) => c.key === 'unique' && c.nullable === false);
659
- const orderColumn = uniqueColumn ? uniqueColumn.name : null;
660
-
661
- // ⚠️ Two slots are RESERVED for the pair's key and value columns before identity columns are
662
- // taken. Appending them last and truncating the whole list to the select cap silently dropped
663
- // the value column on a table with 49+ identity columns -- a plan that looks complete, runs
664
- // without error, and extracts no values at all. When identity has to be trimmed, the columns
665
- // most likely to identify a record survive: the sort column, then indexed ones, then the rest.
666
- const identityBudget = MAX_SELECT_COLUMNS - 2;
667
- const ranked = [...allIdentity].sort((a, b) => rankIdentity(a, orderColumn) - rankIdentity(b, orderColumn));
668
- const identityColumns = ranked.slice(0, identityBudget).map((column) => column.name);
669
- const droppedIdentityColumns = ranked.slice(identityBudget).map((column) => column.name);
670
-
671
- let batchIndex = 0;
672
- const planPairs = pairs.map((pair) => {
673
- const counts = (countsByPair && countsByPair[pair.keyColumn]) || null;
674
- const keys = [...new Set((keysByPair[pair.keyColumn] || []).filter((k) => typeof k === 'string' && k !== ''))].sort();
675
- // identity + this pair's key + this pair's value, capped at the plugin's select limit. The
676
- // key column rides so a value can be attributed to its key without relying on request order,
677
- // which breaks the moment a key has no rows.
678
- const select = [...identityColumns, pair.keyColumn, pair.valueColumn].map((column) => ({ column }));
679
- const order = orderColumn || pair.keyColumn;
680
- const batches = [];
681
- for (let i = 0; i < keys.length; i += batchSize) {
682
- const batchKeys = keys.slice(i, i + batchSize);
683
- // Rows this batch will return, and therefore pages, when discovery supplied counts.
684
- // null when it did not -- an unknown is reported as unknown, never as zero.
685
- const expectedRows = counts ? batchKeys.reduce((sum, key) => sum + (Number.isFinite(counts[key]) ? counts[key] : 0), 0) : null;
686
- batches.push({
687
- batchIndex: batchIndex++,
688
- keyColumn: pair.keyColumn,
689
- keys: batchKeys,
690
- expectedRows,
691
- expectedPages: expectedRows === null ? null : Math.max(1, Math.ceil(expectedRows / MAX_PAGE_LIMIT)),
692
- structureRequest: {
693
- table,
694
- select,
695
- where: [...validateEavScope(scope, 1), { column: pair.keyColumn, op: 'in', value: batchKeys }],
696
- orderBy: [{ column: order, direction: 'asc' }],
697
- },
698
- });
699
- }
700
- return { ...pair, distinctKeyCount: keys.length, batches };
701
- });
702
-
703
- const plan = {
704
- planVersion: 1,
705
- table,
706
- identityColumns,
707
- // Non-empty means the table is wider than the select cap allows, so extracted rows carry
708
- // less than the full record context. Reported, never silent.
709
- droppedIdentityColumns,
710
- orderColumn: orderColumn || null,
711
- // ⚠️ false means the sort column repeats, so offset pagination can shift rows between
712
- // pages. A reader must treat that extraction as best-effort and say so.
713
- orderByIsUnique: Boolean(orderColumn),
714
- batchSize,
715
- pageLimit: MAX_PAGE_LIMIT,
716
- keysTruncated: truncated,
717
- distinctKeyCount: planPairs.reduce((sum, pair) => sum + pair.distinctKeyCount, 0),
718
- expectedBatches: batchIndex,
719
- // The real request cost, not a batch count: a single batch whose keys hold thousands of
720
- // rows needs many 200-row pages. null when discovery could not supply counts.
721
- expectedScopedRequests: planPairs.every((pair) => pair.batches.every((b) => b.expectedPages !== null))
722
- ? planPairs.reduce((sum, pair) => sum + pair.batches.reduce((n, b) => n + b.expectedPages, 0), 0)
723
- : null,
724
- pairs: planPairs,
725
- };
726
- // Identity for the checkpoint. A resume must be able to tell that the plan it is resuming
727
- // into is the plan it started: discovery can rewrite the plan between runs (the site gained
728
- // or lost keys), and continuing a half-finished extraction against a different batch layout
729
- // silently mixes two reads.
730
- plan.planHash = eavReadPlanHash(plan);
731
- return plan;
732
- }
733
-
734
- // Excluded from the hash. `planHash` because a hash cannot cover itself -- including it made the
735
- // embedded value un-recomputable from the persisted file, so nothing could ever verify it.
736
- // `acknowledgedDroppedColumns` because it is a human annotation ABOUT the plan, not part of the
737
- // read the plan describes; acknowledging an omission must not invalidate an in-flight resume.
738
- //
739
- // ⚠️ That exclusion has a consequence, and it is handled in the MANIFEST rather than here: the
740
- // acknowledgement flips reconciliation from failure to success, so if it lived nowhere else,
741
- // withdrawing it later would leave the plan hash unchanged and an incomplete extraction would
742
- // still look reusable. `eavExtractionIsReusable()` below is where that is caught -- the
743
- // approval is provenance, and provenance belongs with the artifact it approved.
744
- const PLAN_HASH_EXCLUDED_KEYS = new Set(['planHash', 'acknowledgedDroppedColumns']);
745
-
746
- /**
747
- * The canonical hash of a read plan's CONTENT.
748
- *
749
- * One function, used in three places that must agree: stamping the plan at build time,
750
- * re-deriving it from the persisted file before promotion, and checking a checkpoint on resume.
751
- * Three call sites hashing "the plan" three slightly different ways is how an integrity check
752
- * ends up unable to detect anything -- which is exactly what happened when the stamp was taken
753
- * before `planHash` existed and codegen was told to hash the finished file.
754
- *
755
- * Keys are sorted at every level so serialization order cannot change the answer.
756
- */
757
- function eavReadPlanHash(plan) {
758
- const canonical = (value) => {
759
- if (Array.isArray(value)) return value.map(canonical);
760
- if (value && typeof value === 'object') {
761
- return Object.keys(value).sort()
762
- .filter((key) => !PLAN_HASH_EXCLUDED_KEYS.has(key))
763
- .reduce((out, key) => { out[key] = canonical(value[key]); return out; }, {});
764
- }
765
- return value;
766
- };
767
- return createHash('sha256').update(JSON.stringify(canonical(plan))).digest('hex').slice(0, 16);
768
- }
769
-
770
- /**
771
- * Does this plan's embedded hash actually match its contents?
772
- *
773
- * Without this, `planHash` proves only that a checkpoint and a plan carry the same string --
774
- * so editing a batch's request while leaving the hash alone reconciled clean, which is the
775
- * tamper case an integrity check exists to catch.
776
- */
777
- function verifyEavReadPlanIntegrity(plan) {
778
- const actual = eavReadPlanHash(plan);
779
- if (plan.planHash !== actual) {
780
- return `plan ${plan.table} declares planHash ${plan.planHash} but its contents hash to ${actual} -- the plan file was edited after discovery wrote it; regenerate it rather than extracting from it`;
781
- }
782
- return null;
783
- }
784
-
785
- /** Sort key for identity columns when the select cap forces a trim: keep what identifies a row. */
786
- function rankIdentity(column, orderColumn) {
787
- if (column.name === orderColumn) return 0;
788
- if (column.key === 'primary') return 1;
789
- if (column.key === 'unique') return 2;
790
- if (column.key === 'index') return 3;
791
- return 4;
792
- }
793
-
794
- /** Every batch across every pair, in execution order. */
795
- function eavReadPlanBatches(plan) {
796
- return (plan.pairs || []).flatMap((pair) => pair.batches);
797
- }
798
-
799
- /**
800
- * Did a plan's execution actually complete? Returns the problems; empty means clean.
801
- *
802
- * Separate from execution on purpose. "It did not throw" is not completeness, and the earlier
803
- * version of this accepted any non-negative row count, so a one-row extraction of a five-batch
804
- * plan passed. Completeness here means three things, and the third is the one that catches a
805
- * page loop that stopped early:
806
- *
807
- * - every batch the plan expects was run, identified by index, not merely counted;
808
- * - each batch read as many rows as its own first page said it would (`snapshotTotal`);
809
- * - the rows actually written equal the sum of those totals.
810
- *
811
- * @param observed { batches: [{batchIndex, rowsRead, snapshotTotal}], rowsWritten }
812
- */
813
- function reconcileEavReadPlan(plan, observed) {
814
- const problems = [];
815
- const batches = (observed && Array.isArray(observed.batches)) ? observed.batches : null;
816
- if (!batches) return ['reconcileEavReadPlan needs observed.batches: [{batchIndex, rowsRead, snapshotTotal}]'];
817
-
818
- if (plan.keysTruncated) {
819
- problems.push(`key discovery hit its cap, so the key list is INCOMPLETE -- this extraction cannot be treated as whole-table`);
820
- }
821
- if (Array.isArray(plan.droppedIdentityColumns) && plan.droppedIdentityColumns.length > 0
822
- && plan.acknowledgedDroppedColumns !== true) {
823
- problems.push(
824
- `this table is wider than the ${MAX_SELECT_COLUMNS}-column select cap, so ${plan.droppedIdentityColumns.length} column(s) are absent from every extracted row `
825
- + `(${plan.droppedIdentityColumns.join(', ')}). The extraction is INCOMPLETE per record. Either narrow the table's mapping and regenerate the plan with an explicit column choice, `
826
- + 'or set acknowledgedDroppedColumns: true on the plan to record that the omission was chosen deliberately',
827
- );
828
- }
829
- if (plan.orderByIsUnique === false) {
830
- problems.push(`this table has no primary or unique column, so batches were ordered by "${plan.orderColumn}", which repeats -- offset pagination may have shifted rows between pages and the extraction is best-effort`);
831
- }
832
-
833
- // ⚠️ Duplicates and strangers are rejected BEFORE any total is computed. Collapsing them into
834
- // a Map while summing the original array let a resume that re-ran batch 0 report double its
835
- // rows and reconcile clean -- duplicated output, promoted as complete.
836
- const expectedIndices = new Set(eavReadPlanBatches(plan).map((b) => b.batchIndex));
837
- // The plan must first be internally consistent: comparing a checkpoint against a plan whose
838
- // own hash no longer describes it just confirms two strings match.
839
- const tampered = verifyEavReadPlanIntegrity(plan);
840
- if (tampered) return [tampered];
841
-
842
- // ⚠️ REQUIRED, not optional. An optional integrity check is one the documented call path
843
- // forgets to pass, and then two different plans reconcile against each other.
844
- if (observed.planHash === undefined || observed.planHash === null) {
845
- return ['reconcileEavReadPlan requires observed.planHash -- without it a checkpoint from a different plan reconciles clean'];
846
- }
847
- if (observed.planHash !== plan.planHash) {
848
- return [`this checkpoint was written against plan ${observed.planHash}, but the plan on disk is ${plan.planHash} -- discovery rewrote it, so the extraction must restart rather than resume into a different batch layout`];
849
- }
850
-
851
- const seen = new Map();
852
- for (const observation of batches) {
853
- if (!expectedIndices.has(observation.batchIndex)) {
854
- problems.push(`observed batch ${observation.batchIndex} is not in this plan -- the checkpoint belongs to a different plan`);
855
- continue;
856
- }
857
- if (seen.has(observation.batchIndex)) {
858
- problems.push(`batch ${observation.batchIndex} was recorded more than once -- a resume re-ran it and its rows are duplicated in the output`);
859
- continue;
860
- }
861
- seen.set(observation.batchIndex, observation);
862
- }
863
- if (problems.some((p) => /recorded more than once|not in this plan/.test(p))) return problems;
864
-
865
- for (const batch of eavReadPlanBatches(plan)) {
866
- const ran = seen.get(batch.batchIndex);
867
- if (!ran) {
868
- problems.push(`batch ${batch.batchIndex} (${batch.keyColumn}, ${batch.keys.length} key(s)) never ran -- the extraction is partial`);
869
- continue;
870
- }
871
- if (!Number.isInteger(ran.snapshotTotal) || !Number.isInteger(ran.rowsRead)) {
872
- problems.push(`batch ${batch.batchIndex} reported a non-integer rowsRead/snapshotTotal`);
873
- continue;
874
- }
875
- if (ran.rowsRead !== ran.snapshotTotal) {
876
- problems.push(`batch ${batch.batchIndex} read ${ran.rowsRead} of ${ran.snapshotTotal} rows -- its page loop stopped early`);
877
- }
878
- }
879
-
880
- const expectedRows = [...seen.values()].reduce((sum, b) => sum + (Number.isInteger(b.rowsRead) ? b.rowsRead : 0), 0);
881
- if (!Number.isInteger(observed.rowsWritten) || observed.rowsWritten < 0) {
882
- problems.push('rowsWritten must be a non-negative integer');
883
- } else if (observed.rowsWritten !== expectedRows) {
884
- problems.push(`wrote ${observed.rowsWritten} rows but the batches read ${expectedRows} -- the output does not match what was fetched`);
885
- }
886
- return problems;
887
- }
888
-
889
- /**
890
- * What the manifest must record about a completed EAV extraction, so a later run can decide
891
- * whether the file on disk is still usable without re-reading the source.
892
- */
893
- function eavExtractionManifest(plan, { planFile, completedBatches, rowsWritten, extractedAt, ndjsonDigest }) {
894
- if (typeof planFile !== 'string' || planFile === '') {
895
- throw new Error(`table ${plan.table}: eavExtractionManifest needs the planFile it was extracted from`);
896
- }
897
- if (typeof ndjsonDigest !== 'string' || ndjsonDigest === '') {
898
- throw new Error(`table ${plan.table}: eavExtractionManifest needs the ndjsonDigest of the promoted file -- a manifest not bound to its data describes nothing`);
899
- }
900
- return {
901
- kind: 'eav-read-plan',
902
- // Which plan produced this file. The hash proves the CONTENT matches; this says which
903
- // artifact on disk to go and re-hash, which a later run needs before it can compare.
904
- planFile,
905
- planHash: plan.planHash,
906
- completedBatches,
907
- rowsWritten,
908
- // These three qualify what the file CONTAINS, so they travel with it. A consumer must be
909
- // able to learn "rows in this file are missing columns" from the artifact rather than from
910
- // whoever happened to run the extraction.
911
- keysTruncated: Boolean(plan.keysTruncated),
912
- droppedIdentityColumns: plan.droppedIdentityColumns || [],
913
- orderByIsUnique: plan.orderByIsUnique !== false,
914
- // The APPROVAL that allowed an incomplete extraction to promote. Recorded because it is
915
- // deliberately outside planHash: without it here, withdrawing the acknowledgement would
916
- // change nothing a later run could see.
917
- acknowledgedDroppedColumns: plan.acknowledgedDroppedColumns === true,
918
- // Binds the manifest to the ACTUAL FILE. Everything else here describes the read that was
919
- // supposed to happen; this is the only field that says what landed on disk. Without it a
920
- // truncated, replaced or half-written NDJSON sitting beside a perfectly valid manifest is
921
- // accepted, and the manifest's authority is exactly what makes that dangerous.
922
- ndjsonDigest,
923
- extractedAt,
924
- };
925
- }
926
-
927
- /**
928
- * The digest recorded in a manifest and recomputed on reuse. One function so the two can never
929
- * be computed differently -- the same reasoning as eavReadPlanHash().
930
- */
931
- function eavExtractionFileDigest(contents) {
932
- return createHash('sha256').update(contents).digest('hex');
933
- }
934
-
935
- const EAV_MANIFEST_REQUIRED_FIELDS = [
936
- 'planFile', 'planHash', 'completedBatches', 'rowsWritten', 'keysTruncated',
937
- 'droppedIdentityColumns', 'orderByIsUnique', 'acknowledgedDroppedColumns', 'ndjsonDigest',
938
- 'extractedAt',
939
- ];
940
-
941
- /**
942
- * Can an existing extraction be reused, or must it be re-read? Returns the reasons it cannot;
943
- * empty means reuse is safe.
944
- *
945
- * **Re-verifies the recorded extraction rather than trusting that it happened.** An earlier
946
- * version checked only `kind`, `planHash` and the acknowledgement, so a manifest carrying
947
- * nothing but those two fields — or one recording zero completed batches, or a `rowsWritten`
948
- * that matched nothing — was accepted, and a run would skip re-extraction on the strength of a
949
- * manifest that described no extraction at all. A manifest is an assertion about a file; the
950
- * point of reading it is to check the assertion, not to accept it.
951
- *
952
- * So the checks are, in order of what makes later ones meaningless:
953
- * 1. shape — every field present and the right type;
954
- * 2. identity — the plan hash still matches, and the plan matches its own hash;
955
- * 3. completeness — the batches the manifest records must RECONCILE against the plan, the
956
- * same reconciliation the extraction itself had to pass;
957
- * 4. qualifiers — what the manifest says about the file must still be true of the plan;
958
- * 5. approval — the dropped-column acknowledgement, which is outside the hash.
959
- */
960
- function eavExtractionIsReusable(plan, manifest, observed) {
961
- if (!manifest || typeof manifest !== 'object' || Array.isArray(manifest) || manifest.kind !== 'eav-read-plan') {
962
- return ['no EAV extraction manifest -- treat the existing file as stale'];
963
- }
964
-
965
- // ⚠️ REQUIRED, and required for the same reason planHash is: a check the caller may omit is a
966
- // check the caller omits. `observed` is what is actually on disk right now -- the sidecar path
967
- // the caller itself resolved, and the digest and line count of the final file it is deciding
968
- // whether to reuse. Everything else here reasons about a read that was SUPPOSED to happen.
969
- if (!observed || typeof observed !== 'object'
970
- || typeof observed.planFile !== 'string' || observed.planFile === ''
971
- || typeof observed.ndjsonDigest !== 'string' || observed.ndjsonDigest === ''
972
- || !Number.isInteger(observed.ndjsonRowCount) || observed.ndjsonRowCount < 0) {
973
- return ['eavExtractionIsReusable requires observed: { planFile, ndjsonDigest, ndjsonRowCount } read from disk -- without them the manifest is only checked against itself'];
974
- }
975
-
976
- // 1. Shape. Reported all at once, and nothing else runs: reasoning about completeness from a
977
- // manifest that is missing fields produces confident nonsense.
978
- const shape = [];
979
- for (const field of EAV_MANIFEST_REQUIRED_FIELDS) {
980
- if (manifest[field] === undefined || manifest[field] === null) shape.push(`manifest is missing ${field}`);
981
- }
982
- if (shape.length === 0) {
983
- if (typeof manifest.planFile !== 'string' || manifest.planFile === '') shape.push('manifest planFile must be a non-empty string');
984
- if (typeof manifest.ndjsonDigest !== 'string' || manifest.ndjsonDigest === '') shape.push('manifest ndjsonDigest must be a non-empty string');
985
- if (!Array.isArray(manifest.completedBatches)) shape.push('manifest completedBatches must be an array');
986
- if (!Number.isInteger(manifest.rowsWritten) || manifest.rowsWritten < 0) shape.push('manifest rowsWritten must be a non-negative integer');
987
- if (!Array.isArray(manifest.droppedIdentityColumns)) shape.push('manifest droppedIdentityColumns must be an array');
988
- if (typeof manifest.keysTruncated !== 'boolean') shape.push('manifest keysTruncated must be a boolean');
989
- if (typeof manifest.orderByIsUnique !== 'boolean') shape.push('manifest orderByIsUnique must be a boolean');
990
- if (typeof manifest.acknowledgedDroppedColumns !== 'boolean') shape.push('manifest acknowledgedDroppedColumns must be a boolean');
991
- }
992
- if (shape.length > 0) return shape;
993
-
994
- // 2. Identity.
995
- const integrity = verifyEavReadPlanIntegrity(plan);
996
- if (integrity) return [integrity];
997
- if (manifest.planHash !== plan.planHash) {
998
- return [`the plan changed since this file was written (${manifest.planHash} -> ${plan.planHash}) -- re-extract`];
999
- }
1000
-
1001
- const reasons = [];
1002
-
1003
- // 2b. The manifest must describe THESE artifacts, not merely valid-looking ones.
1004
- //
1005
- // ⚠️ `manifest.planFile` is compared against the path the CALLER resolved; it is never opened.
1006
- // A manifest is untrusted input -- it can name `../../something-else.json` -- so treating its
1007
- // path as something to follow would let the file choose what it is validated against.
1008
- if (manifest.planFile !== observed.planFile) {
1009
- reasons.push(`manifest names plan file ${manifest.planFile} but this entity's plan is ${observed.planFile} -- the manifest belongs to a different extraction`);
1010
- }
1011
- if (manifest.ndjsonDigest !== observed.ndjsonDigest) {
1012
- reasons.push('the extracted file does not match the digest its manifest recorded -- it was truncated, replaced or half-written since promotion; re-extract');
1013
- }
1014
- if (manifest.rowsWritten !== observed.ndjsonRowCount) {
1015
- reasons.push(`the extracted file holds ${observed.ndjsonRowCount} row(s) but its manifest recorded ${manifest.rowsWritten} -- re-extract`);
1016
- }
1017
-
1018
- // 3. Completeness -- the same bar the extraction had to clear, applied to what it recorded.
1019
- reasons.push(...reconcileEavReadPlan(plan, {
1020
- planHash: manifest.planHash,
1021
- batches: manifest.completedBatches,
1022
- rowsWritten: manifest.rowsWritten,
1023
- }).map((problem) => `the recorded extraction does not reconcile: ${problem}`));
1024
-
1025
- // 4. Qualifiers. If the manifest says the file was paged on a tying sort key and the plan now
1026
- // says otherwise, one of them is describing a different read.
1027
- if (manifest.keysTruncated !== Boolean(plan.keysTruncated)) {
1028
- reasons.push(`manifest records keysTruncated: ${manifest.keysTruncated}, the plan says ${Boolean(plan.keysTruncated)} -- they describe different reads`);
1029
- }
1030
- if (manifest.orderByIsUnique !== (plan.orderByIsUnique !== false)) {
1031
- reasons.push(`manifest records orderByIsUnique: ${manifest.orderByIsUnique}, the plan says ${plan.orderByIsUnique !== false} -- they describe different reads`);
1032
- }
1033
- const dropped = plan.droppedIdentityColumns || [];
1034
- if (JSON.stringify([...manifest.droppedIdentityColumns].sort()) !== JSON.stringify([...dropped].sort())) {
1035
- reasons.push('manifest and plan disagree about which identity columns were dropped -- re-extract');
1036
- }
1037
-
1038
- // 5. Approval, which is deliberately outside the hash and so cannot be caught by step 2.
1039
- // Both sides are checked. The MANIFEST must record that this file's promotion was approved
1040
- // -- a file with missing columns and no recorded approval was never sanctioned, whatever the
1041
- // plan says today -- and the PLAN must still carry the approval, or it has been withdrawn.
1042
- if (dropped.length > 0 && manifest.acknowledgedDroppedColumns !== true) {
1043
- reasons.push(`this file has ${dropped.length} column(s) missing from every row and its manifest does not record an approval for that -- it was promoted unapproved, so re-extract rather than reuse it`);
1044
- }
1045
- if (dropped.length > 0 && plan.acknowledgedDroppedColumns !== true) {
1046
- reasons.push(`this file was promoted with ${dropped.length} column(s) missing from every row, and that omission is no longer acknowledged -- re-extract or re-acknowledge`);
1047
- }
1048
- if (manifest.acknowledgedDroppedColumns === true && dropped.length === 0) {
1049
- reasons.push('the file was promoted under a dropped-column acknowledgement that the current plan no longer needs -- re-extract so the rows carry the full record');
1050
- }
1051
- return reasons;
1052
- }
1053
-
1054
- module.exports = {
1055
- SHARED_CORE_TABLES_REQUIRING_WHERE,
1056
- validateStructureRequest,
1057
- MAX_IN_VALUES,
1058
- MAX_WHERE_CONDITIONS,
1059
- MAX_PINNED_KEYS,
1060
- MAX_PAGE_LIMIT,
1061
- MAX_SELECT_COLUMNS,
1062
- discoverEavKeys,
1063
- validateEavScope,
1064
- buildEavReadPlan,
1065
- eavReadPlanHash,
1066
- verifyEavReadPlanIntegrity,
1067
- eavExtractionManifest,
1068
- eavExtractionFileDigest,
1069
- eavExtractionIsReusable,
1070
- EAV_MANIFEST_REQUIRED_FIELDS,
1071
- eavReadPlanBatches,
1072
- reconcileEavReadPlan, HANDLER_VERSION, discoverStructure, queryStructure, guardedValueColumns, eavAccessPairs, sourceReadCounts, recordTierRefusal, violatesTierRule,
1073
- signMigrationKeyRequest, verifyMigrationKeyResponse,
1074
- };