generate-ppmplugin について
generate-ppmpluginは、サードパーティ製コントロールの.ppmpluginを構築する開発者向けのオーケストレーションスキルです。マニフェスト生成、プラットフォームビルド、パッケージ化、監査を順に実行し、対象選択を調整して、失敗時は次の対応を案内します。
主な機能
- 01ビルド工程全体のオーケストレーション
- 02利用可能なネイティブ対象の検出
- 03AndroidとiOSのビルド調整
- 04パッケージの作成と監査
- 05工程の失敗と対応先の提示
活用シーン
- 01コントロールのリポジトリから検証済みパッケージを作成
- 02選択したネイティブ対象でビルド工程を実行
- 03対応が必要なビルド工程の特定
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ microsoft/ power-platform-skills --skill generate-ppmpluginインストール後、Claude Code で/generate-ppmpluginを入力して読み込まれたか確認します。
詳細
/generate-ppmplugin
サードパーティコントロールのビルドトラックで推奨されるエントリーポイントです。通常のフローでは、ユーザーが /generate-ppmplugin を呼び出すと、5 つのステージスキル(/generate-ppmplugin-manifest、/build-android-binary、/build-ios-binary、/assemble-ppmplugin、/audit-ppmplugin)が順番に実行されます。上級ユーザーは、特定のステージだけを再実行またはデバッグするために、そのステージを直接呼び出すこともできます。リポジトリを調査して適切なターゲットセットを選び、マニフェスト → ビルドスキル(複数可)→ アセンブル → 監査の順に実行し、ディスク上に検証済みの .ppmplugin を生成します(または、失敗したステージを明示して処理を停止します)。
このオーケストレーターが生成するバンドルのレイアウトについては、shared/ppmplugin-format.md §1 をお読みください。
このスキルが行わないこと
- マニフェストの作成、DEX のビルド、フレームワークのビルド、バンドルの ZIP 化、監査の実行は行いません。これらは各ステージスキルが担当します。このスキルは、適切な入力を使って正しい順序で各スキルを呼び出し、ステージ間のゲートを管理します。
- 各ステージの確認/不一致ゲート/既存ファイルの置き換え確認を省略しません。これらは引き続きユーザーに表示されます。オーケストレーターは「次にどのステージを実行するか」という判断だけをなくし、ユーザーがステージを直接呼び出す必要がないようにします。
- Dataverse へのアップロードやキャンバスアプリへの組み込みは行いません(ステージ 3 — 保留中)。
src/、ios/、android/配下のソースコードは編集しません。各ステージはステージングされたコピーからビルドします。ビルドの観点では、リポジトリは読み取り専用です。
ステップ 1 — 共通ドキュメントと前提条件の概要を読む
shared/shared-instructions.mdとshared/ppmplugin-format.mdを読みます。- 作業ディレクトリがサードパーティコントロールのリポジトリであることを確認します。
package.json(開発専用の<kebab>-controlという名前。公開済みの@powerapps/extension-*スコープではありません。このトラックでは npm パッケージではなくバイナリを配布します)と、android/またはios/(あるいは両方)が必要です。いずれかが不足している場合は、NEEDS_CONTEXT: not a third-party-control-ready repo — missing <list>として処理を停止し、shared/repo-layout.mdを案内します。 - オーケストレーターの前提条件ブロックを表示します(サブスキルは呼び出し時にそれぞれ独自の前提条件チェックを再実行します。これは最初にユーザーに提示する概要で、エンドツーエンドで必要なものを把握してもらうためのものです)。
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Prereqs — /generate-ppmplugin (end-to-end)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
/generate-ppmplugin-manifest — no toolchain (pure read + validate + write)
/build-android-binary — JDK 17, Android SDK Build-Tools 35 (d8), Gradle
/build-ios-binary — Xcode 16+ (26.2+ recommended; CocoaPods optional — header-only path) (Mac-only)
/assemble-ppmplugin — jar (JDK)
/audit-ppmplugin — jar (JDK); dexdump or strings (DEX scan)
各ステージに到達した時点で、そのステージ固有の前提条件エラーが表示されます(ユーザーが別のマシンに持っている可能性のあるツールが見つからないことを理由に、オーケストレーターで事前に失敗させないでください)。
ステップ 2 — 利用可能なターゲットを検出する
リポジトリを調べ、実際にビルド可能なネイティブプラットフォームを確認します。検出は構造に基づくもので、将来の予定に基づくものではありません。ソースが存在しないプラットフォームは配布できません。
| ターゲット | 検出条件 |
|---|---|
| Android | android/build.gradle が存在し、android/src/main/java/**/*.kt に ReactContextBaseJavaModule のサブクラスが含まれている |
| iOS | <RCTBridgeModule> を宣言する ios/RCT*Module.h と、+ (NSString *)moduleName を含む .m が存在する(RCT_EXPORT_MODULE ではありません)。podspec は任意です。追加の iOS システムフレームワークを宣言する場合にのみ使用します。/build-ios-binary は podspec ではなく、.h/.m のソースと react-native の devDep ヘッダーからビルドします。 |
✓/✗ のブロックを見やすく表示します。
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Targets available in this repo
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🟢 ✓ Android — android/build.gradle + PenInputModule.kt found
🟢 ✓ iOS — ios/RCTPenInputModule.h (+ .m with +moduleName) found
(検出条件を満たしているように見えても形式が不正な場合(例:android/ は存在するものの Kotlin モジュールがない場合)は、具体的な不足内容を添えて ✗ として表示します。より詳細な構造の事前チェックは /generate-ppmplugin-manifest が行います。このオーケストレーターでは、そのプラットフォームを実行可能なターゲットと見なせるだけの要件が満たされているかを確認します。)
どちらのターゲットも実行可能でない場合は、NEEDS_CONTEXT: no native target available — repo has neither a buildable android/ nor ios/ module として処理を停止します。.ppmplugin 形式には少なくとも 1 つのネイティブエントリーポイントが必要です。マニフェストのみのバンドルは配布できません。
Step 3 — 推奨するターゲットセットを提示して確認する
Step 2 での検出結果を使って推奨オプションを事前に選択し、AskUserQuestion で確認します。
- 両方が利用可能 → 両方を推奨します。理由:パイプライン全体を一度に実行でき、ユーザーはすべてのモバイルプラットフォームで動作するバンドルを取得できます。
- Android のみ利用可能 → Android のみを推奨します。ビルドする iOS ソースがありません。
- iOS のみ利用可能 → iOS のみを推奨します。ビルドする Android ソースがありません。
Question: Which target(s) should this .ppmplugin ship?
- Both (Recommended) — runs /build-android-binary AND /build-ios-binary
- Android only — skips iOS even though the source is here
- iOS only — skips Android even though the source is here
ターゲットが実行可能なオプションのみを表示します。Android のみが実行可能な場合は、「両方」や「iOS のみ」を提示せず、「Android のみ」の確認だけを行います(ユーザーがキャンセルできるよう、選択肢が 1 つでも確認する価値があります)。
Mac のみという制約について: Mac 以外の環境でユーザーが「両方」または「iOS のみ」を選択した場合、1 行の警告(/build-ios-binary は Mac 専用で、実行時にオーケストレーターを停止します)を表示します。Android のみで続行するか、停止するかを提示します。
選択されたターゲットセットを記録します。これは、後続のすべてのサブスキルが参照する契約です。
Step 4 — 各ステージを順番に実行する(ゲートあり)
各ステージを Skill ツール経由で呼び出します。各ステップの結果を確認し、DONE の場合は続行し、BLOCKED / NEEDS_CONTEXT の場合は、明確な引き継ぎを行ってオーケストレーターを停止します。自動での復旧は試みないでください。ステージの失敗は、ユーザーによる確認が必要であることを示しています。
4.1 — /generate-ppmplugin-manifest
Skill: generate-ppmplugin-manifest を呼び出します。通常のフローでは、コミット済みの ./manifest.json がすでに存在するため(スキャフォールド時に /generate-native-extension が作成済み)、サブスキルはそれを検証し、選択されたターゲットに合わせて entrypoints を調整し、ステージング済みのビルド用コピー ppmplugin/staging/manifest.json を書き込みます。契約を新たに作成するわけではありません。(リポジトリに ./manifest.json がない場合(手作業で作成されたモジュールの場合)、サブスキルはソースから作成します。)サブスキルは独自の構造の事前チェックを実行し、AskUserQuestion でターゲットを確認します(デフォルトは Step 3 でオーケストレーターが選択した値です。サブスキルが不必要な再確認を求めないよう、.extension-state.md に記録されています)。その後、ステージング済みマニフェストのパスとともに DONE を返します。
再実行時の安全性。 前回の実行でステージング済みマニフェストがすでに存在する場合は、サブスキルの再実行モード(SKILL.md の Step 1.5)が更新/現状維持を処理します。これはオーケストレーターの担当範囲ではありません。
4.2 — 可能な場合はビルドスキルを並行して実行する
Android ビルドと iOS ビルドは独立しています。それぞれ異なるステージングディレクトリ(ppmplugin/staging/android-build/ と …/ios-build/)を操作し、異なる出力を生成します。両方が選択されている場合は、並行して実行します。
| ターゲットセット | 呼び出すサブスキル |
|---|---|
| Android のみ | Skill: build-android-binary |
| iOS のみ | Skill: build-ios-binary |
| 両方 | 両方を 1 回のターンで実行(Skill ツール呼び出しを並行実行) |
各ビルドスキルは、DONE(ステージング済みバイナリのパスを含む)または BLOCKED(前提条件/ビルドの失敗)を返します。「両方」がターゲットで、一方のビルドが失敗してもう一方が成功した場合は、AskUserQuestion で確認します。
"
/build-<platform>は失敗しましたが、/build-<other>は成功しました。どのように進めますか?"
- 修正して失敗したビルドを再実行する — オーケストレーターを停止します。ユーザーが失敗の原因を調査します
<other>のみを出荷する — 失敗したプラットフォームをターゲットセットから除外し、アセンブルを続行します- 停止
両方が失敗した場合 → BLOCKED: no platform built — see sub-skill output above で停止します。
4.3 — /assemble-ppmplugin
Skill: assemble-ppmplugin を呼び出します。このステージでは、マニフェストのネイティブエントリポイントとステージング済みバイナリを照合して調整し、再検証、ZIP 化、検証を行います。.ppmplugin のパスとともに DONE を返します。
ユーザーが Step 4.2 でプラットフォームを除外した場合(<other> のみを出荷する場合)、このステージ独自の調整ゲートで、不足しているエントリポイントを manifest.json から削除するかどうかが提示されます。オーケストレーターがすでに上流でその判断を行っているため、削除を承認してください。基盤ツールが許す場合は、再確認せずにそのまま処理を進めます。
4.4 — /audit-ppmplugin(最終検証ゲート)
/assemble-ppmplugin が直前に生成した .ppmplugin に対して Skill: audit-ppmplugin を実行します(バンドルのパスを渡します)。これは、「正しい形式の zip」を「実際にデバイスで読み込めるもの」にするためのゲートです。ビルド済みの成果物に対してバリデーターのルールを再実行し、SDK 世代の漏出(INativeExtension*、sendAsync、HermesBytecodeLoader、…)がないか DEX をスキャンし、マニフェストとバンドルの整合性、およびソースからレシーバーまでの契約を確認して、判定を返します。
DONE(CRITICAL が 0 件)→ バンドルは検証済みです。ステップ 5 に進み、アップロード準備完了と報告します。WARNING があれば、最終レポートに記載します。BLOCKED(CRITICAL が 1 件以上)→ 成功と報告してはいけません。監査の CRITICAL 指摘と、担当ステージへの引き継ぎを伝えて停止します(監査により、各指摘は/generate-ppmplugin-manifestまたはビルドスキルにすでに振り分けられています)。バンドルはディスク上に存在しますが、アップロード準備はできていません。ユーザーが上流の問題を修正してから/generate-ppmpluginを再実行します。
オーケストレーターが監査を自動実行するため、正常に完了する場合、ユーザー自身が /audit-ppmplugin を実行することはありません。これは最後の内部ステージです。
ステップ 5 — レポート
最終成果物を、情報を示すブロックとして表示します(質問は含めません)。
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
/generate-ppmplugin — DONE
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Bundle: ppmplugin/pen-input.ppmplugin (v0.1.4) ✓ audit: READY TO UPLOAD
Target: Both (Android DEX + iOS framework)
Steps: manifest ✓ build-android ✓ build-ios ✓ assemble ✓ audit ✓
Next: • deploy the dispatcher PCF → /publish-pcf-companion
• upload this .ppmplugin via the wrap wizard + wire the PCF into a
canvas app (Stage 3 — not yet a skill).
次に、実行可能な次のステップを AskUserQuestion で提示します(shared-instructions §9.1 — Skill ツール経由で実行してください)。
- /publish-pcf-companion を実行(ディスパッチャー PCF を Power Platform 環境にデプロイします。キャンバスアプリでコントロールを動作させるには、事前にこの作業が必要です)
- /debug-extension を実行(コントロールをデバッグして調整し、その後
/generate-ppmpluginを再実行します) - 続行せず、.ppmplugin を手動でアップロードする(ステージ 3 はまだスキルではありません)
バンドルのパスとともに DONE を返します。このブロックを報告するのは、監査が DONE を返した場合のみです。監査に失敗したバンドルは、以下の失敗時の引き継ぎを通じて報告し、成功として報告してはいけません。
失敗時の引き継ぎ
オーケストレーターの価値は、正常に完了する場合の単一のエントリーポイントです。失敗時には、その問題を吸収せずに表面化させる必要があります。各引き継ぎでは、失敗したステージを示し、通常は問題を修正してから /generate-ppmplugin を再実行するようユーザーに伝えます。特定ステージを直接実行するのは、対象を絞った再実行や診断の場合に限ります。
| 失敗 | 引き継ぎメッセージ |
|---|---|
| マニフェストの導出がブロックされた | マニフェストステージで BLOCKED — <理由>。指摘された項目を修正してから、/generate-ppmplugin を再実行してください。 |
| Android ビルドに失敗 | android-build ステージで BLOCKED — <理由>。ppmplugin/staging/manifest.json のマニフェストは保持されています。修正後、/generate-ppmplugin を再実行してください。 |
| iOS ビルドに失敗(Mac のみ) | ios-build ステージで BLOCKED — <理由>。ここで Xcode を利用できない場合は、Mac で再実行するか、「Android-only」ターゲットを選択してください。 |
| 組み立てに失敗 | assemble ステージで BLOCKED — <理由>。ステージング済みのバイナリはそのままです。修正後、/generate-ppmplugin を再実行してください。 |
| 監査で CRITICAL が見つかった | audit ステージで BLOCKED — CRITICAL の指摘が <N> 件あります。.ppmplugin はビルドされましたが、アップロード準備はできていません。<最初の指摘と、その指摘に振り分けられた修正方法>。上流の問題を修正してから、/generate-ppmplugin を再実行してください。 |
一部のみ、または未検証の .ppmplugin を成功として報告してはいけません。宣言されたエントリーポイントがないバンドルや、DEX に SDK 漏出が含まれるバンドルは、アップロード時に失敗するか、デバイス上で予期せず動作しなくなります。ここでその不備を明らかにしてください。