microsoft/powercat-overpage
Reviews the Power Pages site(s) inside a Power Platform solution .zip against best practices across Security, Performance, Accessibility, Maintainability, Architecture and Reliability — by reading the pages, web templates, custom JS/CSS, settings and table permissions and reasoning about them. Optionally also ingests a browser HAR capture (recommended) to investigate real performance bottlenecks and map them to code. Produces a [SolutionName].findings.json (validated against findings.schema.json) with solution-level, per-site and per-component findings, each with a description, a suggested fix, and (where relevant) a code or HAR anchor. Then opens the PowerCAT OverPage viewer with the solution, findings and HAR loaded so the user can explore findings overlaid on a live page preview, on the actual code, and on the network waterfall. Triggers: 'powercat overpage', 'overpage my site', 'review my power pages site', 'review this portal solution', 'evaluate this power pages solution', 'audit power pages site', 'overpage', 'power pages solution review', 'analyze power pages performance', 'review power pages with har'.
npx skills add https://github.com/microsoft/power-cat-skills --skill powercat-overpage
Review the Power Pages site(s) packaged in a Power Platform solution .zip, optionally using a
HAR capture for real performance analysis, and write a single [SolutionName].findings.json.
Then open the PowerCAT OverPage viewer with everything loaded — each finding is overlaid on a
live page preview, on the actual code (Liquid / page copy / custom JS+CSS / web files), and on the
HAR network waterfall.
This is the Power Pages counterpart to PowerCAT OverFlow (which reviews Power Automate flows).
You — the AI agent — produce the findings by reading and reasoning about the solution. There is no
bundled analyzer. Ground every finding in something inspectable (a component, a line of code, a HAR
request). The output must validate against findings.schema.json (next to this file).
Fetch the canonical Power Pages best-practice sources with web_fetch (raw: true):
https://raw.githubusercontent.com/microsoft/power-cat-skills/refs/heads/main/Common/PowerCAT%20OverPage/sources.md
Use only these URLs for the optional source citation on findings. If the fetch fails, continue but
omit source citations (don't invent URLs).
.zip (required): prefer a .zip in <tagged_files> / attachments (most recent).If none, ask via m_ask_user: "Please attach the Power Pages solution .zip you'd like me to review."
.har (optional, recommended): if a .har is attached, use it. If not, ask oncevia m_ask_user: "Optionally attach a browser HAR capture (DevTools → Network → Export HAR while
browsing the live site) — it lets me find real performance bottlenecks and map them to code.
Proceed without it?" Don't block on the answer; review the solution either way.
Remember absolute paths of both files.
Unpack the ZIP. Two Power Pages layouts are supported:
powerpagecomponents/<guid>/powerpagecomponent.xml (+ optionalfilecontent/). Each component XML has <powerpagecomponenttype>, <name>, a <powerpagesiteid>,
and a JSON <content>. Group components by powerpagesiteid — **a solution may contain several
sites; review each.** Key component types: 2=web page (content JSON has copy Liquid +
customjavascript + customcss + partialurl + parentpageid + isroot; note the enhanced data
model pairs a root page with content/language pages — merge by rootwebpageid), 8=web template
(content.source = Liquid), 6=page template, 7=content snippet, 9=site setting, 4/5=weblink
set/link, 3=web file (binary in filecontent/), 15=basic form, 17=list, 18=table
permission, 11=web role, 10=page access control rule.
pac powerpages download): web-pages/, web-templates/, etc. (adx_ YAML).For solution.name/version, read solution.xml (UniqueName, Version). A site's name often
comes from the Browser Title Suffix snippet.
Reject a classic Dataverse solution with no Power Pages site (no powerpagecomponent and no
*.webpage.yml): tell the user and stop.
For every site, raise findings across these categories: **Security, Performance, Accessibility,
Maintainability, Architecture, Reliability** (SEO optional). Each finding has a category, an
impact (high/medium/low), a description (desc), and a suggested fix (fix).
Assign a scope: solution (spans sites), site, page, or component. Guidance:
without access control; secrets in site settings; inline <script> (CSP); open registration;
user input interpolated into Liquid fetchxml.
render-blocking resources; large lists. (Use HAR in Step 4 for measured issues.)
<img> without alt, unlabeled inputs, heading-order jumps, low contrast.web files; duplicate/test/blank pages shipped (e.g. BlankPage, Testing, Copy of …).
components; tables surfaced without a clear permission model; ALM smells (test artifacts in a
managed solution).
references to web templates/snippets/web files that don't exist; broken internal links.
Per site, produce: a categories rollup, an optional site summary, optional site-level findings,
and components (findings keyed by <type>:<name>). 1–8 items per group; don't pad.
Raise findings across categories:
Each finding needs category, impact (high/medium/low), description, and suggested fix.
Parse the HAR (log.pages for per-page onLoad/onContentLoad; log.entries for requests with
sizes, timings, status, and _initiator stacks). Look for and raise Performance findings for:
onLoad (> 3 s) — describe which page and the measured time;Attach a har object to each such finding: { requestUrl, pageUrl?, kind, thirdParty }. Per the
agreed behavior, also surface third-party/CDN bottlenecks (set "thirdParty": true) anchored to
the page that loaded them — even though the fix may be "defer/remove", they're often the real cost.
When a request maps to solution code (a web file, or a page's custom JS), also add a code anchor.
Give findings the most useful anchors so the viewer can locate them:
anchor (visual, on the page preview): { "kind": "selector", "value": "<css>" },{ "kind": "match", "value": "<visible text>" }, or { "kind": "component" } for non-visual.
code (jump to source in the code viewer): { "assetPath": "...", "line": N, "match": "..." }.Asset paths the viewer exposes: web-templates/<Name>.liquid, web-pages/<Page>/copy.html,
web-pages/<Page>/custom.js, web-pages/<Page>/custom.css, web-files/<file>.
har (jump to the network request): see Step 4.A finding can carry several anchors (e.g. a perf finding with both har and code).
solution.categories (highest impact per category across all sites, with a 1–2 sentence summary),
solution.summary (narrative verdict + top 1–3 priorities + cross-site patterns), and optional
solution.findings for solution-wide issues.
Shape (authoritative: findings.schema.json):
{
"solution": { "name", "version"?, "summary", "categories":[...], "findings"?:[...] },
"sites": [
{ "id", "name", "summary"?, "categories"?:[...], "findings"?:[...],
"components": { "<type>:<name>": [ { "category","impact","items":[ {
"label","desc","fix"?,"impact","scope"?,"rule"?,"source"?,
"anchor"?:{...}, "code"?:{...}, "har"?:{...} } ] } ] } }
]
}
site.id must match the powerpagesiteid (or "site" for a single pac export).category ∈ {Security, Performance, Accessibility, Maintainability, Architecture, Reliability, SEO};impact ∈ {high, medium, low}.
findings.schema.json (required keys, enums, additionalProperties:false,anchor value required for selector/match) and fix until it passes.
Output filename: <OriginalSolutionZipBaseName>.findings.json, in the same folder as the .zip.
playwright-browser_navigate → the viewer URL (hosted when published, else http://localhost:4317/).playwright-browser_snapshot to find the inputs: Open .zip (solution), Findings (the JSON),HAR (the capture, if any).
playwright-browser_file_upload once per input with absolute paths.playwright-browser_snapshot to confirm the Overview + findings drawer rendered. The viewer hasfour views: Overview, Preview, Code, Network. Findings carry "View code" / "View request" /
"Show on page" actions that deep-link across them.
If the viewer supports it, you may instead deep-link ?site=<zip>&findings=<json>&har=<har>.
If Playwright is unavailable, Start-Process the viewer URL and give the user the file paths to load.
Write a short chat message (≤170 words):
solution.categories (Category · impact)..findings.json.End with: "Handing over — explore the findings overlaid on each page, the code, and the network in the open viewer."
ground each finding in a component, code line, or HAR request.
findings.schema.json.<componentType>:<componentName> exactly; site.id matches powerpagesiteid.sources.md in source.Take microsoft/powercat-overpage from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.