Compose Multiplatform Patterns
monta-app/ocpp-emulator
Compose Multiplatform and Jetpack Compose patterns for KMP projects — state management, navigation, theming, performance, and platform-specific UI.
Validate, reconcile to the chosen target(s), and stage the manifest.json for a .ppmplugin bundle.
$ npx skills add microsoft/power-platform-skills --skill generate-ppmplugin-manifest -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install microsoft/power-platform-skills generate-ppmplugin-manifest --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/microsoft/power-platform-skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/plugins/power-apps-mobile-extension/skills/generate-ppmplugin-manifest .claude/skills/generate-ppmplugin-manifest && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "generate-ppmplugin-manifest" agent skill from https://github.com/microsoft/power-platform-skills/tree/main/plugins/power-apps-mobile-extension/skills/generate-ppmplugin-manifest into .claude/skills/generate-ppmplugin-manifest/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "generate-ppmplugin-manifest", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/microsoft/power-platform-skills/tree/main/plugins/power-apps-mobile-extension/skills/generate-ppmplugin-manifestType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add microsoft/power-platform-skills --skill generate-ppmplugin-manifest -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install microsoft/power-platform-skills generate-ppmplugin-manifest --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/microsoft/power-platform-skills.git skills-src && mkdir -p .agents/skills && cp -r skills-src/plugins/power-apps-mobile-extension/skills/generate-ppmplugin-manifest .agents/skills/generate-ppmplugin-manifest && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "generate-ppmplugin-manifest" agent skill from https://github.com/microsoft/power-platform-skills/tree/main/plugins/power-apps-mobile-extension/skills/generate-ppmplugin-manifest into .agents/skills/generate-ppmplugin-manifest/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "generate-ppmplugin-manifest", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add microsoft/power-platform-skills --skill generate-ppmplugin-manifest -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install microsoft/power-platform-skills generate-ppmplugin-manifest --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/microsoft/power-platform-skills.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/plugins/power-apps-mobile-extension/skills/generate-ppmplugin-manifest .cursor/skills/generate-ppmplugin-manifest && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "generate-ppmplugin-manifest" agent skill from https://github.com/microsoft/power-platform-skills/tree/main/plugins/power-apps-mobile-extension/skills/generate-ppmplugin-manifest into .cursor/skills/generate-ppmplugin-manifest/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "generate-ppmplugin-manifest", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/microsoft/power-platform-skills.git --path plugins/power-apps-mobile-extension/skills/generate-ppmplugin-manifest--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add microsoft/power-platform-skills --skill generate-ppmplugin-manifest -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install microsoft/power-platform-skills generate-ppmplugin-manifest --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/microsoft/power-platform-skills.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/plugins/power-apps-mobile-extension/skills/generate-ppmplugin-manifest .gemini/skills/generate-ppmplugin-manifest && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "generate-ppmplugin-manifest" agent skill from https://github.com/microsoft/power-platform-skills/tree/main/plugins/power-apps-mobile-extension/skills/generate-ppmplugin-manifest into .gemini/skills/generate-ppmplugin-manifest/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "generate-ppmplugin-manifest", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install microsoft/power-platform-skills generate-ppmplugin-manifestInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add microsoft/power-platform-skills --skill generate-ppmplugin-manifest -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/microsoft/power-platform-skills.git skills-src && mkdir -p .github/skills && cp -r skills-src/plugins/power-apps-mobile-extension/skills/generate-ppmplugin-manifest .github/skills/generate-ppmplugin-manifest && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "generate-ppmplugin-manifest" agent skill from https://github.com/microsoft/power-platform-skills/tree/main/plugins/power-apps-mobile-extension/skills/generate-ppmplugin-manifest into .github/skills/generate-ppmplugin-manifest/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "generate-ppmplugin-manifest", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add microsoft/power-platform-skills --skill generate-ppmplugin-manifest -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install microsoft/power-platform-skills generate-ppmplugin-manifest --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/microsoft/power-platform-skills.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/plugins/power-apps-mobile-extension/skills/generate-ppmplugin-manifest .opencode/skills/generate-ppmplugin-manifest && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "generate-ppmplugin-manifest" agent skill from https://github.com/microsoft/power-platform-skills/tree/main/plugins/power-apps-mobile-extension/skills/generate-ppmplugin-manifest into .opencode/skills/generate-ppmplugin-manifest/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "generate-ppmplugin-manifest", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
generate-ppmplugin-manifestValidate, reconcile to the chosen target(s), and stage the manifest.json for a .ppmplugin bundle.
Generate Ppmplugin Manifest is an agent skill from microsoft/power-platform-skills, published by the product's own GitHub organization. Validate, reconcile to the chosen target(s), and stage the manifest.json for a .ppmplugin bundle. In the normal flow the committed ./manifest.json already exists (authored by /generate-native-extension), so this stage reads it, runs the plugin's upload-compatibility checks locally as a pre-flight gate (name regex, canonical prefix, known incompatible names, method and identifier shapes), reconciles entrypoints down to the platform(s) you ship, and writes the gitignored staged copy ppmplugin/staging/manifest.json…
Its SKILL.md is about 4.8k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Mobile. It works with Android. The repository describes itself as: A plugin marketplace for GitHub Copilot and other AI agents that provides Power Platform development plugins, including reusable skills, agents, and commands for building and… The licence is MIT.
5 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit 0d044b8. It shows what the files ask for, not the result of running them.
Pre-approves these tools, so the agent can use them without asking each time:
ReadWriteEditBashGlobGrepAskUserQuestionSkillFrom allowed-tools in the SKILL.md frontmatter.
No scripts in the folder and no shell commands in SKILL.md (its code samples are json).
From the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Generate Ppmplugin Manifest loads about 4.8k tokens when it runs. Until then it costs about 225 tokens; SKILL.md has 2,092 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check noted patterns worth knowing about, such as sudo or a known installer.
allowed-tools: Read, Write, Edit, Bash, Glob, Grep, AskUserQuestion, SkillAutomated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from microsoft/power-platform-skills at commit 0d044b8, republished under its MIT licence (© microsoft). 2,092 words, ~4,766 tokens.
.claude/skills/generate-ppmplugin-manifest/SKILL.md (or your agent's skills folder).Stages the manifest.json that goes inside a .ppmplugin bundle — the small descriptor the wrap runtime and upload service read to identify the plugin and route calls into it. In the normal flow the committed ./manifest.json already exists (authored by /generate-native-extension next to the code it describes); this stage's job is to validate it, reconcile its entrypoints to the shipped target(s), and write the staged build copy ppmplugin/staging/manifest.json. It is the "get the strings right" gate: it runs instantly, needs no build tools, and catches common upload failures before any Android build. If the repo has no ./manifest.json (a hand-authored native module that skipped the scaffold), this stage authors it from source as a fallback — see Step 2.
Read shared/ppmplugin-format.md — it is the source of truth for the schema, the derivation table, and the validation rules this skill enforces.
Two manifests, one contract. ./manifest.json (repo root, committed) is the source-of-truth contract — it declares every platform the module supports. ppmplugin/staging/manifest.json (gitignored) is the build copy this stage produces — same contract, but entrypoints trimmed to the platform(s) actually being shipped. The build/assemble skills only ever read the staged copy; the committed root file is what the PCF and humans read.
/build-android-binary./assemble-ppmplugin.entrypoints; /assemble-ppmplugin reconciles them against the binaries actually staged and gates on any mismatch../manifest.json on the normal path — it reads it. It only writes ./manifest.json in the fallback case (no committed manifest existed). It never touches src/, ios/, android/, PRD, or package.json beyond reading them.shared/shared-instructions.md, shared/naming-conventions.md, and shared/ppmplugin-format.md.Prereq check — /generate-ppmplugin-manifest: skipped (skill does no installs / auth / network — failures surface at validation).package.json (the dev-only, private, plain <kebab>-control name — NOT a published @powerapps/extension-* scope; this track ships a binary, not an npm package — see repo-layout.md) and an android/ and/or ios/ native module exist. If not, STOP with NEEDS_CONTEXT: not a third-party-control repo (no package.json / native module)..extension-state.md — if it carries a ## ppmplugin (third-party controls) block, note the last target choice and last manifest write (the re-run mode below uses them).This stage has two modes, decided by whether the committed ./manifest.json exists:
Validate-and-stage mode (the normal flow). ./manifest.json exists at the repo root (authored by /generate-native-extension). This is the source of truth — do not re-author it. Read it, validate it (Step 3), reconcile its entrypoints to the chosen target (Step 2 → Target only), and write the staged copy (Step 4). Step 2's field-derivation is skipped — the contract is already authored; you're verifying and staging it, not regenerating it. (Optionally re-derive methods from the Android module source and, if they've drifted from ./manifest.json — e.g. a @ReactMethod was added by hand after scaffold — surface the diff and offer to update the committed file; never silently rewrite it.)
Author-from-source mode (fallback). No ./manifest.json exists — a hand-authored native module that skipped the scaffold. Derive every field mechanically from source (Step 2 in full), then write both the committed ./manifest.json and the staged copy (Step 4).
Re-run within a build session. If the staged copy ppmplugin/staging/manifest.json already exists from a prior run, don't blindly overwrite — diff the target/entrypoints against the committed source and ask via AskUserQuestion: Update (re-stage from the current ./manifest.json + target) / Keep as-is (report and stop). Default the target to the prior choice in .extension-state.md; don't re-ask an answered question.
The structure preflight + target selection below run in both modes (you always need to know which platforms are viable and which to ship). The field-derivation sub-section (items 1–6 + the compute block) runs only in author-from-source mode (Step 1.5) — in the normal validate-and-stage mode the fields already live in ./manifest.json; read them from there and skip derivation, keeping only the target choice.
First, run a structure preflight. The ppmplugin path expects the canonical PAM-extension layout — the shape /generate-native-extension produces (see shared/repo-layout.md). A hand-rolled, foreign, or drifted repo may be missing pieces; flag exactly what, here and now, rather than failing later with a cryptic Gradle/Xcode error or a silently-wrong manifest. Print a visible ✓/✗ block:
package.json (dev-only <kebab>-control name — there is no @powerapps/extension-* scope and no src/ TS layer in this track); class name resolvable from the native module (android/.../<Pascal>Module.kt / ios/RCT<Pascal>Module.m), ./manifest.json, or .extension-state.md.android/ present): android/build.gradle; a Kotlin module class extending ReactContextBaseJavaModule with an override fun getName(); a ReactPackage class; ≥1 @ReactMethod.ios/ present): ios/RCT<Pascal>Module.h declaring <RCTBridgeModule>; .m with + (NSString *)moduleName (NOT RCT_EXPORT_MODULE) and ≥1 RCT_EXPORT_METHOD.A platform whose structure is incomplete is not a valid target — exclude it and say which element is missing. If neither platform is structurally complete, STOP with NEEDS_CONTEXT: repo doesn't match the expected PAM-extension layout — missing <list> pointing at shared/repo-layout.md. (Working on a staged copy protects the source; it does NOT make a missing module appear — that's what this preflight is for.)
Then determine which platform(s) this bundle targets (only from the structurally-complete ones) — it controls which entrypoints get declared:
AskUserQuestion: Android-only / iOS-only / Both — offer only the targets that passed the preflight. Default to what's present, or — on a re-run in Update mode — to the prior target recorded in .extension-state.md./build-android-binary is stable; /build-ios-binary is v0 (Mac-only; known limitation: its React-Core weak-link config still needs validation against a live PAM/wrap shell). If the user targets iOS/Both, the manifest declares entrypoints.ios; /assemble-ppmplugin will still gate if the iOS binary isn't staged at packaging time.Then derive fields from the actual files, not from assumptions (author-from-source mode only — in validate-and-stage mode skip to Step 3 with the fields read from ./manifest.json):
Class name <Pascal> — from the native module (the Android <Pascal>Module.kt filename / its getName() = "<Pascal>Module", or the iOS RCT<Pascal>Module), or the .extension-state.md Identity block. There is no src/<Pascal>Extension.ts in this track. This is the basis for name, nativeModule, receivers[].name.
version — package.json version.
nativeModule — read the Android module's override fun getName(): String = "<X>". Use <X> verbatim.
packageClass — read the ReactPackage .kt file: combine its package <...> line with the class name → FQN (e.g. com.powerapps.peninput.PenInputPackage).
methods — scan the Android module (via the Read/Grep tools, not a shell-specific command — this skill is OS-neutral) for @ReactMethod and collect each annotated function name. Cross-check the count against the operations in ARCHITECTURE.md §3 / PRD §4; if a documented operation has no matching @ReactMethod, surface it as a warning (the manifest reflects what the binary actually exposes, but the mismatch usually means an operation wasn't wired).
iOS entrypoint fields (only when targeting iOS / Both) — read ios/RCT<Pascal>Module.h for the class name (@interface RCT<Pascal>Module : NSObject <RCTBridgeModule>) → that is entrypoints.ios.moduleClass. Read ios/RCT<Pascal>Module.m for + (NSString *)moduleName { return @"<X>"; } and assert <X> equals the nativeModule from step 3 — it's the same bridge symbol on both platforms; a mismatch means the iOS and Android modules disagree. (The .m must not use RCT_EXPORT_MODULE — that macro's +load registration is invisible to the framework's dlopen flat namespace, so the module never loads on device.)
Then compute, per ppmplugin-format.md §3:
name = kebab(className) — from the class name, not the capability/repo name. If kebab(className) differs from the repo's capability kebab (e.g. repo powerapps-pdf-control but class PdfViewer → name: pdf-viewer), print a one-line note so the user knows the .ppmplugin filename won't match the repo name. This is required for the canonical-prefix rule to pass.receivers[].name — take it from the PCF if one exists, do NOT blindly default. If a sibling PCF is present (pcf/<…>/index.ts), grep it for the dispatch key — COMPOSITE_KEY = "<name>/<receiver>" (or the ReceiverKey it binds) — and use that <receiver> value, because the PCF already dispatches to it; a manifest that registers a different receiver name will fail on first dispatch (real bug: PCF dispatched to Snapshot while the manifest defaulted to DeviceInfoExtension). Only if no PCF exists, fall back to <Pascal>Extension. Either way, surface the chosen value as a confirmation point: "PCF dispatches to <name>/<receiver>; the manifest will register receiver <receiver> — confirm?" (Audit re-checks this — see /audit-ppmplugin pcf-composite-key-matches-receiver.)
receivers[]IS the runtime dispatch contract (ppmplugin-format §2 — Runtime dispatch contract). The wrap host routes a call by the composite key<name>/<receivers[].name>toNativeModules.<nativeModule>.<method>— there is no TShandleMessageAsync/sendAsynclayer in a native-only bundle. SonativeModulemust equal the module'sgetName(), and every entry inmethodsmust be a real@ReactMethod/RCT_EXPORT_METHODname (the host calls it directly; an absent method =method '<m>' not foundon device). Derivemethodsfrom the module source, never guess.
entrypoints — declare ONLY the chosen target(s):entrypoints.android = { dex: "<Pascal>Plugin.dex", packageClass: "<FQN from step 4>" }entrypoints.ios = { framework: "<Pascal>Plugin", moduleClass: "RCT<Pascal>Module" }Run every rule from ppmplugin-format.md §4 against the derived manifest. For each, pass or fail with the exact rule:
name matches ^[a-z0-9][a-z0-9-]{0,63}$nativeModule starts with the canonical prefix of name — computed precisely as split name on -/_, PascalCase each segment, join (ppmplugin-format §3), Ordinal/case-sensitive. (Note the helloworld → Helloworld subtlety; kebab(className) must hyphenate at camelCase boundaries so the round-trip holds.)nativeModule starts with a reserved prefix (case-insensitive list in §4)nativeModule is a known incompatible exact name — block (Ordinal, case-sensitive) if it matches the locally checked subset in §4 (DeviceInfo, AuthenticationHelper, NetworkClient, DataverseOfflineProvider, IntuneMAM). The subset is non-exhaustive: passing it locally does not guarantee the upload service will accept the name. Rename the module's getName() (and iOS +moduleName) to a non-reserved form — add a Module suffix (DeviceInfo → DeviceInfoModule) or a vendor prefix (ContosoDeviceInfo) — and re-derive nativeModule to match.nativeModule looks like a generic platform noun → WARNING. If nativeModule matches ^(Device|Network|File|Audio|Camera|Sensor|Location|Storage|Notification|Bluetooth|Wifi|Media|Photo|Contact|Calendar|Battery), warn that generic single-noun names are both upload-conflict-prone and collision-prone (NativeModules is a shared namespace across every plugin the wrap host loads). Recommend a Module suffix or vendor prefix. Surface it; let the user proceed if deliberate.methods non-empty; ≤32; each matches ^[a-zA-Z_$][a-zA-Z0-9_$]{0,127}$receivers[].name matches the same JS-identifier regexentrypoints.js, entrypoints.ts, extension.js, extension.hbc, extensionClassName, jsLayer (the bundle is native-only; these are leakage the wrap runtime no longer reads — §4). Since this skill authors the manifest it won't emit them, but the re-run mode reads an existing manifest, so assert it.Print the result as a visible block:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
manifest.json validation
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🟢 ✓ name 'pen-input' — valid kebab identifier
🟢 ✓ nativeModule 'PenInputModule' starts with canonical prefix 'PenInput'
🟢 ✓ nativeModule 'PenInputModule' — no reserved prefix
🟢 ✓ nativeModule 'PenInputModule' — not a known reserved name
🟢 ✓ methods ['capturePenInput'] — non-empty, valid identifiers
🟢 ✓ receiver name 'PenInputExtension' — valid identifier
🟢 ✓ no SDK-era / JS-layer fields (native-only manifest)
🟢 7 checks passed, 0 failed.
ⓘ Known incompatible-name subset checked locally; the upload service may apply additional checks.If any check fails, STOP with BLOCKED: manifest validation — <rule> and the concrete fix (e.g. "rename the Kotlin module's getName() so it starts with PenInput"). Do NOT write an invalid manifest.
Show the manifest (the validated source + the target-reconciled entrypoints) and wait for confirmation (shared-instructions §7.1). On approval:
ppmplugin/ is in .gitignore (append the line if absent). Do not add manifest.json (the committed root file stays tracked).ppmplugin/staging/manifest.json — the contract with entrypoints trimmed to the chosen target(s). This is what /assemble-ppmplugin zips../manifest.json at the repo root (the full contract, all viable platforms) — this is the source of truth the scaffold would normally have produced. In validate-and-stage mode, leave ./manifest.json untouched (it's already the source) unless the user accepted a drift-update offer in Step 1.5.## ppmplugin (third-party controls) block in .extension-state.md (create it if absent — schema in repo-layout.md): set Target, Manifest: staged <ISO timestamp>. This is what the re-run mode (Step 1.5) and the build/assemble skills read for state.Return DONE with the manifest path. Then surface next steps via AskUserQuestion (shared-instructions §9.1), offering the build skill(s) for the chosen target(s):
(For a Both target, list both build skills. Cap at 4 options per AskUserQuestion.)
When the user picks a Run /… option, immediately invoke that skill via the Skill tool in the same turn (sub-skill invocation, shared-instructions §8 + §9.1 "Execute, don't describe"). Do NOT print a "run it when ready" instruction and stop — selecting the option IS the request to run it. Only "Stay" ends the run.
{
"name": "pen-input",
"version": "0.1.4",
"abi": { "compatibleShells": ">=1.0.0", "builtAgainst": "1.0.0" },
"entrypoints": {
"android": { "dex": "PenInputPlugin.dex", "packageClass": "com.powerapps.peninput.PenInputPackage" }
},
"receivers": [
{ "name": "PenInputExtension", "nativeModule": "PenInputModule", "methods": ["capturePenInput"] }
]
}(This example targets Android-only, so entrypoints.ios is omitted. For a Both target it would also carry "ios": { "framework": "PenInputPlugin", "moduleClass": "RCTPenInputModule" }. name = pen-input = kebab of class PenInput; nativeModule = PenInputModule (the Module suffix avoids reserved bare names) and starts with canonical prefix PenInput ✓; not a reserved prefix ✓.)
© microsoft, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in plugins/power-apps-mobile-extension/skills/generate-ppmplugin-manifest of microsoft/power-platform-skills.
Open the folder on GitHubat commit 0d044b8
Generate Ppmplugin Manifest next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Generate Ppmplugin Manifest this skillmicrosoft/power-platform-skills | 972 | — | ~4.8k | Automated safety check: Notes | MIT | |
| Compose Multiplatform Patternsmonta-app/ocpp-emulator | 180 | 5 repos | ~2k | Automated safety check: Pass | Apache-2.0 | |
| Phone HarnessShawnPana/phone-harness | 3.2k | — | ~4.3k | Automated safety check: Pass | MIT | |
| Stylesarindamxd/camerax-android | 132 | 4 repos | ~2.3k | Automated safety check: Pass | Apache-2.0 | |
| Verified Emailarindamxd/camerax-android | 132 | 4 repos | ~4.7k | Automated safety check: Pass | Apache-2.0 | |
| Argent Metro Debuggerbbplayer-app/BBPlayer | 1.1k | — | ~3.4k | Automated safety check: Pass | MIT |
monta-app/ocpp-emulator
Compose Multiplatform and Jetpack Compose patterns for KMP projects — state management, navigation, theming, performance, and platform-specific UI.
ShawnPana/phone-harness
Control the user's phone — an iPhone through the Mac's iPhone Mirroring window, an Android over adb, or a rented cloud Android: open apps, tap, type, swipe, read the screen.
arindamxd/camerax-android
A skill your agent uses to integrate the Jetpack Compose Styles API into an Android project.
arindamxd/camerax-android
Provides a complete workflow for implementing verified email retrieval on Android Credential Manager API.
bbplayer-app/BBPlayer
Debug a JS runtime via CDP using argent debugger tools. An agent skill from bbplayer-app/BBPlayer.
afkT/DevUtils
统一 Android XML 资源命名:layout、drawable、mipmap、color、values、id 的前缀与 snakecase 规则;把颜色/圆角/描边/状态编码进文件名(bg、border、textcolor…selector)。
microsoft/power-platform-skills
Inspects and configures the web application firewall (WAF) in front of a Power Pages production site.
microsoft/power-platform-skills
Inspects and configures the security headers a Power Pages site sends to browsers — Content Security Policy, frame and clickjacking protection, cross-origin sharing, cookie behavior, and related…
microsoft/power-platform-skills
Scans a Power Pages site project for security issues in source code and dependencies.
microsoft/power-platform-skills
Runs a security scan on a deployed Power Pages site, fetches the latest scan report, and produces a plain-language summary.
microsoft/power-platform-skills
Creates Dataverse tables, columns, and relationships for a Power Pages site based on a data model proposal.
microsoft/power-platform-skills
Creates, edits, and manages Power Pages Server Logic files — server-side JavaScript that runs securely on the Power Pages runtime.
Works with
Categories
Validate, reconcile to the chosen target(s), and stage the manifest.json for a .ppmplugin bundle. Generate Ppmplugin Manifest is an agent skill from microsoft/power-platform-skills, published by the product's own GitHub organization.ppmplugin bundle.
Generate Ppmplugin Manifest fits situations like: mobile work in your project.
Run `npx skills add microsoft/power-platform-skills --skill generate-ppmplugin-manifest -a claude-code`. Or copy the skill folder (plugins/power-apps-mobile-extension/skills/generate-ppmplugin-manifest in microsoft/power-platform-skills) into .claude/skills/generate-ppmplugin-manifest in your project. Claude Code loads it when a task matches its description.
Run `npx skills add microsoft/power-platform-skills --skill generate-ppmplugin-manifest -a codex`. Or copy the skill folder (plugins/power-apps-mobile-extension/skills/generate-ppmplugin-manifest in microsoft/power-platform-skills) into .agents/skills/generate-ppmplugin-manifest in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add microsoft/power-platform-skills --skill generate-ppmplugin-manifest -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/generate-ppmplugin-manifest, .gemini/skills/generate-ppmplugin-manifest, .github/skills/generate-ppmplugin-manifest and .opencode/skills/generate-ppmplugin-manifest in your project.
SKILL.md names no scripts, command-line tools or credentials: Generate Ppmplugin Manifest is instructions for the agent only. Our summary lists: A credential in COMPOSITE_KEY. Its frontmatter pre-approves these tools: Read, Write, Edit, Bash, Glob, Grep, AskUserQuestion, Skill.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found notes only (pre-approves every shell command (allowed-tools: bash)), nothing it rates as a warning. It is not a guarantee. Review the folder before installing.
Generate Ppmplugin Manifest is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 4.8k tokens (SKILL.md is roughly 19k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Generate Ppmplugin Manifest: Compose Multiplatform Patterns (monta-app/ocpp-emulator, 180 stars), Phone Harness (ShawnPana/phone-harness, 3.2k stars), Styles (arindamxd/camerax-android, 132 stars) and Verified Email (arindamxd/camerax-android, 132 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
microsoft (a GitHub organization, an official publisher) maintains it in microsoft/power-platform-skills, which has 972 GitHub stars. The repository holds 87 skills in this directory. The repository was last updated on October 7, 2026.
Source: microsoft/power-platform-skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.