Plugin check: Run node "${PLUGIN_ROOT}/scripts/check-version.js" — if it outputs a message, show it to the user before proceeding.
Replace every deprecated Webapi/<table>/fields = * value with the smallest
explicit column set proven by the site's actual Web API behavior.
The LLM owns source discovery, call-chain reasoning, field decisions, report
writing, and edits. Use the bundled script only to retrieve authoritative
Dataverse table schema; it must not decide which columns the code needs.
Support both:
aggregate YAML;
deployment YAML, or mixed custom JavaScript.
Initial request: $ARGUMENTS
wrappers, dynamic builders, and response consumers.
EntitySetName values to setting logical names using tableschema. Never singularize, pluralize, or guess.
* as unsupported for reads, writes, aggregates, FetchXML, files,and images.
potentially unnecessary columns.
rows first.
filter literals, request bodies, response bodies, and source snippets, and
build them only by rendering the bundled template with the bundled script.
directory.
confirmed the environment, website, site type, data model, and deployment
profile. Neither transfer can be reverted.
PUT, or DELETE Web API calls against a deployed site. Testing a write
destroys real record data.
Read references/column-analysis.md before
analyzing calls. Read
references/configuration-and-reporting.md
before inventorying settings or writing the report. Read
references/site-transfer.md before any download
or upload.
Goal: Resolve the project, confirm the site, and protect existing work.
PROJECT_ROOT from $ARGUMENTS or the current directory.powerpages.config.json indicates an SPA site;website.yml, root sitesetting.yml, or .powerpages-site/indicates downloaded declarative artifacts;
.solution-manifest.json when present. This migration changes existingsettings; do not create or select another solution.
node --version.assets/migration-report-template.html andscripts/render-migration-report.js are readable, and stop if either is
missing.
confirm the environment, website name and WebSiteId, site type, data
model, deployment profile, and target path with the user. Check each
against pac auth who, pac env who, and pac pages list, and stop on
any mismatch. Never infer one from a folder name or an active default.
Analyzing the wrong site produces confident, wrong fixes, so settle identity
before reading any setting. Download only when the user wants a fresh copy orPROJECT_ROOT holds no site content; downloading replaces local files and
cannot be reverted.
🚦 Gate (consent · migrate-webapi-selectall:1.download-site): Approve the download only after displaying the confirmed environment, website name and ID, site type, data model, target path, and the exact command. Canceling leaves local content untouched and continues against the existing copy.
Use AskUserQuestion: Download the confirmed site or Use the local copy.
Repeat step 3 after any download.
Output: Project root, site layouts, solution context, git state, confirmed
site identity, and a downloaded copy when approved.
Goal: Find every configuration and candidate source Web API call before
reasoning about columns.
Use Glob, Grep, and Read to inspect:
sitesetting.yml;*.sitesetting.yml;.powerpages-site/site-settings/;Record every Webapi/<table>/fields and Webapi/<table>/enabled entry with
its relative file, line, scope, key style, and current value. Classify fields
settings as:
wildcard;explicit;missing for an enabled table;duplicate only within the same configuration scope.Do not treat identical settings in different deployment profiles as
duplicates. Record every profile name and which settings it overrides. Never
assume the default profile is the intended deployment profile.
Query Dataverse once per unique table, never once per configuration.
Analyze only authoritative, editable source files. Never inspect compiled or
generated code.
For SPA sites:
powerpages.config.json, package.json, and present framework orbundler configuration before searching calls.
compiledPath and every configured build-output directory as a hardexclusion.
.powerpages-site/web-files/, node_modules/, coverage and cachedirectories, source maps, minified bundles, framework output directories,
and content-hashed assets matching<entry-name>-<content-hash>.<extension>.
.powerpages-site/site-settings/ only for configuration inventory,never for source analysis.
application directories.
For traditional sites, search editable JavaScript, Liquid, web templates, web
files, and other authored source. Do not exclude an authored traditional web
file merely because it is deployed as a web file.
Search source extensions including .js, .jsx, .ts, .tsx, .vue,.html, .htm, .liquid, .aspx, .ascx, .cshtml, and XML web
templates. If a call exists only in compiled, minified, generated, or
content-hashed output, record a missing-source blocker and stop the
migration. Do not infer columns from that output.
Search for:
/_api/, encoded variants, split URL fragments, and API base constants;fetch, Axios, XMLHttpRequest, jQuery AJAX, webapi.safeAjax,shell.ajaxSafePost, and custom request wrappers;
For each source candidate, record relative path, line, method, endpoint
expression, and wrapper chain. A comment, example, or non-table endpoint still
needs an explicit disposition. Excluded build outputs are never recorded.
Write the settings inventory todocs/webapi-selectall-migration/migration-report.json and render the draft
report as described in
references/configuration-and-reporting.md.
Do not propose fields yet.
Stop if any in-scope source or configuration file cannot be read.
🚦 Gate (plan · migrate-webapi-selectall:2.confirm-scope): Confirm the project, configuration scopes and profiles, wildcard count, explicit-setting count, and source inventory before schema retrieval. Canceling leaves only the read-only draft report.
Use AskUserQuestion to confirm or cancel. Expand the inventory and repeat this
phase if the user identifies another source or deployment scope.
Goal: Use authoritative names while letting the LLM determine actual usage.
Build the initial unique list containing:
Do not treat a navigation-property name as a table identifier. Its target
logical name is authoritative only after relationship metadata resolves it.
Resolve the environment URL from confirmed project context or pac env who.
If unavailable, ask for the URL as data gathering; never ask for or accept an
access token.
Write every deduplicated identifier, one per line, todocs/webapi-selectall-migration/table-identifiers.txt. Run:
node "${PLUGIN_ROOT}/skills/migrate-webapi-selectall/scripts/query-table-schema.js" --project-root "<PROJECT_ROOT>" --environment-url "<ENVIRONMENT_URL>" --tables-file "<PROJECT_ROOT>/docs/webapi-selectall-migration/table-identifiers.txt" --output "<PROJECT_ROOT>/docs/webapi-selectall-migration/table-schema.json"
If an identifier does not resolve, trace the code or obtain the correct
contract; do not guess.
After the initial snapshot:
$expand navigation property against its source table'sreturned relationship metadata.
table-identifiers-pass-<N>.txt and query them totable-schema.pass-<N>.json.
resolved.
Treat table-schema.json and all numbered snapshots as one schema package.
Never requery a logical table already present in that package, and never
launch concurrent schema queries.
Identifier lists and schema snapshots are working files. Keep them until
verification finishes, then delete them in Phase 7.
For every source inventory row:
response mappers, types, components, templates, and every caller.
configuration.
references/column-analysis.md.
mapped, non-table, or not-a-call.One logical table is normally reached from several places. Collect every call
site for a table before proposing its fields: duplicated or competing
wrappers, per-page scripts, different query shapes, and repeated calls in the
same file. A later call site for an already-analyzed table can still add
columns, so never stop at the first one.
For normal record GETs without $select, derive output fields from every
consumer and propose a source edit adding the smallest explicit projection.
Filters, ordering, and other query fields still belong in the fields setting,
even when they should not be added to the output projection.
Keep the response projection and fields-setting allowlist as separate sets.
Never add a filter-only, order-only, grouping-only, or write-only column to an
existing $select unless a response consumer also reads it.
For each wildcard setting:
logical table within the applicable site behavior.
external contract.
```text
Webapi/
| Task subject | activeForm | Description |
|---|---|---|
| Prepare migration project | Preparing migration project | Confirm the site, then resolve layouts and git state |
| Inventory Web API usage | Inventorying Web API usage | Find every configuration and source call |
| Resolve actual columns | Resolving actual columns | Retrieve schema and trace every consumer |
| Review migration plan | Reviewing migration plan | Present exact fixes and evidence |
| Apply approved migration | Applying approved migration | Edit projections and configurations |
| Verify migration results | Verifying migration results | Repeat discovery, build, and finalize report |
| Deploy and summarize | Deploying and summarizing | Publish after approval and report outcome |
Mark each task in_progress when starting and completed when finished.
Begin with Phase 1: Prepare.