[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M699Q6E99XTYPJ233YCKPHRM":3,"skill-same:01M699Q6E99XTYPJ233YCKPHRM":76},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":45,"linkOnly":46,"markdownContent":47,"markdownBody":48,"frontMatter":49,"refName":52,"commitSha":53,"skillDirectory":54,"forksCount":55,"repositoryHtmlUrl":56,"repositoryHomepageUrl":57,"ownerHtmlUrl":58,"ownerBlogUrl":59,"ownerDescription":60,"updatedAt":61,"install":62,"resources":75},"01M699Q6E99XTYPJ233YCKPHRM","assemble-ppmplugin",null,"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 \u002F ship without it \u002F 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\u002F\u003CPascalName>Plugin.dex` and `ios\u002F\u003CPascalName>Plugin.framework\u002F` are present into `ppmplugin\u002F\u003Cname>.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 \u002Fgenerate-ppmplugin-manifest and the build skill(s).","microsoft\u002Fpower-platform-skills","microsoft","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F6154722?v=4","01M698VYDXZ6JW5WH3CRV650R8","Microsoft","01M699JVYJFB75D9JM70BN4H0Q",1146,"MIT","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fpower-platform-skills\u002Fblob\u002Fmain\u002Fplugins\u002Fpower-apps-mobile-extension\u002Fskills\u002Fassemble-ppmplugin\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44],"assemble ppmplugin","assemble","verified","android","re","native","present","layout","compatibility","edit","write","read","broken","extra","Bash","ship","disk","PAM","shipping","run","generate","2026-11-10 10:12:30",false,"---\nname: assemble-ppmplugin\ndescription: \"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 \u002F ship without it \u002F 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\u002F\u003CPascalName>Plugin.dex` and `ios\u002F\u003CPascalName>Plugin.framework\u002F` are present into `ppmplugin\u002F\u003Cname>.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 \u002Fgenerate-ppmplugin-manifest and the build skill(s).\"\nallowed-tools: Read, Write, Edit, Bash, Glob, Grep, AskUserQuestion, Skill\nmodel: sonnet\n---\n\n# \u002Fassemble-ppmplugin\n\nThe final step: take the label (`manifest.json` from [`\u002Fgenerate-ppmplugin-manifest`](..\u002Fgenerate-ppmplugin-manifest\u002FSKILL.md)) and the binaries the build skills produced, zip them into the single `\u003Cname>.ppmplugin` file, and verify the box contains exactly the right items. The output is the deliverable — the file you can hand off \u002F 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.\n\nRead [`shared\u002Fppmplugin-format.md`](..\u002F..\u002Fshared\u002Fppmplugin-format.md) §1 — the bundle layout this skill produces and verifies.\n\n## What this skill does NOT do\n- 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)).\n- Does not upload to Dataverse \u002F wire into a canvas app (Stage 3 — deferred).\n- Does not build any binary — it consumes whatever the build skills staged (`android\u002F\u003CPascal>Plugin.dex` from `\u002Fbuild-android-binary` and\u002For `ios\u002F\u003CPascal>Plugin.framework\u002F` from `\u002Fbuild-ios-binary`) and bundles those present.\n\n---\n\n## Step 1 — Read shared docs + prereq block\n\n1. Read [`shared\u002Fshared-instructions.md`](..\u002F..\u002Fshared\u002Fshared-instructions.md) and [`shared\u002Fppmplugin-format.md`](..\u002F..\u002Fshared\u002Fppmplugin-format.md).\n2. Prereq: `jar` (ships with the JDK). Print the visible block (shared-instructions §9.2):\n\n```\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n Prereq check — \u002Fassemble-ppmplugin\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n ? ✓ jar (JDK) available\n ? 1 check passed, 0 failed. Ready to proceed.\n```\n\nIf `jar` is missing, STOP with `BLOCKED: jar not found — install a JDK (JDK 17)`.\n\n---\n\n## Step 2 — Reconcile declared entrypoints against staged binaries (the gate)\n\nThe 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.\n\n1. Read `ppmplugin\u002Fstaging\u002Fmanifest.json` — else STOP with `NEEDS_CONTEXT: manifest missing — run \u002Fgenerate-ppmplugin-manifest`. Read `name` for the output filename `\u003Cname>.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).\n2. **Declared** platforms: is `entrypoints.android` present? `entrypoints.ios`?\n3. **Staged** binaries:\n   - Android: `ppmplugin\u002Fstaging\u002Fandroid\u002F\u003Cdex>` exists, where `\u003Cdex>` = `entrypoints.android.dex`.\n   - iOS: `ppmplugin\u002Fstaging\u002Fios\u002F\u003Cframework>.framework\u002F` exists (a **flat** `.framework`, NOT an `.xcframework` — [§5b](..\u002F..\u002Fshared\u002Fppmplugin-format.md)), where `\u003Cframework>` = `entrypoints.ios.framework`. If an `.xcframework` is staged instead, surface it as a gate — the wrap CI can't ingest it; re-run `\u002Fbuild-ios-binary` for the flat device-slice framework.\n4. Reconcile, per platform:\n\n| Declared | Staged | Action |\n|---|---|---|\n| yes | yes | ship it ✓ |\n| yes | **no** | **MISMATCH → gate** (below) |\n| no | yes | binary present but the manifest won't route it — surface; offer to re-run `\u002Fgenerate-ppmplugin-manifest` to declare it, or leave it out |\n| no | no | not part of this bundle — ignore |\n\n5. If nothing is both declared AND staged → STOP with `NEEDS_CONTEXT: no built binary to ship — run a build skill first`.\n\n**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`:\n\n> *\"Manifest declares `\u003Cplatform>` but no `\u003Cplatform>` binary is staged.\"*\n> - **Build `\u003Cplatform>` first** — run the build skill (`\u002Fbuild-android-binary`, or `\u002Fbuild-ios-binary` for iOS, Mac-only) [invoke it via the Skill tool — execute, don't describe]\n> - **Ship without `\u003Cplatform>`** — remove `entrypoints.\u003Cplatform>` from the staged `manifest.json`, ship the platforms that ARE built\n> - **Stop**\n\nIf 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.\n\n---\n\n## Step 3 — Final validation pass\n\nRe-run the [`ppmplugin-format §4`](..\u002F..\u002Fshared\u002Fppmplugin-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:\n- Android: `entrypoints.android.dex` exactly matches the staged DEX filename.\n- iOS: `entrypoints.ios.framework` matches the staged `…\u002F\u003Cframework>.framework` directory name, and that `.framework\u002F` carries the binary + `Headers\u002F\u003Cframework>.h` + `Modules\u002Fmodule.modulemap` + `Info.plist` (the wrap-CI requirements — `\u002Faudit-ppmplugin` does the deep check; flag here if any are obviously absent).\n\nIf validation fails, STOP with `BLOCKED: manifest validation — \u003Crule>` and do not produce the\nbundle. A `.ppmplugin` that fails the local compatibility checks is not ready for upload.\n\n---\n\n## Step 4 — Zip + verify\n\n**Before zipping:** if the output `ppmplugin\u002F\u003Cname>.ppmplugin` already exists, do NOT silently overwrite it — ask via `AskUserQuestion`: **Replace** [default] \u002F **Keep existing** (stop, leave the prior bundle untouched). Proceed to zip only on Replace.\n\n1. **Zip** the manifest plus **only the platform folder(s) reconciled as shipped in Step 2**. Pass them explicitly so the build dirs (`android-build\u002F`, `ios-build\u002F`) 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):\n\n   macOS \u002F Linux (bash):\n   ```bash\n   mkdir -p ppmplugin\n   # list only the shipped platforms, e.g. `android` for Android-only, `android ios` for Both:\n   ( cd ppmplugin\u002Fstaging && jar cMf \"..\u002F\u003Cname>.ppmplugin\" manifest.json android ios )\n   ```\n\n   Windows (PowerShell):\n   ```powershell\n   New-Item -ItemType Directory -Force ppmplugin | Out-Null\n   Push-Location ppmplugin\\staging\n   jar cMf ..\\\u003Cname>.ppmplugin manifest.json android ios\n   Pop-Location\n   ```\n   (`-M` = no JAR manifest entry; the bundle's `manifest.json` is our own. Drop `ios` (or `android`) from the argument list if that platform isn't shipped.) On **Replace** (confirmed above), the prior bundle is overwritten.\n\n2. **Verify layout** — list and assert it matches the reconciled manifest exactly:\n   ```bash\n   jar tf ppmplugin\u002F\u003Cname>.ppmplugin\n   ```\n   Android-only expects exactly:\n   ```\n   manifest.json\n   android\u002F\u003CPascal>Plugin.dex\n   ```\n   A **Both** bundle also has `ios\u002F\u003CPascal>Plugin.framework\u002F…` entries (flat framework — binary + `Headers\u002F` + `Modules\u002Fmodule.modulemap` + `Info.plist`). STOP with `BLOCKED: unexpected bundle contents` (and the actual listing) if: a build dir leaked in (`android-build\u002F`, `ios-build\u002F`), a stray file appears (`.DS_Store`, `META-INF\u002F`), an `ios\u002F\u003C…>.xcframework\u002F` is present (must be a flat `.framework`), or a declared platform's binary is missing. The bundle must contain exactly the manifest + the entrypoints' binaries — nothing else.\n\n---\n\n## Step 5 — Report\n\nUpdate the `## ppmplugin (third-party controls)` block in `.extension-state.md`: `Bundle: \u003Cname>.ppmplugin assembled \u003CISO timestamp> (v\u003Cversion>, platforms: \u003Candroid[,ios]>)`. Print the deliverable as a visible fenced block (shared-instructions §9.1, informational form):\n\n```\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n .ppmplugin ready\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n ppmplugin\u002Fpen-input.ppmplugin   (v0.1.4, Android-only)\n Contents:\n   manifest.json\n   android\u002FPenInputPlugin.dex\n Next: \u002Faudit-ppmplugin — verify the bundle is upload-ready before shipping it.\n       (Then: deploy the dispatcher PCF via \u002Fpublish-pcf-companion, and upload the\n        .ppmplugin via the wrap wizard — Stage 3, not yet a skill.)\n```\n\nThen offer the next step via `AskUserQuestion` (shared-instructions §9.1 — **invoke the chosen skill via the Skill tool; execute, don't describe**):\n- **Run \u002Faudit-ppmplugin** (recommended — the final upload-readiness gate: validator rules + DEX SDK-leakage scan + iOS framework checks)\n- **Run \u002Fpublish-pcf-companion** (deploy the dispatcher PCF to a Power Platform env)\n- **Stay — I'll inspect the bundle first**\n\n(When `\u002Fassemble-ppmplugin` runs as an internal stage of `\u002Fgenerate-ppmplugin`, the orchestrator invokes `\u002Faudit-ppmplugin` automatically and this gate is skipped.) Return `DONE` with the bundle path.\n","# \u002Fassemble-ppmplugin\n\nThe final step: take the label (`manifest.json` from [`\u002Fgenerate-ppmplugin-manifest`](..\u002Fgenerate-ppmplugin-manifest\u002FSKILL.md)) and the binaries the build skills produced, zip them into the single `\u003Cname>.ppmplugin` file, and verify the box contains exactly the right items. The output is the deliverable — the file you can hand off \u002F 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.\n\nRead [`shared\u002Fppmplugin-format.md`](..\u002F..\u002Fshared\u002Fppmplugin-format.md) §1 — the bundle layout this skill produces and verifies.\n\n## What this skill does NOT do\n- 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)).\n- Does not upload to Dataverse \u002F wire into a canvas app (Stage 3 — deferred).\n- Does not build any binary — it consumes whatever the build skills staged (`android\u002F\u003CPascal>Plugin.dex` from `\u002Fbuild-android-binary` and\u002For `ios\u002F\u003CPascal>Plugin.framework\u002F` from `\u002Fbuild-ios-binary`) and bundles those present.\n\n---\n\n## Step 1 — Read shared docs + prereq block\n\n1. Read [`shared\u002Fshared-instructions.md`](..\u002F..\u002Fshared\u002Fshared-instructions.md) and [`shared\u002Fppmplugin-format.md`](..\u002F..\u002Fshared\u002Fppmplugin-format.md).\n2. Prereq: `jar` (ships with the JDK). Print the visible block (shared-instructions §9.2):\n\n```\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n Prereq check — \u002Fassemble-ppmplugin\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n ? ✓ jar (JDK) available\n ? 1 check passed, 0 failed. Ready to proceed.\n```\n\nIf `jar` is missing, STOP with `BLOCKED: jar not found — install a JDK (JDK 17)`.\n\n---\n\n## Step 2 — Reconcile declared entrypoints against staged binaries (the gate)\n\nThe 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.\n\n1. Read `ppmplugin\u002Fstaging\u002Fmanifest.json` — else STOP with `NEEDS_CONTEXT: manifest missing — run \u002Fgenerate-ppmplugin-manifest`. Read `name` for the output filename `\u003Cname>.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).\n2. **Declared** platforms: is `entrypoints.android` present? `entrypoints.ios`?\n3. **Staged** binaries:\n   - Android: `ppmplugin\u002Fstaging\u002Fandroid\u002F\u003Cdex>` exists, where `\u003Cdex>` = `entrypoints.android.dex`.\n   - iOS: `ppmplugin\u002Fstaging\u002Fios\u002F\u003Cframework>.framework\u002F` exists (a **flat** `.framework`, NOT an `.xcframework` — [§5b](..\u002F..\u002Fshared\u002Fppmplugin-format.md)), where `\u003Cframework>` = `entrypoints.ios.framework`. If an `.xcframework` is staged instead, surface it as a gate — the wrap CI can't ingest it; re-run `\u002Fbuild-ios-binary` for the flat device-slice framework.\n4. Reconcile, per platform:\n\n| Declared | Staged | Action |\n|---|---|---|\n| yes | yes | ship it ✓ |\n| yes | **no** | **MISMATCH → gate** (below) |\n| no | yes | binary present but the manifest won't route it — surface; offer to re-run `\u002Fgenerate-ppmplugin-manifest` to declare it, or leave it out |\n| no | no | not part of this bundle — ignore |\n\n5. If nothing is both declared AND staged → STOP with `NEEDS_CONTEXT: no built binary to ship — run a build skill first`.\n\n**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`:\n\n> *\"Manifest declares `\u003Cplatform>` but no `\u003Cplatform>` binary is staged.\"*\n> - **Build `\u003Cplatform>` first** — run the build skill (`\u002Fbuild-android-binary`, or `\u002Fbuild-ios-binary` for iOS, Mac-only) [invoke it via the Skill tool — execute, don't describe]\n> - **Ship without `\u003Cplatform>`** — remove `entrypoints.\u003Cplatform>` from the staged `manifest.json`, ship the platforms that ARE built\n> - **Stop**\n\nIf 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.\n\n---\n\n## Step 3 — Final validation pass\n\nRe-run the [`ppmplugin-format §4`](..\u002F..\u002Fshared\u002Fppmplugin-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:\n- Android: `entrypoints.android.dex` exactly matches the staged DEX filename.\n- iOS: `entrypoints.ios.framework` matches the staged `…\u002F\u003Cframework>.framework` directory name, and that `.framework\u002F` carries the binary + `Headers\u002F\u003Cframework>.h` + `Modules\u002Fmodule.modulemap` + `Info.plist` (the wrap-CI requirements — `\u002Faudit-ppmplugin` does the deep check; flag here if any are obviously absent).\n\nIf validation fails, STOP with `BLOCKED: manifest validation — \u003Crule>` and do not produce the\nbundle. A `.ppmplugin` that fails the local compatibility checks is not ready for upload.\n\n---\n\n## Step 4 — Zip + verify\n\n**Before zipping:** if the output `ppmplugin\u002F\u003Cname>.ppmplugin` already exists, do NOT silently overwrite it — ask via `AskUserQuestion`: **Replace** [default] \u002F **Keep existing** (stop, leave the prior bundle untouched). Proceed to zip only on Replace.\n\n1. **Zip** the manifest plus **only the platform folder(s) reconciled as shipped in Step 2**. Pass them explicitly so the build dirs (`android-build\u002F`, `ios-build\u002F`) 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):\n\n   macOS \u002F Linux (bash):\n   ```bash\n   mkdir -p ppmplugin\n   # list only the shipped platforms, e.g. `android` for Android-only, `android ios` for Both:\n   ( cd ppmplugin\u002Fstaging && jar cMf \"..\u002F\u003Cname>.ppmplugin\" manifest.json android ios )\n   ```\n\n   Windows (PowerShell):\n   ```powershell\n   New-Item -ItemType Directory -Force ppmplugin | Out-Null\n   Push-Location ppmplugin\\staging\n   jar cMf ..\\\u003Cname>.ppmplugin manifest.json android ios\n   Pop-Location\n   ```\n   (`-M` = no JAR manifest entry; the bundle's `manifest.json` is our own. Drop `ios` (or `android`) from the argument list if that platform isn't shipped.) On **Replace** (confirmed above), the prior bundle is overwritten.\n\n2. **Verify layout** — list and assert it matches the reconciled manifest exactly:\n   ```bash\n   jar tf ppmplugin\u002F\u003Cname>.ppmplugin\n   ```\n   Android-only expects exactly:\n   ```\n   manifest.json\n   android\u002F\u003CPascal>Plugin.dex\n   ```\n   A **Both** bundle also has `ios\u002F\u003CPascal>Plugin.framework\u002F…` entries (flat framework — binary + `Headers\u002F` + `Modules\u002Fmodule.modulemap` + `Info.plist`). STOP with `BLOCKED: unexpected bundle contents` (and the actual listing) if: a build dir leaked in (`android-build\u002F`, `ios-build\u002F`), a stray file appears (`.DS_Store`, `META-INF\u002F`), an `ios\u002F\u003C…>.xcframework\u002F` is present (must be a flat `.framework`), or a declared platform's binary is missing. The bundle must contain exactly the manifest + the entrypoints' binaries — nothing else.\n\n---\n\n## Step 5 — Report\n\nUpdate the `## ppmplugin (third-party controls)` block in `.extension-state.md`: `Bundle: \u003Cname>.ppmplugin assembled \u003CISO timestamp> (v\u003Cversion>, platforms: \u003Candroid[,ios]>)`. Print the deliverable as a visible fenced block (shared-instructions §9.1, informational form):\n\n```\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n .ppmplugin ready\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n ppmplugin\u002Fpen-input.ppmplugin   (v0.1.4, Android-only)\n Contents:\n   manifest.json\n   android\u002FPenInputPlugin.dex\n Next: \u002Faudit-ppmplugin — verify the bundle is upload-ready before shipping it.\n       (Then: deploy the dispatcher PCF via \u002Fpublish-pcf-companion, and upload the\n        .ppmplugin via the wrap wizard — Stage 3, not yet a skill.)\n```\n\nThen offer the next step via `AskUserQuestion` (shared-instructions §9.1 — **invoke the chosen skill via the Skill tool; execute, don't describe**):\n- **Run \u002Faudit-ppmplugin** (recommended — the final upload-readiness gate: validator rules + DEX SDK-leakage scan + iOS framework checks)\n- **Run \u002Fpublish-pcf-companion** (deploy the dispatcher PCF to a Power Platform env)\n- **Stay — I'll inspect the bundle first**\n\n(When `\u002Fassemble-ppmplugin` runs as an internal stage of `\u002Fgenerate-ppmplugin`, the orchestrator invokes `\u002Faudit-ppmplugin` automatically and this gate is skipped.) Return `DONE` with the bundle path.\n",{"name":5,"model":50,"description":7,"allowed-tools":51},"sonnet","Read, Write, Edit, Bash, Glob, Grep, AskUserQuestion, Skill","main","0a55a88fa2855404029d1e5450faf92878baf763","plugins\u002Fpower-apps-mobile-extension\u002Fskills\u002Fassemble-ppmplugin",230,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fpower-platform-skills","https:\u002F\u002Fmicrosoft.github.io\u002Fpower-platform-skills\u002F","https:\u002F\u002Fgithub.com\u002Fmicrosoft","https:\u002F\u002Fopensource.microsoft.com","Open source projects and samples from Microsoft","2026-11-14 02:26:14",{"source":8,"skillName":5,"commands":63,"prompt":73,"zipAvailable":74},[64,67,70],{"tool":65,"command":66},"npx","npx skills add microsoft\u002Fpower-platform-skills --skill assemble-ppmplugin",{"tool":68,"command":69},"bunx","bunx skills add microsoft\u002Fpower-platform-skills --skill assemble-ppmplugin",{"tool":71,"command":72},"pnpm","pnpm dlx skills add microsoft\u002Fpower-platform-skills --skill assemble-ppmplugin","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fpower-platform-skills\u002Fblob\u002Fmain\u002Fplugins\u002Fpower-apps-mobile-extension\u002Fskills\u002Fassemble-ppmplugin\u002FSKILL.md",true,[],[77,97,120,138,152,162],{"skillNo":78,"name":79,"nameZh":6,"description":80,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":81,"categories":82,"keywords":83,"publishedAt":45},"01M699WVHX0XN59EPBTTPEKYPG","setup","Use when Process Intelligence needs building, explicit cloud\u002Faccount\u002Fenvironment configuration, sign-in, connection diagnostics, or recovery from an authentication error.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fpower-platform-skills\u002Fblob\u002Fmain\u002Fplugins\u002Fprocess-intelligence\u002Fskills\u002Fsetup\u002FSKILL.md",[],[79,35,84,85,86,87,88,89,90,91,92,93,94,95,96,38],"when","connection","error","sign","intelligence","configuration","use","process","diagnostics","environment","authentication","cloud","recovery",{"skillNo":98,"name":99,"nameZh":6,"description":100,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":101,"categories":102,"keywords":108,"publishedAt":45},"01M699WSR9EX55YY1WD9J22FEG","report-issue","Use when the user wants a Process Intelligence bug-report draft or support summary for a failed operation.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fpower-platform-skills\u002Fblob\u002Fmain\u002Fplugins\u002Fprocess-intelligence\u002Fskills\u002Freport-issue\u002FSKILL.md",[103],{"categoryNo":104,"categoryName":105,"taxonomyType":106,"taxonomyTypeDesc":107},"01JBSEEDCAT000000000000034","行政与办公人员","PROFESSION","适用职业",[109,110,111,112,113,91,90,114,115,88,116,117,118,84,119],"report issue","report","issue","support","user","bug","summary","draft","operation","for","bug-report",{"skillNo":121,"name":122,"nameZh":6,"description":123,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":124,"categories":125,"keywords":126,"publishedAt":45},"01M699WR26YQ9Q21KE6MJF5B2G","investigate-process","Use when a broad Process Mining business question, observed pattern or competing explanation needs investigation across analytical perspectives.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fpower-platform-skills\u002Fblob\u002Fmain\u002Fplugins\u002Fprocess-intelligence\u002Fskills\u002Finvestigate-process\u002FSKILL.md",[],[91,127,128,129,84,130,131,132,133,35,134,90,135,136,137],"investigate","investigate process","mining","process mining","investigation","perspectives","question","business","pattern","across","analytical",{"skillNo":139,"name":140,"nameZh":6,"description":141,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":142,"categories":143,"keywords":144,"publishedAt":45},"01M699WP9SDG5ZR12P8VYNXKTN","derive-metric","Use when a requested measure is missing, a saved custom metric needs reuse, or an ephemeral formula or derived scalar is needed.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fpower-platform-skills\u002Fblob\u002Fmain\u002Fplugins\u002Fprocess-intelligence\u002Fskills\u002Fderive-metric\u002FSKILL.md",[],[145,146,35,90,147,148,149,150,151,84],"metric","derive metric","formula","missing","reuse","saved","custom",{"skillNo":153,"name":154,"nameZh":6,"description":155,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":156,"categories":157,"keywords":158,"publishedAt":45},"01M699WMG5R8P6SMTDAS1TKF9E","compare-cohorts","Use when comparing process cohorts, departments, periods or before-and-after results under matched definitions.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fpower-platform-skills\u002Fblob\u002Fmain\u002Fplugins\u002Fprocess-intelligence\u002Fskills\u002Fcompare-cohorts\u002FSKILL.md",[],[159,160,84,90,91,161,35],"compare","compare cohorts","results",{"skillNo":163,"name":164,"nameZh":6,"description":165,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":166,"categories":167,"keywords":168,"publishedAt":45},"01M699WJWNVTMP9XK3NCJHV14D","analyze-variants","Use when investigating common or slow variants, repeated work, unusual paths, or a specific Process Mining case.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fpower-platform-skills\u002Fblob\u002Fmain\u002Fplugins\u002Fprocess-intelligence\u002Fskills\u002Fanalyze-variants\u002FSKILL.md",[],[169,170,171,130,84,129,172,173,90,91,35,174,175],"analyze","variants","analyze variants","case","paths","work","common"]