Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
microsoft avatar

Genpage

  • 140 installs
  • 605 repo stars
  • Updated August 4, 2026
  • microsoft/power-platform-skills

Power Apps genpage skill creating generative pages with React Fluent UI V9 for model-driven apps.

About

Power Platform genpage skill for generative pages in model-driven apps. Orchestrates specialist agents for planning, entity creation, and code generation using React v17, TypeScript, and Fluent UI V9. Covers page creation, updates, and deployment to model-driven app environments. Large workflow skill coordinating multi-agent generation of data-connected pages with Power Platform entity integration and Fluent UI component patterns.

  • Generative pages for model-driven apps with React v17 TypeScript Fluent UI V9
  • Orchestrates specialist agents for planning entity creation code gen
  • Create update and deploy generative page workflows
  • Model-driven app environment deployment
  • Multi-agent coordination for page generation

Genpage by the numbers

  • 140 all-time installs (skills.sh)
  • +7 installs in the week ending Aug 4, 2026 (Skillselion tracking)
  • Ranked #968 of 2,245 Frontend Development skills by installs in the Skillselion catalog
  • Security screen: LOW risk (skills.sh audit)
  • Data as of Aug 5, 2026 (Skillselion catalog sync)
At a glance

genpage capabilities & compatibility

Capabilities
create generative page · deploy model driven page · orchestrate page agents
Works with
azure
Use cases
frontend · ui design
From the docs

What genpage says it does

Creates, updates, and deploys Power Apps generative pages for model-driven apps using React v17, TypeScript, and Fluent UI V9.
SKILL.md
npx skills add https://github.com/microsoft/power-platform-skills --skill genpage

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs140
repo stars605
Security audit3 / 3 scanners passed
Last updatedAugust 4, 2026
Repositorymicrosoft/power-platform-skills

How do I create or deploy a generative page in a model-driven app?

Create, update, and deploy Power Apps generative pages for model-driven apps using React v17, TypeScript, and Fluent UI V9.

Who is it for?

Developers building generative pages in Power Apps model-driven apps.

Skip if: Code apps with Vite or deprecated generate-canvas-app skill.

When should I use this skill?

User creates updates or deploys Power Apps generative pages.

What you get

Generative page created updated and deployed with React TypeScript Fluent UI V9.

Files

SKILL.mdMarkdownGitHub ↗

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: 1. `genpage-planner` — validates prerequisites, gathers requirements, detects what entities and apps exist, presents a plan for approval, writes genpage-plan.md 2. `genpage-entity-builder` — creates Dataverse entities (tables, columns, relationships, choices, sample data) via the plugin's Node.js Web API scripts 3. `genpage-page-builder` — generates one complete .tsx file per page; multiple builders run in parallel for multi-page requests

Edit flow:

4. `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
  • Troubleshooting: troubleshooting.md
  • Sample pages: samples/

Development Standards

  • React 17 + TypeScript — all generated code
  • Fluent UI V9@fluentui/react-components exclusively (DatePicker from @fluentui/react-datepicker-compat, TimePicker from @fluentui/react-timepicker-compat)
  • Single file architecture — all components, utilities, styles in one .tsx file
  • 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:

1. Extract the page name or a 2-4 word summary from $ARGUMENTS 2. Convert to kebab-case (e.g., "Candidate Tracker" → candidate-tracker) 3. Create the folder: mkdir -p <folder-name> 4. 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" <working-dir> <kebab-slug>
  • <kebab-slug> 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

1. Invoke genpage-planner via Task with the prompt below. 2. Wait for it to finish (it returns a summary). 3. If the return includes { "action": "edit" }, jump to the Edit Flow section. 4. 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: 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.

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 <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 Solution value 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 <working-dir>/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 ## Pages table
  • Every page has a ### [Page Name] subsection in ## Per-Page Specifications
  • All filenames in the `## 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 ${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:

1. Read ${PLUGIN_ROOT}/references/rules.md 2. Read the sample listed in the plan's ## Relevant Samples 3. If the plan's Per-Page Specification has Needs caching: true, also read ${PLUGIN_ROOT}/references/data-caching.md 4. If the plan's ## Environment indicates non-English languages, also read ${PLUGIN_ROOT}/references/localization.md 5. Read genpage-plan.md (already in working directory) and RuntimeTypes.ts if Data mode is dataverse 6. Write the .tsx file to <working-dir>/<filename>.tsx following all rules 7. After writing, Grep every named import from @fluentui/react-icons against ${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 8. 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 <id> --code-file <path> --data-sources '<entities>' --prompt "<full prompt>" --model <model-id> --name "<page name>" --agent-message "<description>" --add-to-sitemap`
- Result: page-id = <returned-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 <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-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 <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"

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_<filename-without-tsx>" as a placeholder because GUIDs don't exist until after Phase 6 (see Rule 13). This phase substitutes the real GUIDs.

Steps

1. Build filename-without-tsx → page-id map from Phase 6 upload output. 2. Sort keys by length descending so PAGEREF_pet can't match inside PAGEREF_pet-gallery. 3. 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>". 4. If a placeholder doesn't match any map key (typo, missing sibling), stop and report — never silently ship the literal string. 5. 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.

Phase 7: Verify in Browser (Optional)

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

  • If the user picks Skip verification → jump to Phase 8.
  • If the user picks Yes → read ${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.

Phase 8: Summary

By Phase 8 the workflow-log.md should already contain Phase 0 through Phase 7 sections written incrementally — the planner writes Phase 1 inside its agent context, you (the orchestrator) write Phase 0 / 0.5 / 3 / 4 / 6 / 6.5 / 7 as each runs, and the entity-builder and page-builder agents append their own Phase 2 / 5 sections when invoked.

In Phase 8, append a final ## Phase 8 — Summary section to the same file:

## Phase 8 — Summary

| Page | File | Entities | Status |
|------|------|----------|--------|
| <Name> | <file>.tsx | <entities or "mock data"> | Deployed |

- App: <name> (<app-id>)
- Entities created: <list, or "none">
- Browser verification: <skipped | confirmed | failed: <reason>>

The log MUST contain command-level entries for every prereq / auth / question / upload / script invocation — not just outcome summaries. The eval harness greps the log for tokens like node --version, pac auth list, AskUserQuestion, EnterPlanMode, --prompt, check-auth.js, etc. A decision-only log (e.g., Decision: new page without the underlying AskUserQuestion) will fail Layer 1 assertions even when the agent's behavior was correct.

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 pages

---

Edit Flow

For 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.

Related skills

FAQ

What UI stack?

React v17, TypeScript, and Fluent UI V9.

What app type?

Generative pages for model-driven apps, not canvas code apps.

How is work orchestrated?

Specialist agents for planning, entity creation, and code generation.

Is Genpage safe to install?

skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.