Creates, updates, and deploys Power Apps generative pages for model-driven apps using React v17, TypeScript, and Fluent UI V9. Orchestrates specialist agents for planning, entity creation, and code generation. Use it when user asks to build, retrieve, or update a page in an existing Microsoft Power Apps model-driven app. Use it when user mentions "generative page", "page in a model-driven", or "genux".
73
92%
Does it follow best practices?
Impact
—
No eval scenarios have been run
Advisory
Suggest reviewing before use
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
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.mdgenpage-entity-builder — creates Dataverse entities (tables, columns,
relationships, choices, sample data) via the plugin's Node.js Web API scriptsgenpage-page-builder — generates one complete .tsx file per page; multiple
builders run in parallel for multi-page requestsEdit flow:
genpage-edit-planner — reads the downloaded page artifacts, gathers change
requirements, presents an edit plan, writes genpage-edit-plan.mdYou (the skill) coordinate the agents and own app creation, RuntimeTypes generation, deployment, browser verification, and the inline application of planned edits.
@fluentui/react-components exclusively (DatePicker from @fluentui/react-datepicker-compat, TimePicker from @fluentui/react-timepicker-compat).tsx file100vh/100vwFollow these phases in order for every /genpage invocation.
Derive a short folder name from the user's requirements:
$ARGUMENTScandidate-tracker)mkdir -p <folder-name>⚠️ CRITICAL — you MUST invoke
genpage-plannervia theTasktool. You MUST NOT inline the planner's questions yourself withAskUserQuestion.The planner is not optional or skippable. It runs:
- Prerequisite validation (
node --version,pac helpversion >= 2.7.0)- Auth verification (
pac auth list, environment selection)- The structured "Create new / Edit existing" question (via
AskUserQuestioninside the planner subagent, not here)- Language detection (
pac model list-languages) — only on new-page path- Entity existence detection (
pac model list-tables --search)- App detection (
pac model list) with proper selection prompts- Plan-mode presentation and approval
- Writes
genpage-plan.mdto the working directoryReasons 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 cleanlyEven if
$ARGUMENTSlooks 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.
genpage-planner via Task with the prompt below.{ "action": "edit" }, jump to the Edit Flow section.genpage-plan.md. Proceed to Phase 2.Pass a prompt that includes:
$ARGUMENTS${CLAUDE_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: ${CLAUDE_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.
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:
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 "${CLAUDE_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: true and identitiesMatch: true → proceed to 2b.ok: true and identitiesMatch: 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 the message field 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.
Invoke the genpage-entity-builder agent via the Task tool. Pass in the prompt:
genpage-plan.md${CLAUDE_PLUGIN_ROOT}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
<working-dir>/entity-creation-log.md for recovery on failure.
Read genpage-plan.md for the app decision and the Solution line in
## Environment.
If "create new":
pac model create --name "App Name" --solution "<Solution unique name>" --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".
Solution value verbatim. The planner always writes one
(default fallback is literally Default).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.
If any page uses Dataverse entities, generate the TypeScript schema:
pac model genpage generate-types --data-sources "entity1,entity2,..." --output-file <working-dir>/RuntimeTypes.tsWindows + 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.
Read genpage-plan.md and extract the pages table.
Before invoking any builders, verify:
## Pages table### [Page Name] subsection in ## Per-Page Specifications## Pages table 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 ${CLAUDE_PLUGIN_ROOT}/references/plan-schema.md for the full contract.
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:
${CLAUDE_PLUGIN_ROOT}/references/rules.md## Relevant SamplesNeeds caching: true, also read
${CLAUDE_PLUGIN_ROOT}/references/data-caching.md## Environment indicates non-English languages, also read
${CLAUDE_PLUGIN_ROOT}/references/localization.mdgenpage-plan.md (already in working directory) and RuntimeTypes.ts
if Data mode is dataverse.tsx file to <working-dir>/<filename>.tsx following all rules@fluentui/react-icons against
${CLAUDE_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 contextThis saves ~5-15s of Task overhead and ~3K tokens that would otherwise be duplicated in a subagent context.
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:
genpage-plan.md${CLAUDE_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: ${CLAUDE_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: ${CLAUDE_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.
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.
--prompt semantics--add-to-sitemap, no --page-id): full page description
from plan's ## User Requirements.--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.
pac model genpage upload `
--app-id <app-id> `
--code-file <working-dir>/<file>.tsx `
--name "Page Display Name" `
--data-sources "entity1,entity2" `
--prompt "<Full page description from plan's ## User Requirements>" `
--model "<current-model-id>" `
--agent-message "Description of what was built and any relevant details" `
--add-to-sitemapFor mock data pages: Same but omit --data-sources.
Use --page-id, omit --add-to-sitemap, and scope --prompt to the delta only:
pac model genpage upload `
--app-id <app-id> `
--page-id <page-id> `
--code-file <working-dir>/<file>.tsx `
--data-sources "entity1,entity2" `
--prompt "<Only the changes in this upload, e.g. 'Add a search box and sort by company name'>" `
--model "<current-model-id>" `
--agent-message "Description of what was changed in this upload"Runs only when the plan has 2+ pages AND any built .tsx contains a PAGEREF_
token. Page-builders emit pageId: "PAGEREF_<filename-without-tsx>" as a
placeholder because GUIDs don't exist until after Phase 6 (see Rule 13). This
phase substitutes the real GUIDs.
Build filename-without-tsx → page-id map from Phase 6 upload output.
Sort keys by length descending so PAGEREF_pet can't match inside
PAGEREF_pet-gallery.
For each .tsx in <working-dir>/*.tsx (top level only, no recursion),
replace every quoted "PAGEREF_<name>" (must be in double quotes — that's
the format page-builders emit) with "<page-id-guid>".
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 the delta only — not the original page description:
pac model genpage upload `
--app-id <app-id> `
--page-id <page-id-from-Phase-6> `
--code-file <working-dir>/<file>.tsx `
--data-sources "entity1,entity2" `
--prompt "Resolve cross-page navigation placeholders to real page GUIDs (post-deploy fix-up)" `
--model "<current-model-id>" `
--agent-message "Replaced PAGEREF_<name> tokens with actual page IDs returned by Phase 6"Pages with no PAGEREF_ strings need no second upload.
After successful deployment, ask the user via AskUserQuestion:
"Would you like to verify the page(s) in the browser using Playwright?"
Options: Yes, verify in browser / Skip verification
${CLAUDE_PLUGIN_ROOT}/skills/genpage/verify-flow.md
for the full Playwright verification workflow (navigate, structural
verification including below-the-fold, interactive testing, screenshots,
fix-and-redeploy). The orchestrator only loads that file on demand to keep
context lean when verification is skipped.Write a workflow-log.md file to the working directory summarizing the run:
agents invoked, commands executed, decisions made, files produced. This log is
useful for debugging and required by the eval harness.
Then present a final summary to the user:
## Genpage Complete
| Page | File | Entities | Status |
|------|------|----------|--------|
| [Name] | [file].tsx | [entities or "mock data"] | Deployed |
App: [app name] ([app-id])
Screenshots: [if verification was done]
Next steps: Share with team, iterate on design, create additional pagesFor the edit flow (triggered when the genpage-planner returns
{ "action": "edit" }), see edit-flow.md in this folder.
The edit flow has its own 8 phases (Edit Phase 1-8): discover and select target
app + page via pac model list + pac model genpage list, download, generate
RuntimeTypes if needed, invoke genpage-edit-planner, apply the edit inline,
deploy, verify, summarize.
3b2009f
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.