Install
$ agentstack add skill-microsoft-power-platform-skills-genpage ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Power Apps Generative Pages Builder
Triggers: genpage, generative page, create genpage, genux page, build genux, power apps page, model page Keywords: power apps, generative pages, genux, model-driven, dataverse, react, fluent ui, pac cli Aliases: /genpage, /gen-page, /genux
Overview
This skill orchestrates four specialist agents across the create and edit flows:
Create flow:
genpage-planner— validates prerequisites, gathers requirements, detects what
entities and apps exist, presents a plan for approval, writes genpage-plan.md
genpage-entity-builder— creates Dataverse entities (tables, columns,
relationships, choices, sample data) via the plugin's Node.js Web API scripts
genpage-page-builder— generates one complete.tsxfile per page; multiple
builders run in parallel for multi-page requests
Edit flow:
genpage-edit-planner— reads the downloaded page artifacts, gathers change
requirements, presents an edit plan, writes genpage-edit-plan.md
You (the skill) coordinate the agents and own app creation, RuntimeTypes generation, deployment, browser verification, and the inline application of planned edits.
References
- Code generation rules: [rules.md](../../references/rules.md)
- Troubleshooting: [troubleshooting.md](../../references/troubleshooting.md)
- Sample pages: [samples/](../../samples/)
Development Standards
- React 17 + TypeScript — all generated code
- Fluent UI V9 —
@fluentui/react-componentsexclusively (DatePicker from@fluentui/react-datepicker-compat, TimePicker from@fluentui/react-timepicker-compat) - Single file architecture — all components, utilities, styles in one
.tsxfile - No external libraries — only React, Fluent UI V9, approved Fluent icons, D3.js for charts
- Type-safe DataAPI — use RuntimeTypes when Dataverse entities are involved
- Responsive design — flexbox, relative units, never
100vh/100vw - Accessibility — WCAG AA, ARIA labels, keyboard navigation, semantic HTML
- Complete code — no placeholders, TODOs, or ellipses in final output
Instructions
Follow these phases in order for every /genpage invocation.
Phase 0: Create Working Directory
Derive a short folder name from the user's requirements:
- Extract the page name or a 2-4 word summary from
$ARGUMENTS - Convert to kebab-case (e.g., "Candidate Tracker" →
candidate-tracker) - Create the folder:
mkdir -p - Resolve its absolute path — this is the working directory for all subsequent phases
Phase 0.5: Initialize Local-Dev Manifest
Write package.json and genpage.d.ts into the working directory so the developer can npm install and get IntelliSense, type-checking, and "go to definition" in their editor. Versions come from references/supported-dependencies.md (single source of truth: scripts/lib/supported-dependencies.js).
node "${PLUGIN_ROOT}/scripts/generate-page-manifest.js"
- `` is the same slug used for the working directory.
- Add
--features charts,datepicker,timepicker(comma-separated) only when
the requirements clearly call for them; otherwise omit and keep the manifest lean.
- The script is idempotent — it skips files that already exist. Pass
--force to overwrite (used in regeneration flows when versions drift).
- Output is a JSON summary on stdout; pipe to stderr for visibility but do
not block the workflow if the script returns non-zero — the manifest is a dev-ergonomics aid, not part of the deployed artifact.
Phase 1: Plan
> ⚠️ CRITICAL — you MUST invoke genpage-planner via the Task tool. You MUST > NOT inline the planner's questions yourself with AskUserQuestion. > > The planner is not optional or skippable. It runs: > 1. Prerequisite validation (node --version, pac help version >= 2.7.0) > 2. Auth verification (pac auth list, environment selection) > 3. The structured "Create new / Edit existing" question (via AskUserQuestion > inside the planner subagent, not here) > 4. Language detection (pac model list-languages) — only on new-page path > 5. Entity existence detection (pac model list-tables --search) > 6. App detection (pac model list) with proper selection prompts > 7. Plan-mode presentation and approval > 8. Writes genpage-plan.md to the working directory > > Reasons to NEVER ask "new or edit?" yourself before invoking the planner: > - You would skip prereq + auth (the planner is the only thing that runs them) > - The structured question gives the user labeled options; an inline free-text > prompt forces them to guess > - The planner returns { "action": "edit" } as a contract — your inline > question can't produce that signal cleanly > > Even if $ARGUMENTS looks like it tells you the intent, still invoke the > planner. Pass the intent in the prompt — the planner uses it to skip its > own Question 1 if appropriate, but the prereq/auth/env steps still run.
Steps
- Invoke
genpage-plannerviaTaskwith the prompt below. - Wait for it to finish (it returns a summary).
- If the return includes
{ "action": "edit" }, jump to the Edit Flow section. - Otherwise the planner has written
genpage-plan.md. Proceed to Phase 2.
Invocation prompt
Pass a prompt that includes:
- The user's requirements:
$ARGUMENTS - The working directory (absolute path from Phase 0)
- The plugin root path:
${PLUGIN_ROOT}
Example:
> You are the genpage-planner agent. Plan generative page(s) for the following requirements: > > [paste $ARGUMENTS here verbatim, or "no arguments provided — gather from user"] > > Working directory: [absolute path from Phase 0] > Plugin root: ${PLUGIN_ROOT} > > Follow the instructions in your agent file. Validate prereqs, confirm auth, ask > the new/edit question via AskUserQuestion, then proceed accordingly. Write > genpage-plan.md to the working directory if creating. Return the page list, > entity status, app selection, and any { "action": "edit" } signal when complete.
Phase 2: Create Entities (Conditional)
Read genpage-plan.md from the working directory. Check the Entity Creation Required section.
If the section literally says "No entity creation required — all entities already exist": Skip to Phase 3.
If entities need creating:
2a. Pre-flight: az + pac + Dataverse
Entity creation runs through the plugin's Node.js Web API scripts using az for auth, and the az and pac identities should normally match. Run the consolidated pre-flight:
node "${PLUGIN_ROOT}/scripts/check-auth.js"
It returns a single JSON object:
{
"ok": true | false,
"blocker": null | "az_missing" | "az_not_logged_in" | "pac_not_logged_in"
| "no_env_url" | "whoami_403" | "whoami_401" | "whoami_error",
"message": "human-readable next step",
"azUser": "...", "pacUser": "...", "envUrl": "...",
"identitiesMatch": true | false,
"whoAmI": { "ok": true, "userId": "...", "organizationId": "..." }
}
ok: trueandidentitiesMatch: true→ proceed to 2b.ok: trueandidentitiesMatch: false→ proceed to 2b but surface the
message to the user as an inline warning ("az is X, pac is Y — WhoAmI works for now, but if entity creation later returns 403, run the suggested az login --username to align them").
ok: false→ show themessagefield to the user verbatim and
stop the workflow. The script already includes a fix-it command for every blocker (run az login, etc.).
Capture envUrl from the result — Phase 2b passes it to the entity-builder.
2b. Invoke entity-builder
Invoke the genpage-entity-builder agent via the Task tool. Pass in the prompt:
- Path to
genpage-plan.md - Working directory (absolute path)
- Plugin root:
${PLUGIN_ROOT} - Dataverse env URL (from
pac org who)
The entity-builder reads Solution and Publisher Prefix directly from the plan's ## Environment — no need to re-thread them here.
Wait for completion. The builder writes a transactional log at /entity-creation-log.md for recovery on failure.
Phase 3: App Creation/Selection
Read genpage-plan.md for the app decision and the Solution line in ## Environment.
If "create new":
pac model create --name "App Name" --solution "" --publish
--solution is mandatory. pac model create errors out with "The given solution name is not valid: ()" if you omit it — its claimed "active solution" fallback does not work in practice.
--publish is mandatory. Without it the new appmodule stays in draft and the genux runtime URL errors with "app not published".
- Use the plan's
Solutionvalue verbatim. The planner always writes one
(default fallback is literally Default).
- If the plan is somehow missing
Solution, pass--solution Default—
every Dataverse env has a built-in "Default Solution" by that unique name.
Store the new app-id for Phase 6.
If existing app-id: Use it directly. pac model create is not called, so the Solution line is informational only for this phase.
Phase 4: Generate RuntimeTypes (Conditional)
If any page uses Dataverse entities, generate the TypeScript schema:
pac model genpage generate-types --data-sources "entity1,entity2,..." --output-file /RuntimeTypes.ts
> Windows + Bash: Always use forward slashes in file paths (e.g., D:/temp/RuntimeTypes.ts).
After generating, read the RuntimeTypes.ts file to verify it generated correctly.
For mock data pages only: Skip this phase.
Phase 5: Build Pages (Parallel)
Read genpage-plan.md and extract the pages table.
5a. Validate the plan before dispatch
Before invoking any builders, verify:
- At least one page exists in the
## Pagestable - Every page has a
### [Page Name]subsection in## Per-Page Specifications - All filenames in the
## Pagestable are unique. If any are duplicated,
rewrite the plan appending -1, -2, etc. before dispatch. Duplicate filenames cause silent last-writer-wins data loss under parallel execution.
See ${PLUGIN_ROOT}/references/plan-schema.md for the full contract.
5b. Single-page fast path (skip Task dispatch when N=1)
If the plan's Pages table contains exactly one row, do NOT dispatch a Task subagent. Inline the page-builder workflow directly in the orchestrator:
- Read
${PLUGIN_ROOT}/references/rules.md - Read the sample listed in the plan's
## Relevant Samples - If the plan's Per-Page Specification has
Needs caching: true, also read
${PLUGIN_ROOT}/references/data-caching.md
- If the plan's
## Environmentindicates non-English languages, also read
${PLUGIN_ROOT}/references/localization.md
- Read
genpage-plan.md(already in working directory) andRuntimeTypes.ts
if Data mode is dataverse
- Write the
.tsxfile to/.tsxfollowing all rules - After writing, Grep every named import from
@fluentui/react-iconsagainst
${PLUGIN_ROOT}/references/verified-icons.txt (one Grep per name). Rewrite any unverified names with the closest verified alternative; do not load the full icon list into context
- Proceed to Phase 6
This saves ~5-15s of Task overhead and ~3K tokens that would otherwise be duplicated in a subagent context.
5c. Multi-page: invoke page-builders in parallel
If the plan's Pages table contains 2+ rows, invoke a genpage-page-builder agent via the Task tool per page. Fire all invocations in a single message for parallel execution.
For each page, pass a prompt that includes:
- Page name (e.g., "Candidate Tracker")
- Target file name (e.g., "candidate-tracker.tsx")
- Absolute path to
genpage-plan.md - Data mode (see below) — either a RuntimeTypes path or an explicit mock flag
- Working directory
- Plugin root:
${PLUGIN_ROOT}
For Dataverse pages, include the RuntimeTypes line:
> You are the genpage-page-builder agent. Generate the [Page Name] page. > > - Target file: [filename].tsx > - Plan document: [absolute path to genpage-plan.md] > - Data mode: dataverse > - RuntimeTypes: [absolute path to RuntimeTypes.ts] > - Working directory: [absolute path from Phase 0] > - Plugin root: ${PLUGIN_ROOT} > > Follow the instructions in your agent file. Write [filename].tsx and return your > result when done.
For mock data pages, omit the RuntimeTypes line and set Data mode: mock:
> You are the genpage-page-builder agent. Generate the [Page Name] page. > > - Target file: [filename].tsx > - Plan document: [absolute path to genpage-plan.md] > - Data mode: mock > - Working directory: [absolute path from Phase 0] > - Plugin root: ${PLUGIN_ROOT} > > Follow the instructions in your agent file. Write [filename].tsx and return your > result when done.
Wait for all page-builder tasks to complete before proceeding.
Phase 6: Deploy
For each .tsx file produced, deploy to Power Apps.
Copy the upload commands below exactly — --app-id, --code-file, --prompt, --agent-message are all required and must use these exact flag names.
Log the full command verbatim into workflow-log.md under a ## Phase 6 — Deploy section before invoking it. Including --prompt and all other flags. The eval harness greps the log for these tokens — a terse summary like Command: pac model genpage upload --add-to-sitemap will fail the --prompt scoping assertion. Format:
## Phase 6 — Deploy
- Command: `pac model genpage upload --app-id --code-file --data-sources '' --prompt "" --model --name "" --agent-message "" --add-to-sitemap`
- Result: page-id = , status = success
--prompt semantics
- First upload (
--add-to-sitemap, no--page-id): full page description
from plan's ## User Requirements.
- Any subsequent upload (
--page-id, no--add-to-sitemap): delta only —
the changes in this upload, written like a commit message, never a re-statement of the original.
Applies in Phase 6 updates, Phase 6.5 PAGEREF re-uploads, Phase 7.5 fix re-deploys, and the entire edit flow.
For Dataverse entity pages (first upload — create):
pac model genpage upload `
--app-id `
--code-file /.tsx `
--name "Page Display Name" `
--data-sources "entity1,entity2" `
--prompt "" `
--model "" `
--agent-message "Description of what was built and any relevant details" `
--add-to-sitemap
For mock data pages: Same but omit --data-sources.
For updating existing pages (subsequent upload):
Use --page-id, omit --add-to-sitemap, and scope --prompt to the delta only:
pac model genpage upload `
--app-id `
--page-id `
--code-file /.tsx `
--data-sources "entity1,entity2" `
--prompt "" `
--model "" `
--agent-message "Description of what was changed in this upload"
Phase 6.5: Navigation Fix-Up (Multi-Page Only)
Runs only when the plan has 2+ pages AND any built .tsx contains a PAGEREF_ token. Page-builders emit pageId: "PAGEREF_" as a placeholder because GUIDs don't exist until after Phase 6 (see Rule 13). This phase substitutes the real GUIDs.
Steps
- Build
filename-without-tsx → page-idmap from Phase 6 upload output. - Sort keys by length descending so
PAGEREF_petcan't match inside
PAGEREF_pet-gallery.
- For each
.tsxin/*.tsx(top level only, no recursion),
replace every quoted "PAGEREF_" (must be in double quotes — that's the format page-builders emit) with "".
- If a placeholder doesn't match any map key (typo, missing sibling), stop
and report — never silently ship the literal string.
- Re-upload only the files that had at least one replacement. Use the update form
of pac model genpage upload (--page-id, no --add-to-sitemap). Per the "--prompt semantics" rule in Phase 6, this is an update, so --prompt describes th
…
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: microsoft
- Source: microsoft/power-platform-skills
- License: MIT
- Homepage: https://aka.ms/ppskills
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.