rp-discovery
Discovers and documents the source platform schema (entities, fields, relationships) for a migration project. Use when capturing source structure before…
npx skills add https://github.com/wix/skills --skill rp-discoveryrp-discovery
Discover and document the source-platform schema for the active migration project.
Purpose
Use this skill to inspect the source system, identify entities, relationships, fields, identifiers, media, rich content, and platform-specific constraints. Examples include Shopify, WordPress, WooCommerce, and custom CMS platforms.
This skill owns the platform-agnostic discovery process and its output contract
(source-profile.md + source-schema.json). Platform-specific details — how to capture a
given source, its auth model, REST quirks — live in a dedicated source adapter skill,
not here. For WordPress / WooCommerce, that adapter is rp-source-wordpress. To support a
new platform, add a sibling adapter (e.g. rp-source-shopify) and leave this skill
unchanged.
Inputs
Expected inputs may include:
migrations/<project>/orchestration/run.jsonmigrations/<project>/orchestration/decisions.json- source site/app URL
- source platform name when it cannot be inferred
- source acquisition mode when the platform offers multiple read paths
- source API docs
- credentials, tokens, or local dump files when available
- export files when the run is file-based rather than URL-based
- current project under
migrations/<project>/ - project-local config under
migrations/<project>/config/
Config gate before capture
Before running source capture, verify the project-local config files created by
replatform:
config/wix.envshould always exist withWIX_SITE_STRATEGY,WIX_SITE_ID, andWIX_AUTH_TOKENkeys, even though discovery itself may not use Wix credentials yet.config/source.<platform>.envshould exist once the source platform is known. For WordPress this isconfig/source.wordpress.env.
If a required key is missing or blank, ask the user for that value and fill the config file for them before continuing. Ask one value at a time. Never print secret values back to the user; report only present/missing.
Treat migrations/<project>/config/*.env as secret-bearing once they may contain real
values. Do not inspect them with whole-file reads that echo contents into tool output.
Use secret-safe checks only: existence, required key names, and present / blank /
missing status.
Site creation precedence
If this skill encounters conflicting Wix guidance about how to create a new site +
headless destination, replatform's migration contract wins.
- Route headless destination creation back to the Wix CLI headless scaffold defined in
replatform→ "Headless site creation" (npm create @wix/new@latest headless). This is the verified way to get a genuine headless site; the account-level Projects API is deprecated for this workflow (it produced non-headless sites). - Discovery is source-side and does not create the site itself — just defer to that section.
Workflow
-
Confirm the active project under
migrations/<project>/. -
Start from the source URL when available and try to identify the source platform yourself before asking the user. Use lightweight signals such as a REST index, headers, HTML/application markers, or platform-specific route patterns. Only ask the user to name the platform if detection remains inconclusive.
-
Once the platform is inferred, resolve the acquisition mode before requesting source credentials when the platform has materially different read paths.
- For Shopify URL-based migrations, ask whether to use the
Admin APIor only publicly availablestorefrontdata. - For WordPress / WooCommerce URL-based migrations, ask whether to import
public content onlyoralso include private/authenticated data. - Only the WordPress / WooCommerce
also include private/authenticated databranch should trigger a credentials request. Thepublic content onlybranch proceeds without credentials and should be described as limited to public data. For WooCommerce, this branch should still probe public Store API catalog routes such as/wc/store/v1/productsand/wc/store/v1/products/categoriesbefore declaring commerce out of scope. Treat file/export ingestion as a separate flow that starts from user-provided files instead of a site URL probe; do not offer exports as a third option in the URL-based acquisition-mode question.
- For Shopify URL-based migrations, ask whether to use the
-
Then select the matching source adapter skill (e.g.
rp-source-wordpressfor WordPress / WooCommerce,rp-source-csvwhen the run is file-based). If no adapter exists for the platform, capture entities manually following the same output contract.- File-based runs (
sourceMode=files_only,sourcePlatform=csv) userp-source-csvregardless of which system produced the files; that adapter identifies the originating vendor from the header row. There is no acquisition-mode question and no credentials request for this path.
- File-based runs (
-
Run the adapter's capture step to produce a raw, machine-captured dump under
<migrations-root>/<project>/data/<source>-discovery/. For WordPress, the capture script lives inrp-source-wordpress/scripts/— run it from that skill directory (seerp-source-wordpressCapture section andCONVENTIONS.md). The adapter owns the capture mechanics, auth model, and platform quirks; this skill consumes its output. For long runs, pass--progress-log <path>and poll it perCONVENTIONS.md#progress-log-polling.- Distinguish supported entities (advertised by the source) from used entities
(those with
recordCount > 0). Entities advertised but empty should be flagged, not mapped as if they hold data. - A capture made without credentials is usually incomplete (gated entities, private fields, PII return 401/403). Do not treat an unauthenticated capture as authoritative — the adapter documents what auth a complete run requires.
- For WordPress / WooCommerce captures, read
data/wp-discovery/skipped-routes.jsonwhen present. Treat it as the canonical route-scope audit trail: skipped routes are evidence, not source entities, unless they were explicitly force-included by an audited override. - For CSV captures, the capture script lives in
rp-source-csv/scripts/csv-discovery.jsand takes the whole file set in one run (--fileis repeatable) so roles and split files resolve together. Readdata/csv-discovery/fileset.json— it is the canonical machine capture, andsource-schema.jsonis synthesized from it:- carry
sourceFiles[](withrole,vendor,partOf),vendor,dialect,drift,mappingHints, andcsvInputRootintosourceMeta, keeping file paths relative tocsvInputRootso the project stays movable; - give every entity an
origin(file-rows|row-group|column-values) with the parameters that origin needs, and sethierarchical: trueon nested derived entities so the mapper's faithfulness-ledger rule fires; - surface
drift.unmappedColumnsasunknownsso the mapper handles them explicitly; - honor
halt: true. An ambiguous layout, an unknown file role, conflicting split-file headers, or a near-miss vendor detection is a question for the user, not something to resolve by picking the highest-scoring candidate. The warning text names the decision to put to them.
- carry
- Distinguish supported entities (advertised by the source) from used entities
(those with
-
Capture field-level schema details, including type, cardinality, requiredness, and example values.
-
When bundled Wix domain knowledge recognizes a source route or source entity, annotate the discovered entity with
sourceMeta.candidateTargetRefs[]such as["stores/product"]. Discovery must still record source facts only; these refs are mapper hints, not target decisions. -
Note operational constraints such as pagination, rate limits, auth model, and incremental sync options. If the source base URL or discovered media/file URLs use
localhost,127.0.0.1, or another private-only host, record a media reachability note insource-profile.md. Localhost is fine for discovery and local source reads, but Wix Media import is URL-based and Wix servers cannot fetch the user's localhost. This is an optional preparation step and, as far as we know today, only affects media import. State the two acceptable choices:- expose the source with a public HTTPS tunnel such as ngrok before live media import
- skip/defer media import while continuing non-media entities
Include concise ngrok setup instructions when relevant:
brew install ngrok ngrok config add-authtoken "<YOUR_AUTHTOKEN>" ngrok http 8090 export WP_BASE_URL=https://<id>.ngrok-free.app -
Synthesize the raw capture into the normalized artifacts below.
Artifacts to create or update
-
migrations/<project>/discovery/run.json -
migrations/<project>/discovery/entities/ -
migrations/<project>/discovery/warnings.json -
migrations/<project>/discovery/llm-handoff.json -
migrations/<project>/orchestration/checkpoints.json -
migrations/<project>/data/<source>-discovery/: raw machine-captured output from the source adapter. Treated as evidence, not a hand-off artifact — downstream skills reference it for traceability but do not read it wholesale. -
migrations/<project>/source-profile.md: source platform, access method, limits, auth, and operational notes. Synthesized from the raw capture. Capture the operational facts the adapter documents (auth model, pagination, rate limits) sorp-import-codegenhas them without re-deriving. -
migrations/<project>/source-schema.json: machine-readable schema for entities and fields. Synthesized from the raw capture — this andsource-profile.mdare the canonical hand-off torp-mapper. Include traceability pointers so the mapper can drill into a specific entity's raw file when needed:- top-level
rawDiscovery: relative path to the raw capture dir, e.g.data/wp-discovery/. - per-entity
rawFile: file name within that dir, e.g.wp-v2--posts.md. - per-entity
recordCountandinUseso consumers can distinguish supported vs. actually-used entities. - per-entity
relationsderived from the source-declared relationships in the raw capture, so relationships are evidence-backed rather than guessed. Each relation should carry anevidencepointer back to the source signal it came from. - For WordPress / WooCommerce, synthesize entities only from sampled
backend_dataand acceptedbackend_metadataroute artifacts. Do not synthesize entities from routes listed inskipped-routes.jsonunless the skipped-route record hasincludedByOverride: true; in that case, includeoriginalDiscoveryCategory,includedByOverride: true, andoverrideReasonwhen present in the entitysourceMeta. - Follow the adapter's
source-schema.example.jsonfor the shape (e.g.rp-source-wordpress/source-schema.example.json). It is a template to follow, not a strict schema to validate against — keep the platform-agnostic core stable and push platform quirks into each entity's opensourceMetablob.
- top-level
-
Optional supporting notes under
migrations/<project>/research/if needed.
Output quality rules
- Separate confirmed facts from assumptions.
- Record per-entity volume (record counts) so downstream skills know what the site actually uses, not just what it supports.
- Preserve source-specific identifiers exactly.
- Include enough detail for downstream mapping and code generation.
- Flag unknowns explicitly instead of inventing structure.