| name | powerapps-code-app |
| description | Extend Power Apps Code Apps conversationally — add Dataverse tables, Power Platform connectors (Office 365, SQL, SharePoint, Copilot Studio), Power Automate flows, run locally, and push to Power Platform. Use when the user wants to wire data into a code app, asks about pac code, npx power-apps, pac connection list, power.config.json, add-data-source, add-flow, or asks to test/deploy a code app. Trigger on: add Dataverse table, connect to Dataverse, add a connector, add Office 365, add SQL connection, add SharePoint list, add a flow, integrate Power Automate, run code app locally, push code app, deploy to Power Apps. Do NOT trigger for: model-driven apps, canvas apps (non-code), PCF code components — those use different tooling. |
powerapps-code-app
Orchestrator for extending Power Apps Code Apps. Drives the full loop: discover state → plan work → add data → wire UI → test locally → push to Power Platform. Prefers the newer npm CLI (npx power-apps), falls back to pac code where the npm CLI hasn't reached parity (Dataverse + non-flow connectors).
CLI choice (read first)
| Operation | Preferred | Fallback | Notes |
|---|
| Init project | npx power-apps init | pac code init | Needs @microsoft/power-apps ≥ 1.0.4 for npm CLI |
| Add Dataverse table | pac code add-data-source -a dataverse -t <name> | — | npm CLI does not yet support this |
| Add connector | pac code add-data-source -a <api> -c <id> | — | npm CLI does not yet support this |
| Add Power Automate flow | npx power-apps add-flow --flow-id <id> | — | npm CLI only. Needs SDK ≥ 1.1.1 |
| Run local | npm run dev | — | Same for both |
| Push to cloud | npx power-apps push | pac code push | Use after npm run build |
Full command reference: references/08-cli-cheatsheet.md.
Safety rules
- Read-only operations run without confirmation:
pac auth list, pac env who, pac connection list, pac code list-*, pac --version, npx power-apps list-flows, npm --version, reading power.config.json / package.json, npm run dev.
- Mutations require
AskUserQuestion confirmation: pac code add-data-source, pac code delete-data-source, npx power-apps add-flow, npx power-apps remove-flow, npx power-apps push, pac code push, npm install (any version bump), any file write under src/.
- Never edit files under
src/generated/ — they are regenerated by the CLI. If the schema changes, delete + re-add the data source.
Workflow
Step 0 — Bootstrap context
Run scripts/preflight.ps1 once at session start (it's a single PowerShell call that emits one JSON blob). Parse it and summarize in 4–6 lines:
- PAC CLI: <version> (auth: <profile or "not signed in">)
- npm CLI: <version> | npx power-apps: <version or "not available">
- SDK @microsoft/power-apps: <version> (flows supported: yes/no — needs ≥ 1.1.1)
- Env in power.config.json: <environmentId> (matches pac env who: yes/no)
- Data sources wired: <count> (<names>)
- Flows wired: <count> (<names>)
If preflight returns non-zero (no power.config.json or package.json), tell the user this directory is not a Power Apps code app and offer to scaffold one with npx degit github:microsoft/PowerAppsCodeApps/templates/vite my-app.
If preflight surfaces deep blockers (auth expired, env ID mismatch, unknown auth state), spawn the prereq-doctor sub-agent for triage — see "Sub-agent invocation" below.
Step 1 — Phase router
Use AskUserQuestion to confirm what the user wants. Build the options dynamically from preflight output:
- If
pacAuthOk == false → first option must be "Sign in to Power Platform (pac auth create)".
- If
envIdMatchesConfig == false → flag the mismatch as a blocker before continuing.
- If
sdkSupportsFlows == false and the user mentions flows → first option is "Upgrade @microsoft/power-apps to latest".
- Always offer: "Add Dataverse table", "Add connector", "Add Power Automate flow", "Test locally", "Push to Power Platform".
The user can pick multiple. Sequence the work: Dataverse → connectors → flows → test → deploy.
Step 2 — Execute phases
For each phase, load the matching reference file and follow its procedure. Gate every mutation behind AskUserQuestion.
Phase: Add Dataverse table
- Ask the user for the logical name (singular, lowercase — e.g.
contact, account, new_governanceitem). Reject display names.
- Confirm:
pac code add-data-source -a dataverse -t <name> (show the exact command).
- Run. On success, verify
src/generated/services/<Pascal>Service.ts exists.
- Offer to spawn dataverse-wirer to scaffold a typed hook + sample UI.
Full procedure: references/02-dataverse.md.
Phase: Add connector
- Read references/03-connectors.md. Connectors need a pre-created connection in the maker portal — surface
https://make.powerapps.com/connections and wait for the user to confirm they've created one.
- Run
pac connection list (read-only, no confirm needed). Show the user the table, ask them to pick a row (or paste the connection ID).
- For tabular sources (SQL / SharePoint), run discovery helpers (
pac code list-datasets, pac code list-tables) before assembling the final command.
- Confirm:
pac code add-data-source -a <api> -c <id> [-t <table> -d <dataset> | -sp <storedProc>]. For ALM portability, suggest the -cr <connectionReferenceLogical> -s <solutionId> variant when the user mentions environment promotion.
- Run. Offer dataverse-wirer for UI scaffolding.
Phase: Add Power Automate flow
- Check
sdkSupportsFlows. If false, confirm and run npm install @microsoft/power-apps@latest first.
- Read references/04-flows.md. Remind the user: flow must be solution-aware + PowerApps trigger only.
- Run
npx power-apps list-flows [--search <query>] (read-only). Show the table.
- Confirm:
npx power-apps add-flow --flow-id <guid>.
- Run. Verify generated files at
src/services/<FlowName>Service.ts, src/models/<FlowName>Model.ts, schemas/logicflows/<FlowName>.Schema.json.
Phase: Test locally
Follow references/05-testing-local.md. Run npm run dev, surface the Local Play URL. Always repeat the two critical reminders:
- Open the URL in the same browser profile as your Power Platform tenant — otherwise auth fails silently.
- Since Dec 2025, Chrome/Edge block local-network access by default. Grant the prompt when it appears.
Phase: Push to Power Platform
Spawn the deploy-runner sub-agent — see "Sub-agent invocation".
Step 3 — Closing summary
End-of-turn: 1–2 sentences listing exactly what was added (table/flow names, file paths) and the deployed URL if a push happened. Example:
Added Dataverse table contact → generated src/generated/services/ContactsService.ts + ContactsModel.ts. Pushed to https://apps.powerapps.com/play/e/Default-…/a/…
Sub-agent invocation
Use the Agent tool with subagent_type: general-purpose. Read the agent prompt file, append context, pass as the prompt parameter. The agent files are self-contained — do not paraphrase them.
prereq-doctor
Fire when preflight surfaces non-trivial blockers (auth state ambiguous, env mismatch, PAC missing, multiple auth profiles, undeployed app conflicts). Reads agents/prereq-doctor.md.
Agent({
subagent_type: "general-purpose",
description: "Diagnose Power Apps Code App env",
prompt: <contents of agents/prereq-doctor.md> + "\n\n# Project path\n<absolute path>"
})
dataverse-wirer
Fire after a data source is successfully added, when the user wants UI scaffolding ("create a hook for contacts", "build me a list component", "wire it into the home page"). Reads agents/dataverse-wirer.md.
Pass the data source name, kind (dataverse | connector | flow), the generated service + model file paths, and any column subset the user mentioned.
deploy-runner
Fire for the deploy phase (npm run build + push). Reads agents/deploy-runner.md.
Pass the project path and CLI preference (npm or pac). Sub-agent returns { status, url, durationMs } or a classified error.
Best practices to enforce (always)
When the wirer (or the orchestrator itself) generates code that uses generated services, it MUST follow references/07-best-practices.md:
- Always pass
select to getAll — never pull full row width.
- Partial updates only — only the changed fields.
- Use connection references (not raw connection IDs) for anything that will move between Dev/Test/Prod.
- Use
import type { … } for generated models.
- Exclude system-managed fields (
accountid, ownerid, etc.) on create.
When the skill should stop
- User explicitly says "stop", "cancel", "never mind".
- A mutation prompt is rejected — do not retry. Move on or ask what to do instead.
- Preflight detects this isn't a code app and the user declines to scaffold one.
- An irrecoverable error (auth flow can't complete, network unreachable to make.powerapps.com).