genpage

作者: microsoft

使用 React v17、TypeScript 和 Fluent UI V9 建立、更新及部署 Power Apps 生成式頁面,適用於模型驅動應用程式。完成從…開始的工作流程。

npx skills add https://github.com/microsoft/power-platform-skills --skill genpage

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:

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

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.

來自 microsoft 的更多技能

oss-growth
microsoft
開源增長駭客角色
official
microsoft-foundry
microsoft
端到端部署、評估與管理 Foundry 代理:Docker 建置、ACR 推送、託管/提示代理建立、容器啟動、批次評估、持續評估、提示最佳化工作流程、agent.yaml、從追蹤資料集整理。用途:將代理部署至 Foundry、託管代理、建立代理、調用代理、評估代理、執行批次評估、持續評估、持續監控、持續評估狀態、最佳化提示、改善提示、提示最佳化器、最佳化代理指令、改善代理...
officialdevelopmentdevops
azure-ai
microsoft
用於 Azure AI:搜尋、語音、OpenAI、文件智慧。協助搜尋、向量/混合搜尋、語音轉文字、文字轉語音、轉錄、OCR。適用情境:AI 搜尋、查詢搜尋、向量搜尋、混合搜尋、語意搜尋、語音轉文字、文字轉語音、轉錄、OCR、將文字轉換為語音。
officialdevelopmentapi
azure-deploy
microsoft
對已準備好的應用程式執行 Azure 部署,這些應用程式需具備現有的 .azure/deployment-plan.md 與基礎架構檔案。當使用者要求建立新應用程式時,請勿使用此技能——應改用 azure-prepare。此技能會執行 azd up、azd deploy、terraform apply 及 az deployment 命令,並內建錯誤復原機制。需具備來自 azure-prepare 的 .azure/deployment-plan.md,以及來自 azure-validate 的驗證狀態。適用時機:「執行 azd up」、「執行 azd deploy」、「執行部署」……
officialdevopsaws
azure-storage
microsoft
Azure Storage Services 包括 Blob 儲存體、檔案共用、佇列儲存體、表格儲存體和 Data Lake。回答關於儲存存取層(熱、冷、凍結、封存)、各層使用時機及層級比較的問題。提供物件儲存、SMB 檔案共用、非同步訊息、NoSQL 鍵值及大數據分析。包含生命週期管理。用於:blob 儲存體、檔案共用、佇列儲存體、表格儲存體、data lake、上傳檔案、下載 blob、儲存帳戶、存取層...
officialdevelopmentdatabase
azure-diagnostics
microsoft
在 Azure 上使用 AppLens、Azure Monitor、資源健康狀態和安全分類來偵錯 Azure 生產問題。適用時機:偵錯生產問題、疑難排解應用程式服務、應用程式服務高 CPU、應用程式服務部署失敗、疑難排解容器應用程式、疑難排解函數、疑難排解 AKS、kubectl 無法連線、kube-system/CoreDNS 失敗、Pod 擱置、CrashLoop、節點未就緒、升級失敗、分析記錄、KQL、深入解析、映像提取失敗、冷啟動問題、健康狀態探查失敗...
officialdevopsdevelopment
azure-prepare
microsoft
準備 Azure 應用程式以進行部署(基礎架構 Bicep/Terraform、azure.yaml、Dockerfile)。用於建立/現代化或建立+部署;不適用於跨雲端遷移(請使用 azure-cloud-migrate)。請勿用於:copilot-sdk 應用程式(請使用 azure-hosted-copilot-sdk)。適用時機:「建立應用程式」、「建置 Web 應用程式」、「建立 API」、「建立無伺服器 HTTP API」、「建立前端」、「建立後端」、「建置服務」、「現代化應用程式」、「更新應用程式」、「新增驗證」、「新增快取」、「託管於 Azure」、「建立並...」
officialdevelopmentdevops
azure-validate
microsoft
部署前驗證 Azure 就緒狀態。對設定、基礎架構(Bicep 或 Terraform)、RBAC 角色指派、受控身分權限及先決條件進行深度檢查,再進行部署。適用時機:驗證我的應用程式、檢查部署就緒狀態、執行預檢檢查、驗證設定、確認是否可部署、驗證 azure.yaml、驗證 Bicep、部署前測試、疑難排解部署錯誤、驗證 Azure Functions、驗證函式應用程式、驗證無伺服器...
officialdevopstesting