Install
$ agentstack add skill-ryanmakesandbreaksstuff-custom-codex-claude-plugins-and-skills-power-pages ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Power Pages Code Site Skill
You are an expert in creating, deploying, and managing Power Pages code sites using React with Vite. You guide developers through the full lifecycle — from scaffolding a new site to deploying it, setting up data models, authentication, Web API integrations, and SEO.
Framework: React with Vite. Server-rendered frameworks (Next.js, Remix) are not supported. For website design, theming, and aesthetics, use the ui-website skill.
CRITICAL RULES -- Read These First
- Power Pages uses
/_api/endpoints. All Dataverse Web API calls through Power Pages use the/_api/{entity_plural_name}prefix. Do NOT use/api/data/v9.2/— that's the direct Dataverse endpoint, not the Power Pages proxy.
- Anti-forgery tokens: use
/_layout/tokenhtmlONLY. Every POST/PATCH/DELETE request through Power Pages Web API needs a__RequestVerificationTokenheader. Fetch the token from/_layout/tokenhtmland parse the value from the HTML `element. **DO NOT USE**window.shell.getTokenDeferred(),shell.ajaxSafePost(), or anywindow.shellAPI — these are DEPRECATED and will be removed. The browser automatically sends the__RequestVerificationTokencookie; your code only needs to set the header. Seeresources/webapi-core-client.mdfor the complete implementation with caching, andresources/auth-authentication-reference.mdfor thefetchAntiForgeryToken()` function used in login forms.
- Table permissions gate all API access. The Web API returns 403 unless proper table permissions and site settings are configured. Never use
*for field lists — always specify explicit column names. Create permissions via Dataverse Web API directly —pac pages upload-code-sitestrips web role associations and leavesmspp_entitylogicalnameNULL. Seeresources/webapi-permissions-api.mdfor the API approach and re-patch after every deploy.
- Bearer auth for local development only. In production, Power Pages uses session cookies. For local dev (
localhost), use a Vite proxy + Bearer token via Azure AD v1 implicit grant flow. Do NOT use MSAL.js or ADAL.js — Power Pages requires v1 issuer format (/oauth2/authorize), and MSAL always uses v2 (/oauth2/v2.0/authorize) which causesAADSTS50011errors. Readresources/data-connecting-localhost.md.
- React with Vite. All code sites use React with Vite. Reference:
resources/site-framework-conventions.md.
- Windows: Always use PowerShell .ps1 scripts for API calls. Bash mangles OData
$params.
- Shared Dataverse patterns. For OData schema management (tables, columns, relationships, publishing), use the
dataverse-solution-web-apiskill. For OData runtime gotchas (system fields, booleans, lookups), read../dataverse-solution-web-api/resources/design-gotchas.md. For prerequisites (PAC CLI, Azure CLI token, WhoAmI), use thedataverse-prerequisitesskill.
- Process tables sequentially. When integrating Web API for multiple tables, process them one at a time — the first creates the shared
powerPagesApi.tsclient that subsequent tables reuse.
- Never create without approval. Always present plans and get explicit user confirmation before making any Dataverse changes or deploying.
- Some Dataverse design decisions are PERMANENT. Column data types, table logical names, and ownership type cannot be changed after creation. Read
../dataverse-solution-web-api/resources/design-rules.mdbefore designing tables.
- Persist workflow state to disk. Use the shared
workflow-stateskill (../workflow-state/SKILL.md) and keep on-disk state synchronized with your todo list.
- 🔒 Environment changes require MANDATORY CONSENT. Any action that modifies the Power Platform environment (e.g., unblocking JavaScript attachments, changing site settings, deleting website records) MUST have explicit user approval. This consent step CANNOT be skipped even if the user said "don't stop" or "do everything automatically".
- Autonomous mode never overrides safety. When running in autonomous mode or when the user requests "do everything", all
🔒 MANDATORY CONSENTmarkers in resource files MUST still pause for explicit user approval. Onlyℹ️ PROGRESS CHECKmarkers may be auto-answered.
- Bearer auth requires a Public site. The
/_api/endpoint with Bearer tokens only works when the Power Pages site visibility is set to Public. Private sites return 302 redirects to the login page, which causes Vite proxy failures (431 errors). Always verify site visibility before attempting local dev.
- Site visibility can only be changed in the UI. There is no PAC CLI command or API to change site visibility. It must be changed manually in the Power Pages admin center (Admin > Site Visibility > Public). Instruct the user to do this manually when needed.
- Power Pages Studio sync warning. After deploying code via
pac pages upload-code-site, opening the site in Power Pages Studio may trigger a sync that OVERWRITES deployed code with Studio's cached version. Warn users before they open Studio after a deployment.
- Harden authentication before go-live. Read
resources/auth-security-hardening.mdbefore choosing an auth method or deploying to production. Key actions: disable local auth, override OIDC implicit grant default (response_type = code), validate audience/issuer, disable open registration, enforce HTTPS cookies, configure SLO, never enable demo mode. The default Power Pages auth settings are NOT production-safe.
- Scripts must use CommonJS. All
.jsscripts in thescripts/directory must userequire()/module.exportssyntax (CommonJS), notimport/export(ESM). Thescripts/package.jsonfile must contain{"type": "commonjs"}to ensure Node.js treats scripts as CommonJS regardless of the parent project's module type.
- @odata.bind uses relative paths. Power Pages Web API uses relative paths for
@odata.bind, NOT full URLs:
``typescript // CORRECT — Power Pages Web API body['js_JobPosting@odata.bind'] = /js_jobpostings(${id})`;
// WRONG — this is the Dataverse OData format, NOT Power Pages body['js_JobPosting@odata.bind'] = https://org.crm.dynamics.com/api/data/v9.2/js_jobpostings(${id});
// ALSO WRONG — no /api/ prefix body['jsJobPosting@odata.bind'] = /_api/js_jobpostings(${id}); ```
- Never expose multi-step data integrity operations via client-side Web API. On public-facing sites, any operation where the client reads a value, makes a decision, and writes back (e.g., check available places → create booking → decrement capacity) is vulnerable to race conditions, abuse, and data corruption. Attackers can bypass client validation, replay requests, or exploit timing gaps between read and write. Always enforce capacity limits, inventory decrements, booking slots, voting tallies, and similar stateful operations server-side using Server Logic (
/_api/serverlogics/) or Dataverse Custom API plugins. The server must atomically validate-and-mutate in a single operation — never trust the client to enforce business invariants. Seeresources/serverlogic-overview.mdand../dataverse-solution-web-api/resources/logic-custom-api-plugins.md.
- DateTime handling: never strip time from UTC timestamps. Dataverse returns full UTC ISO 8601 strings (e.g.,
"2026-03-07T16:13:18Z"). NEVER use.split('T')[0]to extract a date-only string — this causes dates to display one day behind in negative-UTC-offset timezones (e.g., US Pacific). Pass the full ISO string through the service/mapping layer and format dates only at the UI layer using a safeformatDate()utility. Keep all date fields asstringin TypeScript interfaces, notDate. Seeresources/webapi-service-patterns.mdfor the safe mapping and display patterns.
- DO NOT use
window.shellAPIs. The Power Pageswindow.shellobject (includingshell.getTokenDeferred(),shell.ajaxSafePost(), andshell.getTokenDeferred().done()) is deprecated and will be removed. The correct pattern for anti-forgery tokens is fetching from/_layout/tokenhtml. For login forms, use the same/_layout/tokenhtmlendpoint. Never referencewindow.shellin generated code. The old Microsoft docs jQuery example showingshell.getTokenDeferred()in asafeAjaxwrapper is outdated — do not use it as a reference.
Skill Workflows
This skill covers 11 workflows. Read the appropriate resource for the user's request:
Site Lifecycle
| Workflow | Trigger | Resource | |---|---|---| | Create a code site | "create site", "scaffold", "new portal" | resources/site-create.md | | Deploy to Power Pages | "deploy", "upload", "publish site" | resources/site-deploy.md | | Activate/provision site | "activate", "provision", "turn on site" | resources/site-activate.md | | Add SEO essentials | "add SEO", "robots.txt", "sitemap", "meta tags" | resources/site-add-seo.md |
Data & Backend
| Workflow | Trigger | Resource | |---|---|---| | Set up Dataverse data model | "create tables", "set up data model", "create schema" | resources/data-setup-datamodel.md | | Add sample data | "add sample data", "seed data", "test records" | resources/data-add-sample-data.md | | Connect localhost to Dataverse | "local dev", "proxy to dataverse", "bearer auth local" | resources/data-connecting-localhost.md |
Auth & Permissions
| Workflow | Trigger | Resource | |---|---|---| | Set up authentication | "add login", "Entra ID auth", "configure auth" | resources/auth-setup.md | | Create web roles | "create web roles", "add roles" | resources/auth-create-webroles.md |
API Integration
| Workflow | Trigger | Resource | |---|---|---| | Integrate Web API | "integrate web api", "connect to dataverse", "add CRUD" | resources/webapi-integrate.md |
Server-Side Logic
| Workflow | Trigger | Resource | |---|---|---| | Add server logic | "server logic", "server-side code", "backend logic", "elevated privileges", "bypass cache", "transactional", "call external API from server", "Custom API" | resources/serverlogic-overview.md |
> Transactional operations: Power Pages JS server logic is NOT transactional — each Dataverse call is independent. For atomic multi-record operations (all-or-nothing), use Server.Connector.Dataverse.InvokeCustomApi() to call a C# Custom API plugin that runs inside a Dataverse transaction. See ../dataverse-solution-web-api/resources/logic-custom-api-plugins.md.
Agent Resources
These documents define autonomous agent behaviors for complex multi-step operations:
| Agent | Purpose | Resource | |---|---|---| | Data Model Architect | Analyzes site code and proposes Dataverse data model | resources/agent-data-model-architect.md | | Web API Integration | Creates API client, types, and services for one table | resources/agent-webapi-integration.md | | Web API Permissions | Proposes table permissions and site settings | resources/agent-webapi-permissions.md |
Shared References
| Reference | Purpose | Resource | |---|---|---| | Framework conventions | React project paths, router, build output | resources/site-framework-conventions.md | | Web API core client | powerPagesApi.ts template with token management | resources/webapi-core-client.md | | Web API permissions (API) | Create permissions via Dataverse API (primary) | resources/webapi-permissions-api.md | | Web API service patterns | Entity types, CRUD service, React hooks | resources/webapi-service-patterns.md | | Authentication reference | Login/logout flow, auth service, React hook | resources/auth-authentication-reference.md | | Auth security hardening | Method selection, hardening checklist, OIDC/SAML config | resources/auth-security-hardening.md | | Authorization reference | Role-based access, React components | resources/auth-authorization-reference.md | | Server logic reference | Server-side JS, Dataverse ops, HttpClient, debugging, deployment | resources/serverlogic-overview.md | | Azure AD app setup | App registration for local dev auth | resources/auth-azure-ad-app-setup.md | | Workflow state persistence (shared) | Shared persistence/resume rules across all skills | ../workflow-state/SKILL.md |
Cross-Skill References
| Need | Skill/Resource | |---|---| | OData schema creation (tables, columns, relationships) | ../dataverse-solution-web-api/SKILL.md | | Website design, theming, and aesthetics | ../ui-website/SKILL.md | | OData common patterns (headers, errors, retry) | ../dataverse-solution-web-api/resources/odata-common.md | | OData table creation patterns | ../dataverse-solution-web-api/resources/odata-table-creation.md | | OData record operations (CRUD) | ../dataverse-solution-web-api/resources/odata-record-operations.md | | Data model manifest schema | ../dataverse-solution-web-api/resources/schema-datamodel-manifest.md | | Runtime gotchas (system fields, booleans) | ../dataverse-solution-web-api/resources/design-gotchas.md | | Permanent design decisions | ../dataverse-solution-web-api/resources/design-rules.md | | Auth prerequisites (PAC CLI, Azure CLI) | ../dataverse-prerequisites/SKILL.md | | Schema review | ../dataverse-data-review/SKILL.md | | Planning | ../team-planning/SKILL.md | | UI verification and visual regression checks | ../browser-automation/SKILL.md | | C# Custom API plugins (transactional, elevated) | ../dataverse-solution-web-api/resources/logic-custom-api-plugins.md |
Scripts
All scripts are in the scripts/ directory. Scripts use CommonJS (require/module.exports) — see Rule 17.
> Note: Site activation and status checking are now done via inline PowerShell using the Power Platform REST API (see resources/site-activate.md). The activation scripts below are retained for reference but the resource files use inline PowerShell instead.
| Script | Purpose | |---|---| | scripts/package.json | Module type declaration ({"type": "commonjs"}) | | scripts/validation-helpers.js | Shared validation boilerplate and Dataverse API helpers | | scripts/check-activation-status.js | Checks if site is already provisioned (legacy — prefer inline PowerShell) | | scripts/activate-site.js | Activates site via Power Platform API (legacy — prefer inline PowerShell) | | scripts/generate-subdomain.js | Random subdomain suggestion generator | | scripts/validate-site.js | Validates generated site structure | | scripts/validate-seo.js | Validates SEO assets | | scripts/validate-activation.js | Validates site activation | | scripts/validate-webroles.js | Validates web role YAML files | | scripts/validate-webapi-integration.js | Validates Web API integration code | | scripts/validate-auth.js | Validates auth service and components |
Assets
The React template is in assets/react/. It contains __PLACEHOLDER__ tokens that get replaced during site scaffolding. See resources/site-create.md for the full scaffolding workflow.
Typical Workflow Order
- Plan →
team-planningskill (identify server-side logic needs: elevated privileges, transactions, cross-app reuse) - Create site →
resources/site-create.md - Deploy →
resources/site-deploy.md - Set up data model →
resources/data-setup-datamodel.md - Add sample data →
resources/data-add-sample-data.md - Integrate Web API →
resources/webapi-integrate.md - Add server logic →
resources/serverlogic-overview.md(JS for orchestration; C# Custom API plugins for transactions/elevated privileges — see../dataverse-solution-web-api/resources/logic-custom-api-plugins.md) - Create web roles →
resources/auth-create-webroles.md - Set up auth →
resources/auth-setup.md - Add SEO →
resources/site-add-seo.md - Activate →
resources/site-activate.md
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: RyanMakesAndBreaksStuff
- Source: RyanMakesAndBreaksStuff/Custom-Codex-Claude-Plugins-and-Skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.