Skip to main content
ClaudeWave
Skill808 repo starsupdated 3d ago

assemble-ppmplugin

Assemble the final `.ppmplugin` binary bundle for a PAM native extension and verify its contents. First **reconciles** the manifest's declared `entrypoints` against the binaries actually staged — if the manifest declares a platform with no built binary it gates (build it / ship without it / stop) rather than shipping a broken bundle. Then re-runs the plugin's upload-compatibility checks on the reconciled manifest, zips the manifest plus whichever of `android/<PascalName>Plugin.dex` and `ios/<PascalName>Plugin.framework/` are present into `ppmplugin/<name>.ppmplugin`, and verifies the archive layout with `jar tf` (exactly the manifest + the shipped binaries — nothing missing, nothing extra). Output: a statically verified `.ppmplugin` file on disk. Prereqs: `jar` (JDK). Run after /generate-ppmplugin-manifest and the build skill(s).

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

SKILL.md

# /assemble-ppmplugin

The final step: take the label (`manifest.json` from [`/generate-ppmplugin-manifest`](../generate-ppmplugin-manifest/SKILL.md)) and the binaries the build skills produced, zip them into the single `<name>.ppmplugin` file, and verify the box contains exactly the right items. The output is the deliverable — the file you can hand off / upload. Before zipping, it **reconciles** the manifest's declared platforms against the binaries that actually built, so the shipped bundle never claims a platform it doesn't contain.

Read [`shared/ppmplugin-format.md`](../../shared/ppmplugin-format.md) §1 — the bundle layout this skill produces and verifies.

## What this skill does NOT do
- Does not author the manifest or build any binary — it consumes the staged outputs of the prior third-party-control skills (manifest + the build skill(s)).
- Does not upload to Dataverse / wire into a canvas app (Stage 3 — deferred).
- Does not build any binary — it consumes whatever the build skills staged (`android/<Pascal>Plugin.dex` from `/build-android-binary` and/or `ios/<Pascal>Plugin.framework/` from `/build-ios-binary`) and bundles those present.

---

## Step 1 — Read shared docs + prereq block

1. Read [`shared/shared-instructions.md`](../../shared/shared-instructions.md) and [`shared/ppmplugin-format.md`](../../shared/ppmplugin-format.md).
2. Prereq: `jar` (ships with the JDK). Print the visible block (shared-instructions §9.2):

```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 Prereq check — /assemble-ppmplugin
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 🟢 ✓ jar (JDK) available
 🟢 1 check passed, 0 failed. Ready to proceed.
```

If `jar` is missing, STOP with `BLOCKED: jar not found — install a JDK (JDK 17)`.

---

## Step 2 — Reconcile declared entrypoints against staged binaries (the gate)

The shipped bundle's `manifest.json` MUST declare exactly the platforms whose binaries are in the zip — no more, no less. The manifest was authored from *intent* (target choice); this step makes it match *reality* (what actually built). This is the one place that sees the final set of binaries, so it owns consistency.

1. Read `ppmplugin/staging/manifest.json` — else STOP with `NEEDS_CONTEXT: manifest missing — run /generate-ppmplugin-manifest`. Read `name` for the output filename `<name>.ppmplugin` (the **version is NOT in the filename** — it lives in the manifest's `version` field; the wrap pipeline reads it from there. Still read `version` to show it in the deliverable report).
2. **Declared** platforms: is `entrypoints.android` present? `entrypoints.ios`?
3. **Staged** binaries:
   - Android: `ppmplugin/staging/android/<dex>` exists, where `<dex>` = `entrypoints.android.dex`.
   - iOS: `ppmplugin/staging/ios/<framework>.framework/` exists (a **flat** `.framework`, NOT an `.xcframework` — [§5b](../../shared/ppmplugin-format.md)), where `<framework>` = `entrypoints.ios.framework`. If an `.xcframework` is staged instead, surface it as a gate — the wrap CI can't ingest it; re-run `/build-ios-binary` for the flat device-slice framework.
4. Reconcile, per platform:

| Declared | Staged | Action |
|---|---|---|
| yes | yes | ship it ✓ |
| yes | **no** | **MISMATCH → gate** (below) |
| no | yes | binary present but the manifest won't route it — surface; offer to re-run `/generate-ppmplugin-manifest` to declare it, or leave it out |
| no | no | not part of this bundle — ignore |

5. If nothing is both declared AND staged → STOP with `NEEDS_CONTEXT: no built binary to ship — run a build skill first`.

**The mismatch gate (declared but not staged).** Do NOT silently ship a manifest pointing at a missing binary. The situation is genuinely ambiguous (changed-my-mind vs forgot-to-build), so surface it and ask via `AskUserQuestion`:

> *"Manifest declares `<platform>` but no `<platform>` binary is staged."*
> - **Build `<platform>` first** — run the build skill (`/build-android-binary`, or `/build-ios-binary` for iOS, Mac-only) [invoke it via the Skill tool — execute, don't describe]
> - **Ship without `<platform>`** — remove `entrypoints.<platform>` from the staged `manifest.json`, ship the platforms that ARE built
> - **Stop**

If the user picks "Ship without", **edit the staged `manifest.json` to drop that entrypoint** before continuing. After this step, the manifest's `entrypoints` set equals the staged-binary set exactly.

---

## Step 3 — Final validation pass

Re-run the [`ppmplugin-format §4`](../../shared/ppmplugin-format.md) validation rules on the **reconciled** staged `manifest.json` (it may have been edited in Step 2 or by hand). Also cross-check, for each shipped platform:
- Android: `entrypoints.android.dex` exactly matches the staged DEX filename.
- iOS: `entrypoints.ios.framework` matches the staged `…/<framework>.framework` directory name, and that `.framework/` carries the binary + `Headers/<framework>.h` + `Modules/module.modulemap` + `Info.plist` (the wrap-CI requirements — `/audit-ppmplugin` does the deep check; flag here if any are obviously absent).

If validation fails, STOP with `BLOCKED: manifest validation — <rule>` and do not produce the
bundle. A `.ppmplugin` that fails the local compatibility checks is not ready for upload.

---

## Step 4 — Zip + verify

**Before zipping:** if the output `ppmplugin/<name>.ppmplugin` already exists, do NOT silently overwrite it — ask via `AskUserQuestion`: **Replace** [default] / **Keep existing** (stop, leave the prior bundle untouched). Proceed to zip only on Replace.

1. **Zip** the manifest plus **only the platform folder(s) reconciled as shipped in Step 2**. Pass them explicitly so the build dirs (`android-build/`, `ios-build/`) are never swept in. `jar` (JDK) recurses directories, so it handles the iOS `.framework` tree, and it behaves identically on every OS — only the shell glue differs (§5):

   macOS / Linux (bash):
   ```bash
   mkdir -p ppmplugin
   # list only the shipped platforms, e.g. `android` for Andr
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.