debug-extension
Diagnose and fix failures in a built third-party `.ppmplugin` control: crashes, silent no-ops, PCF error outputs, or incorrect behavior. Uses the reported symptom, `shared/error-codes.md`, and file-level evidence to trace the manifest, Android/iOS modules, PCF dispatch, and build configuration. Produces a ranked diagnosis, asks for approval, then applies a surgical fix while keeping the committed manifest and affected contracts synchronized. Re-validates manifest changes through /generate-ppmplugin-manifest.
git clone --depth 1 https://github.com/microsoft/power-platform-skills /tmp/debug-extension && cp -r /tmp/debug-extension/plugins/power-apps-mobile-extension/skills/debug-extension ~/.claude/skills/debug-extensionSKILL.md
# /debug-extension
Investigate a failure the user observed while testing a **built** `.ppmplugin` control,
find the root cause, and fix it. The wrap binary runs inside the customer's shell with
**no logcat / Xcode console / native debugger reachable**, so the evidence is usually just
the PCF's `ErrorCode` / `ErrorMessage`, the raw `<name>Json` diagnostic output, a host log
line, or the user's description of what they saw. This skill turns that thin evidence into
a located root cause and a fix.
**Investigation-first, fix as the resolution.** Unlike a plain "apply this change" flow,
`/debug-extension` starts from a *symptom* and works backward to a *cause* before touching
code. When the cause is found, it proposes the fix and applies it under the same discipline
a careful edit uses (spec-vs-drift diagnosis, contract-consistency, surgical edits, gates).
**This is one door, not the only door.** Per `shared/shared-instructions.md §7.5`, a fix
can be applied from *any* skill or a plain conversational turn — the user is never blocked
or forced to route through this skill. What this skill adds is *structure* for a reported
problem: the symptom→layer triage, the dispatch-path trace, and the located-evidence
diagnosis before any edit. Reach for it when something *broke on device* and you don't yet
know why; for a planned feature change where you already know what to edit, just edit
directly.
**When to use:**
- "I tapped the button and nothing happened — no error, no UI." (silent no-op)
- "The PCF shows `ErrorCode: PARSE` / `ErrorMessage: ...`." (a code to trace)
- "The app crashes the moment the screen loads." (crash-at-launch)
- "Host log says `Loaded 0 plugin package(s)`." (a native-load signature)
- "It works on iOS but does nothing on Android." (parity / transport bug)
- "The Done button returns the wrong data." (behavior drift)
**When NOT to use:**
- No repo yet → `/generate-native-extension`.
- A brand-new operation → `/design-native-extension-feature`, then generate.
- A planned change with a known edit and no reported failure → just edit (any skill / chat).
- A build that never produced a binary → the failure is a *build* failure; run
`/generate-ppmplugin` and read its stage output first.
**Decoupled from generate-*.** This skill refuses to run if no extension repo is detected.
It does NOT scaffold, install dependencies, build binaries, or assemble the bundle. It
diagnoses, then edits files.
---
## Step 0 — Verify this is an extension repo
Detect the repo in this order. Stop with `BLOCKED: not an extension repo (no <X> found)`
if any **required** signal is missing.
| Signal | Required? | Check |
|---|---|---|
| `PRD.md` exists at repo root | **Yes** | The spec is the baseline the observed behavior is compared against. |
| `package.json` exists at repo root | **Yes** | Confirms this is a generated extension repo, not a random directory. |
| `ARCHITECTURE.md` exists at repo root | No | Strongly preferred — holds the dispatch contract + per-op impl the trace follows. Note its absence as a concern. |
| `.extension-state.md` exists at repo root | No | Informational — prior edits / drift entries are debugging leads. Created at Step 9 if absent. |
| `pcf/` folder with a `ControlManifest.Input.xml` inside | No | Drives PCF detection. Use Glob under `pcf/` to locate the manifest and capture `has_pcf: true|false`. |
| `ppmplugin/` build output / a `.ppmplugin` artifact | No | Informational — confirms a binary was built (this skill debugs *built* controls). Absence → the failure may be pre-build; note it. |
If PRD or `package.json` is missing, suggest `/generate-native-extension` and stop.
---
## Step 1 — Read shared docs, PRD, ARCHITECTURE, manifest, and state
In this order:
1. `shared/shared-instructions.md` — constants, return-status codes (`DONE` / `DONE_WITH_CONCERNS` / `BLOCKED` / `NEEDS_CONTEXT`), safety rules.
2. **`shared/error-codes.md`** — the canonical catalog + the **symptom → likely cause → where-to-look** map. This is the core input to triage (Step 3). Read it fully.
3. `shared/naming-conventions.md` — maps PRD identity to file paths for the trace.
4. `shared/repo-layout.md` — the expected file tree.
5. `shared/ppmplugin-format.md` — the dispatch contract, the wrap `sendAsync` transport, the `{ isUpdate, message }` response container, and the native-load model (`§2`, `§5`, `§5b`). Essential for tracing transport / load failures.
6. `./PRD.md` — full read (identity, operations, expected behavior).
7. `./ARCHITECTURE.md` — full read (SDK pin, per-op impl walkthroughs, message contract, §5 error codes, manifest impl). The trace follows this.
8. `./manifest.json` — the committed dispatch contract (`name`, `receivers[].method`, `receivers[].nativeModule`).
9. `./.extension-state.md` — prior `## Edits` / `## Debug` entries and any recorded drift — often the fastest lead.
**Skip `shared/prereq-check.md`.** Debug installs/auths nothing. If a fix later needs the
PCF `npm run build`, Step 8 surfaces a missing toolchain then.
Per `shared-instructions.md §9.2`, print a one-line prereq notice at the start of Step 1:
```
Prereq check — /debug-extension: skipped (skill does no installs / auth / network — investigation only until a fix's smoke check).
```
---
## Step 2 — Capture the bug report
Gather the symptom. If the user invoked the skill with no detail, prompt for it — ask for
whichever of these they have (one consolidated prompt, not five):
- **What happened vs. what they expected** (the observable behavior).
- **`ErrorCode` / `ErrorMessage`** shown on the PCF (or in Power Fx via `Self.ErrorCode` / `Self.ErrorMessage`).
- **The raw `<name>Json`** diagnostic output (the wire bytes — transport-level forensics).
- **Any host log line** (e.g. `Loaded 0 plugin package(s)`, `native module '<x>' not loaded`, `method '<m>' not found`, a stack trace).
- **Platform** (iOS / Android / both) and **when** it happens (at launch / on tap / after the operation).
- **Repro steps**, if anGuide 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.