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 <folder-name> - Resolve its absolute path — this is the working directory for all subsequent phases
Phase 1: Plan
**⚠️ CRITICAL — you MUST invokegenpage-plannervia theTasktool. 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 helpversion >= 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:
${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.
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 "${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: 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:
${CLAUDE_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 <working-dir>/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 "<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".
- Use the plan's
Solutionvalue verbatim. The planner always writes one
(default fallback is literally Default).
- If the plan is somehow missing
Solution, pass `--solu