Skip to main content
ClaudeWave
Skill808 repo starsupdated 3d ago

generate-pcf-companion

Generate the dispatcher PCF for a third-party `.ppmplugin` (wrap-runtime) control. Runs `pac pcf init` in the pcf/ subfolder, rewrites ControlManifest.Input.xml from ARCHITECTURE §6, and writes index.ts derived from ARCHITECTURE §4 (message contract), §8 (PCF surface), §9 (error UX) — no placeholders. The bridge dispatches the composite key `<name>/<receiver>` to `NativeModules.<nativeModule>.<method>` via the host-injected `window.PowerApps.NativeExtension.sendAsync` global (never `cordova.exec` — not in the PCF sandbox); also emits a `PowerAppsNativeExtension.d.ts` ambient declaration. Responses are peeled with `extractResponse`. Emits structured JSON debug/error logs. Validated by `npm run build`. **Local only** — does not deploy. Needs only `pac` CLI. Run after the native module exists. Uses npm (not pnpm).

Install in Claude Code
Copy
git clone --depth 1 https://github.com/microsoft/power-platform-skills /tmp/generate-pcf-companion && cp -r /tmp/generate-pcf-companion/plugins/power-apps-mobile-extension/skills/generate-pcf-companion ~/.claude/skills/generate-pcf-companion
Then start a new Claude Code session; the skill loads automatically.

SKILL.md

# /generate-pcf-companion

Generates the dispatcher PCF — the Canvas Studio control that calls the third-party native module through the host-injected `window.PowerApps.NativeExtension.sendAsync` global, routed by the composite key `<name>/<receiver>` read from the committed `./manifest.json` (the source of truth `/generate-native-extension` authors at scaffold time). Lives at `pcf/<Pascal>PCF/` in the same repo the native module lives in. The PCF is a Studio-side companion; it is **NOT** part of the `.ppmplugin` bundle (the bundle ships native binaries only — `manifest.json` + `android/`/`ios/`).

This skill assumes the native module already exists in the repo. Run it after the module is in place.

> **PCF framework reference (public Microsoft Learn docs).** Ground `pac pcf init`, the `ControlManifest.Input.xml` schema, the `init`/`updateView`/`getOutputs`/`destroy` lifecycle, and the `usage` (`bound`/`input`/`output`) rules against the official Power Apps Component Framework docs — they are the authority when this skill's templates and the live framework disagree. (The `sendAsync` transport + `extractResponse` response-unwrap specifics are this track's own, in [`shared/ppmplugin-format.md §2`](../../shared/ppmplugin-format.md) — not in these generic PCF docs.)
> - Overview: <https://learn.microsoft.com/en-us/power-apps/developer/component-framework/overview>
> - Create a code component: <https://learn.microsoft.com/en-us/power-apps/developer/component-framework/create-custom-controls-using-pcf>
> - Custom controls overview: <https://learn.microsoft.com/en-us/power-apps/developer/component-framework/custom-controls-overview>

---

## Step 1 — Read the shared docs and the PRD

1. Read [`shared/shared-instructions.md`](../../shared/shared-instructions.md), [`shared/naming-conventions.md`](../../shared/naming-conventions.md), [`shared/ppmplugin-format.md`](../../shared/ppmplugin-format.md), [`shared/repo-layout.md`](../../shared/repo-layout.md).
2. Apply the **per-skill minimal prereq policy** ([`shared-instructions.md §1.5`](../../shared/shared-instructions.md)). This skill needs Node + `pac` CLI only — `pac pcf init` is a local file generator and `npm install`/`npm run build` under `pcf/` only needs Node. It does NOT need pnpm, package-feed authentication, .NET SDK runtime, or active `pac auth`.

   **Print the prereq status as a visible block per `shared-instructions.md §9.2`** before continuing:

   ```
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    Prereq check — /generate-pcf-companion
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

    🟢 ✓ Node 20+ installed                   (for npm install + tsc under pcf/)
    🟢 ✓ pac CLI installed                    (for pac pcf init)

    🟢 2 checks passed. Ready to proceed.
   ```

   If `pac` is missing, STOP with the fix command (`dotnet tool install -g Microsoft.PowerApps.CLI.Tool` — note: installing `pac` requires .NET SDK as a one-time install, but neither .NET nor `pac auth` is needed at runtime for scaffold). If Node is missing, STOP with the install instruction. Run the **`/generate-pcf-companion` check** from [`prereq-check.md`](../../shared/prereq-check.md) (Node + `pac` only — this self-contained track has no "baseline" check).

   **.NET SDK + active `pac auth` are NOT checked here.** If the user later picks the optional "Yes, also deploy now" path in Step 2, the deploy prereq one-liner is run **at that point** (just-in-time, before `pac pcf push`).
3. Read `./PRD.md`. If missing or §8 (PCF surface) is incomplete (any `<NEEDS INPUT>` or missing fields in §8.1–§8.4), STOP with `BLOCKED: PRD.md §8 PCF surface is incomplete — re-run /design-native-extension-feature and complete the PCF section.`
4. Read `./.extension-state.md`. If Phase isn't at least `scaffold`, STOP with `BLOCKED: run /generate-native-extension first.`
The structural patterns this skill needs to emit (manifest shape, `index.ts` bridge wiring, output mapping) are fully prescribed in this SKILL.md (§4–§5) and in [`shared/ppmplugin-format.md`](../../shared/ppmplugin-format.md) §2 (Runtime dispatch contract). Do NOT fetch the reference extension repo at runtime — its lessons are already encoded here, and fetching it would risk reference-specific UI logic bleeding into an unrelated PCF.

---

## Step 1.5 — Resolve the dispatch contract from `./manifest.json` and the native module

The wrap **runtime dispatch contract** ([`shared/ppmplugin-format.md`](../../shared/ppmplugin-format.md) §2) is the **authoritative specification** of how a host call reaches the bundle. The `.ppmplugin` bundle is native-only (no TS `handleMessageAsync` layer *in the bundle*), but the **companion PCF** dispatches through the host-injected **`window.PowerApps.NativeExtension.sendAsync`** global — it must **NEVER** call `cordova.exec` directly (the raw `cordova` global is not exposed to the PCF sandbox; a direct call is a silent no-op on device, worst on Android). `sendAsync` performs the underlying `cordova.exec("SendMessagePlugin", …)` transport *inside the host context* and routes to the React Native module the binary ships:

```
PCF → window.PowerApps.NativeExtension.sendAsync("<name>/<receiver>", { method, args: [request] })
    → host global (host context): cordova.exec("SendMessagePlugin", "<name>/<receiver>", [JSON.stringify({method,args}), corrId])
    → proxy → NativeModules[<nativeModule>][<method>].apply(mod, <args-array>)
```

The **composite routing key** `<name>/<receiver>` is what the host resolves to a module; the **method** is one entry from that receiver's `methods[]`. One PCF drives **both iOS and Android** through this global — no platform branch.

> **⚠️ TWO invariants — both confirmed on device; getting either wrong = silent failure:**
> 1. **Dispatch via `sendAsync`, NEVER `cordova.exec`.** The envelope is a **RAW object** `{ method, args: [request] }` — the PCF does **not** stringify it; `sendAsync` does the `JSON.stringify` internally. A PC
add-data-sourceSkill

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

canvas-appSkill

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-canvas-mcpSkill

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

generate-canvas-appSkill

[DEPRECATED — use canvas-app instead] Generate a complete Power Apps canvas app.

report-issueSkill

>

add-azuredevopsSkill

Adds Azure DevOps connector to a Power Apps code app. Use when querying work items, creating bugs, managing pipelines, or making ADO API calls.

add-connectorSkill

Use when adding a Power Platform connector to an Expo/React Native Power Apps mobile app and no dedicated mobile connector skill exists.

add-datasourceSkill

Use when adding an unspecified data source to an Expo/React Native Power Apps mobile app; routes to Dataverse, SharePoint, or another connector.