publish-pcf-companion
Deploy the dispatcher PCF for a third-party `.ppmplugin` control to a Power Platform environment via `pac pcf push`. The dispatcher PCF is the Studio-side control that dispatches the composite key `<name>/<receiver>` over the wrap shell's `SendMessagePlugin` bridge to the control's native module. Verifies deploy prereqs (Node.js 20+ with npm, .NET SDK, and active `pac auth`), then three confirmation gates — publisher prefix (2–8 chars; defaults to `pamext` or the last-used value from `.extension-state.md`), version bump (patch / minor / major / no-bump), target environment URL (from `pac org who`). Builds the PCF if needed, then pushes. Decoupled from /generate-pcf-companion so the engineer can scaffold and customize locally, then deploy when ready. Updates `.extension-state.md` with deployment history (timestamp, env URL, version, prefix used).
git clone --depth 1 https://github.com/microsoft/power-platform-skills /tmp/publish-pcf-companion && cp -r /tmp/publish-pcf-companion/plugins/power-apps-mobile-extension/skills/publish-pcf-companion ~/.claude/skills/publish-pcf-companionSKILL.md
# /publish-pcf-companion
On-demand deployment of the **dispatcher PCF** for a third-party `.ppmplugin` control to a Power Platform environment. The dispatcher PCF is the Studio-side control that dispatches the composite key `<name>/<receiver>` over the wrap shell's `SendMessagePlugin` bridge to the control's native module. Runs `pac pcf push` against the user's active `pac auth` profile. Decoupled from `/generate-pcf-companion` — the engineer scaffolds locally, customizes / iterates, then deploys when ready.
---
## Step 1 — Read shared docs and verify prereqs
1. Read [`shared/shared-instructions.md`](../../shared/shared-instructions.md), [`shared/naming-conventions.md`](../../shared/naming-conventions.md).
2. Apply the **per-skill minimal prereq policy** ([`shared-instructions.md §1.5`](../../shared/shared-instructions.md)). This skill needs Node.js 20+ with npm, `pac` CLI, .NET SDK, and an active `pac auth` profile. It does not need pnpm.
**Print the prereq status as a visible block per `shared-instructions.md §9.2`** before continuing:
```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Prereq check — /publish-pcf-companion
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🟢 ✓ Node.js 20+ and npm installed (for npm install / npm run build)
🟢 ✓ pac CLI installed (for pac pcf push)
🟢 ✓ .NET SDK installed (solution build runs inside pac pcf push)
🟢 ✓ pac auth profile active (target env: <env URL from pac org who>)
🟢 4 checks passed. Ready to proceed.
```
Fix table for failures:
| Missing | `→ Fix:` line in the failure block |
|---|---|
| Node.js / npm | Install Node.js 20 LTS from `https://nodejs.org`, then verify with `node -v` and `npm -v` |
| `pac` CLI | `dotnet tool install -g Microsoft.PowerApps.CLI.Tool` (chains on .NET SDK first if also missing) |
| .NET SDK | `brew install dotnet` (mac) / `winget install Microsoft.DotNet.SDK.10` (win) / package manager (linux) |
| No active `pac auth` | `pac auth create --environment <your-env-url>` (interactive browser flow; use an identity with access to the target Power Platform environment). **Do not reach for `--deviceCode` first** — it's a headless-shell fallback that commonly fails under Conditional Access. |
Run the `/publish-pcf-companion` check from [`prereq-check.md`](../../shared/prereq-check.md). Per the auto-fix policy (shared-instructions §1.5): a missing `pac` CLI is auto-fixable when .NET is present — **offer `dotnet tool install -g Microsoft.PowerApps.CLI.Tool` and continue on `yes`**; no active `pac auth` → **initiate `pac auth create --environment <url>`** (browser) and verify after. If an auth attempt *fails*, walk the variant ladder in [`prereq-check.md`](../../shared/prereq-check.md) (browser → device code only if headless → back to browser with `--environment` → `pac auth clear`) — change a variable each step and never re-run a variant that already failed. A missing **.NET SDK** hard-stops (system-wide install — print the command).
3. Read `./PRD.md`. Required — the skill derives the PCF folder name (`pcf/<Pascal>PCF/`) and publisher prefix from PRD §2. If PRD is missing, STOP with `BLOCKED: PRD.md missing — cannot determine PCF folder name`.
4. Read `./.extension-state.md` if present. The state file is informational; this skill works without it but uses Phase info to surface "scaffold-pcf hasn't happened yet" early.
---
## Step 2 — Detect current state
Build a status dashboard so the user sees what was detected before any action.
**Discover the PCF folder robustly** — don't assume the exact nesting depth. Use Glob to find
`pcf/**/ControlManifest.Input.xml` and select the first match. `pac pcf init` normally produces
`pcf/<Pascal>PCF/<Pascal>PCF/ControlManifest.Input.xml`, but case differences and manual
restructuring should not break discovery. If `pcf/` is absent, stop with
`BLOCKED: no pcf/ directory — PCF has not been scaffolded. Run /generate-pcf-companion first.` If
`pcf/` exists but the manifest is absent, list the relevant files with Glob and stop with
`BLOCKED: pcf/ exists but no ControlManifest.Input.xml was found.`
Derive the PCF project root from the manifest path by moving up two directory levels. Use Glob to
check whether `<PCF_PROJECT_ROOT>/out/` exists. Use Read to extract the `<control version="X.Y.Z">`
value from the manifest and the latest deployment version from `.extension-state.md`. Run
`pac org who` to retrieve the active environment because that is a real toolchain command.
Print:
```
PCF deploy status
─────────────────
Repo: <cwd>
PCF project root: <PCF_PROJECT_ROOT from find>
Manifest: <MANIFEST path>
Built (out/): <yes | no — will build now>
Current manifest version: <CURRENT_VERSION>
Last deployed version: <LAST_DEPLOYED or "none — first deploy">
Publisher prefix: <LAST_PREFIX from .extension-state.md, else `pamext` default — confirmed in Step 3.0>
Active pac auth env: <env URL from `pac org who`>
Active pac auth user: <user from `pac org who`>
Plan: pick publisher prefix → bump version if chosen → build if needed → pac pcf push --publisher-prefix <chosen prefix>
```
**Why the version matters:** Power Platform caches PCF controls by version in deployed apps. If you re-push the same version, apps that already loaded the previous bundle may not see your changes until their cache invalidates (timing varies — sometimes minutes, sometimes hours, sometimes never until the maker re-publishes the app). **Best practice is to bump the patch version on every meaningful push.**
If `pac org who` returns "No active connection": STOP — this means `pac auth list` showed a profile but it's not currently selected. Run `pac auth select --index <n>` and re-run this skill. (Step 1 catches missing auth; this catches the rarer "auth exists but not active" case.)
> **Why Glob instead of an exact path:** the standard layout is nested two levels below the project
> rooGuide the user to add a data source, connection, or API connector to a Canvas App via Power Apps Studio, then verify and continue. USE WHEN the user asks to add a data source, add a connection, add an API, add a connector, connect to SharePoint / Dataverse / SQL / Excel / OneDrive / Teams / Office 365, or any similar request to make new data available to the app. DO NOT USE WHEN the user is asking to list or describe existing data sources — call list_data_sources or list_apis directly instead.
Creates or edits a Power Apps Canvas App through the Canvas Authoring MCP coauthoring session. Handles new app generation, direct targeted edits, complex multi-screen changes, responsive layout, per-screen self-QA, and compile-error convergence. Trigger on requests to create, build, generate, modify, update, change, fix, or edit a Canvas App or .pa.yaml files.
Configure the Canvas Authoring MCP server for the current coauthoring session. USE WHEN "configure MCP", "set up MCP server", "MCP not working", "connect Canvas Apps MCP", "canvas-authoring not available", "MCP not configured", "set up canvas apps".
[DEPRECATED — use canvas-app instead] Generate a complete Power Apps canvas app.
>
Adds Azure DevOps connector to a Power Apps code app. Use when querying work items, creating bugs, managing pipelines, or making ADO API calls.
Use when adding a Power Platform connector to an Expo/React Native Power Apps mobile app and no dedicated mobile connector skill exists.
Use when adding an unspecified data source to an Expo/React Native Power Apps mobile app; routes to Dataverse, SharePoint, or another connector.