mcpField
G
generate-ppmplugin

generate-ppmplugin

github.com/microsoft开发1.1k71 次安装今天更新
代码仓库

关于 generate-ppmplugin

generate-ppmplugin 是面向第三方控件开发者的 .ppmplugin 构建编排技能。它依次运行清单生成、平台构建、打包和审计技能,协调目标选择,并在阶段失败时提供后续处理指引。

主要功能

  1. 01编排完整构建流程
  2. 02检测可用的原生目标
  3. 03协调 Android 和 iOS 构建
  4. 04打包并审计软件包
  5. 05报告阶段失败及处理指引

适用场景

  1. 01从控件仓库构建经过验证的软件包
  2. 02为选定的原生平台运行构建流程
  3. 03确定需要处理的构建阶段

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/microsoft/power-platform-skills --skill generate-ppmplugin

安装后在 Claude Code 中输入/generate-ppmplugin确认已加载。

详细介绍

/generate-ppmplugin

第三方控件构建流程的推荐入口。在常规流程中,用户调用 /generate-ppmplugin,它会按顺序驱动五个阶段技能(/generate-ppmplugin-manifest、/build-android-binary、/build-ios-binary、/assemble-ppmplugin、/audit-ppmplugin)。高级用户可以直接调用某个阶段,以便重新运行或仅调试该阶段。检查仓库,选定合适的目标集,依次运行 manifest → 构建技能 → assemble → audit,并在磁盘上生成经过验证的 .ppmplugin(或在失败阶段明确停止)。

阅读 shared/ppmplugin-format.md §1,了解此编排器生成的捆绑包布局。

此技能不做什么

  • 不会编写 manifest、构建 DEX、构建框架、压缩捆绑包或运行审计——这些工作由各阶段技能负责。此技能会按正确顺序、使用正确的输入调用这些技能,并在阶段之间设置关卡。
  • 不会跳过任何阶段的确认、失配关卡或替换已有文件的提示——这些仍会显示给用户。编排器只负责免去“下一步运行哪个阶段?”的决策,让用户无需直接调用阶段技能。
  • 不会上传到 Dataverse,也不会接入 canvas 应用(阶段 3 — 暂缓)。
  • 不会编辑 src/、ios/、android/ 下的源代码——每个阶段都会从暂存副本构建。从构建角度看,仓库是只读的。

第 1 步 — 阅读共享文档和前置条件摘要

  1. 阅读 shared/shared-instructions.md 和 shared/ppmplugin-format.md。
  2. 确认工作目录是第三方控件仓库:其中有一个 package.json(仅供开发使用的 <kebab>-control 名称——不是已发布的 @powerapps/extension-* 作用域;此流程会交付二进制文件,而不是 npm 包),并且包含 android/ 或 ios/(或两者)。如果缺少,请以 NEEDS_CONTEXT: not a third-party-control-ready repo — missing <list> 停止,并指向 shared/repo-layout.md。
  3. 打印编排器的前置条件摘要块(调用子技能时,它们会各自重新检查前置条件——此处的摘要会预先展示给用户,让用户了解端到端所需条件):
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 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 根据 .h/.m 源文件和 react-native devDep 头文件构建,而非根据 podspec 构建)

打印一个醒目的 ✓/✗ 区块:

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 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 格式至少需要一个原生入口点;仅包含 manifest 的捆绑包无法交付。


步骤 3 — 推荐并确认目标集合

使用步骤 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 可行,就不要提供“Both”或“iOS only”——只需确认“Android-only”(即使只有一个选项,也值得确认,以便用户可以取消)。

**仅限 Mac 的限制:**如果用户在非 Mac 上选择 Both 或 iOS-only,显示一行警告(/build-ios-binary 仅支持 Mac,到达该步骤时会中止协调器)。提供改为 Android-only 或停止的选项。

记录所选目标集合;这是所有下游子技能都会遵循的约定。


步骤 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 询问目标(默认采用协调器在步骤 3 中选择的目标——记录在 .extension-state.md 中,因此子技能无需重复询问),并返回 DONE 及暂存清单路径。

**重新运行安全性。**如果之前运行时已存在暂存清单,子技能的重新运行模式(其 SKILL.md 中的步骤 1.5)会处理更新或保持原样;这不属于协调器的职责。

4.2 — 尽可能并行运行构建技能

Android 和 iOS 构建彼此独立——它们操作不同的暂存目录(ppmplugin/staging/android-build/ 与 …/ios-build/),并生成不同的输出。两者都被选中时,应并发运行:

目标集合调用的子技能
仅 AndroidSkill: build-android-binary
仅 iOSSkill: build-ios-binary
两者两者都调用,在同一轮中并行调用 Skill 工具

每个构建技能都会返回 DONE(附带暂存二进制文件路径)或 BLOCKED(前置条件/构建失败)。如果目标为 Both,且一个构建失败、另一个成功,则通过 AskUserQuestion 询问:

“/build-<platform> 失败;/build-<other> 成功。你想如何继续?”

  • 修复并重新运行失败的构建 — 停止协调器;由用户调查失败原因
  • 仅发布 <other> — 从目标集合中移除失败的平台,继续组装
  • 停止

如果两者都失败 → 以 BLOCKED: no platform built — see sub-skill output above 停止。

4.3 — /assemble-ppmplugin

调用 Skill: assemble-ppmplugin。该阶段会将清单的原生入口点与暂存二进制文件协调一致、重新验证、打包为 ZIP 并进行校验。它会返回 DONE 及 .ppmplugin 路径。

如果用户在步骤 4.2 中移除了一个平台(仅发布 <other>),该阶段自己的协调门控会询问是否从 manifest.json 中移除缺失的入口点——应接受,因为协调器已在上游做出该决定。如果底层工具允许,则直接传递该决定,不要再次询问。

4.4 — /audit-ppmplugin(最终验证关卡)

对 /assemble-ppmplugin 刚生成的 .ppmplugin 调用 Skill: audit-ppmplugin(传入捆绑包路径)。此关卡确保产物不只是“格式正确的 zip”,而是真正“能在设备上加载”:它会针对构建产物重新运行验证器规则,扫描 DEX 中是否泄漏了 SDK 时代的内容(INativeExtension*、sendAsync、HermesBytecodeLoader 等),检查清单与捆绑包的一致性以及源码到接收器的契约,并给出判定结果。

  • DONE(0 个 CRITICAL)→ 捆绑包已验证;继续执行步骤 5,并报告 READY TO UPLOAD。在最终报告中列出任何 WARNING。
  • BLOCKED(≥1 个 CRITICAL)→ 不要报告成功。停止并列出审计发现的 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(Stage 3 目前还不是一个技能)

返回 DONE 并附上捆绑包路径。只有审计返回 DONE 时,才报告此区块——未通过审计的捆绑包必须通过下方的失败交接报告,绝不能作为成功报告。


失败交接

编排器的价值在于为正常流程提供单一入口点。发生失败时,应将问题明确呈现,而不是自行处理。每条交接都会指出失败阶段,通常会告知用户修复后重新运行 /generate-ppmplugin;只有在有针对性地重跑或诊断时,才直接调用阶段:

失败交接消息
清单推导受阻BLOCKED at manifest stage — <reason>. Fix the flagged item, then re-run /generate-ppmplugin.
Android 构建失败BLOCKED at android-build stage — <reason>. The manifest in ppmplugin/staging/manifest.json is preserved; re-run /generate-ppmplugin after fixing.
iOS 构建失败(仅限 Mac)BLOCKED at ios-build stage — <reason>. If you don't have Xcode here, re-run on a Mac or pick "Android-only" target.
组装失败BLOCKED at assemble stage — <reason>. The staged binaries are intact; re-run /generate-ppmplugin after fixing.
审计发现 CRITICALBLOCKED at audit stage — <N> CRITICAL finding(s). The .ppmplugin was built but is NOT upload-ready. <first finding + its routed fix>. Fix upstream, then re-run /generate-ppmplugin.

绝不要将部分完成或未经验证的 .ppmplugin 报告为成功。缺少已声明入口点的捆绑包,或 DEX 中包含 SDK 泄漏的捆绑包,会在上传时失败,或在设备上悄无声息地失效;请在此处明确指出问题。

评论

支持 Markdown