关于 publish-pcf-companion
面向已为第三方 `.ppmplugin` 搭建 dispatcher PCF 的工程师,按步骤部署到 Power Platform 环境。它检查目标环境,引导确认发布者前缀和版本,再构建并推送控件。
主要功能
- 01检查 Node.js、pac CLI、.NET 和身份验证
- 02查找 PCF 清单及项目根目录
- 03提示确认发布者前缀和版本
- 04构建 PCF 并运行 `pac pcf push`
适用场景
- 01部署已定制的 dispatcher PCF
- 02推送前确认目标环境
- 03提升 PCF 版本后重新构建
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ microsoft/ power-platform-skills --skill publish-pcf-companion安装后在 Claude Code 中输入/publish-pcf-companion确认已加载。
详细介绍
/publish-pcf-companion
按需将第三方 .ppmplugin 控件的 dispatcher PCF 部署到 Power Platform 环境。dispatcher PCF 是 Studio 端控件,它通过包装壳的 SendMessagePlugin 桥接,将复合键 <name>/<receiver> 分发到控件的原生模块。使用用户当前激活的 pac auth 配置运行 pac pcf push。此流程独立于 /generate-pcf-companion——工程师先在本地搭建脚手架、进行自定义和迭代,然后在准备就绪时部署。
第 1 步 — 阅读共享文档并确认先决条件
-
阅读
shared/shared-instructions.md、shared/naming-conventions.md。 -
应用按技能设置的最小先决条件策略(
shared-instructions.md §1.5)。此技能需要 Node.js 20+ 和 npm、pacCLI、.NET SDK,以及已激活的pac auth配置。不需要 pnpm。继续之前,按照
shared-instructions.md §9.2将先决条件状态打印为可见区块:━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Prereq check — /publish-pcf-companion ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 🟢 ✓ Node.js 20+ and npm installed (for npm install / npm run build) 🟢 ✓ pac CLI installed (for pac pcf push) 🟢 ✓ .NET SDK installed (solution build runs inside pac pcf push) 🟢 ✓ pac auth profile active (target env: <env URL from pac org who>) 🟢 4 checks passed. Ready to proceed.故障修复表:
缺少项 故障区块中的 → Fix:行Node.js / npm 从 https://nodejs.org安装 Node.js 20 LTS,然后使用node -v和npm -v验证pacCLIdotnet tool install -g Microsoft.PowerApps.CLI.Tool(如果 .NET SDK 也缺失,则先安装 .NET SDK).NET SDK brew install dotnet(mac)/winget install Microsoft.DotNet.SDK.10(win)/ 使用包管理器(linux)没有已激活的 pac authpac auth create --environment <your-env-url>(交互式浏览器流程;使用有权访问目标 Power Platform 环境的身份)。不要优先使用--deviceCode——这是无头 shell 环境下的备用方案,在条件访问策略下经常会失败。按照
prereq-check.md运行/publish-pcf-companion检查。根据自动修复策略(shared-instructions §1.5):如果缺少pacCLI 但已安装 .NET,则可自动修复——提供dotnet tool install -g Microsoft.PowerApps.CLI.Tool并在用户回答yes后继续;如果没有已激活的pac auth,则启动pac auth create --environment <url>(浏览器流程),然后验证。如果身份验证尝试失败,按照prereq-check.md中的变体顺序处理(浏览器 → 仅在无头环境下使用设备代码 → 使用--environment返回浏览器流程 →pac auth clear)——每一步都更改一个变量,绝不重新运行已失败的变体。如果缺少 .NET SDK,则必须停止(需要系统范围安装——打印安装命令)。 -
阅读
./PRD.md。此文件为必需项——技能会根据 PRD §2 确定 PCF 文件夹名称(pcf/<Pascal>PCF/)和发布者前缀。如果 PRD 缺失,请停止并显示BLOCKED: PRD.md missing — cannot determine PCF folder name。 -
如果
./.extension-state.md存在,则阅读。状态文件仅供参考;此技能无需该文件也能运行,但会利用其中的 Phase 信息,尽早提示“尚未执行 scaffold-pcf”。
步骤 2 — 检测当前状态
构建状态仪表板,让用户在执行任何操作前查看检测结果。
稳健地发现 PCF 文件夹 — 不要假设嵌套深度固定。使用 Glob 查找
pcf/**/ControlManifest.Input.xml 并选择第一个匹配项。pac pcf init 通常会生成
pcf/<Pascal>PCF/<Pascal>PCF/ControlManifest.Input.xml,但大小写差异和手动重组不应影响发现。如果
pcf/ 不存在,则停止并显示
BLOCKED: no pcf/ directory — PCF has not been scaffolded. Run /generate-pcf-companion first.。如果
pcf/ 存在但清单不存在,则使用 Glob 列出相关文件并停止,显示
BLOCKED: pcf/ exists but no ControlManifest.Input.xml was found.。
从清单路径向上移动两个目录层级,推导出 PCF 项目根目录。使用 Glob
检查 <PCF_PROJECT_ROOT>/out/ 是否存在。使用 Read 从清单中提取 <control version="X.Y.Z">
值,并从 .extension-state.md 中提取最新部署版本。运行
pac org who,因为这是一个真实的工具链命令,用于获取当前活动环境。
打印:
PCF deploy status
─────────────────
Repo: <cwd>
PCF project root: <PCF_PROJECT_ROOT from find>
Manifest: <MANIFEST path>
Built (out/): <yes | no — will build now>
Current manifest version: <CURRENT_VERSION>
Last deployed version: <LAST_DEPLOYED or "none — first deploy">
Publisher prefix: <LAST_PREFIX from .extension-state.md, else `pamext` default — confirmed in Step 3.0>
Active pac auth env: <env URL from `pac org who`>
Active pac auth user: <user from `pac org who`>
Plan: pick publisher prefix → bump version if chosen → build if needed → pac pcf push --publisher-prefix <chosen prefix>
版本为何重要: Power Platform 会在已部署的应用中按版本缓存 PCF 控件。如果你重新推送相同版本,已加载先前捆绑包的应用可能看不到你的更改,直到缓存失效(所需时间不定——有时几分钟,有时几小时,有时需要制作者重新发布应用后才会失效)。最佳实践是在每次有意义的推送时递增补丁版本。
如果 pac org who 返回“ No active connection”:停止——这意味着 pac auth list 显示了一个配置文件,但它当前未被选中。运行 pac auth select --index <n>,然后重新运行此技能。(步骤 1 会发现缺少身份验证的情况;此处会发现较少见的“存在身份验证但未激活”情况。)
为何使用 Glob 而不是精确路径: 标准布局位于项目根目录下两层,但大小写差异、手动重组和非标准脚手架工具都可能出现。Glob 能在不假设固定路径的情况下,以操作系统无关的方式发现文件。
步骤 3 — 与用户确认
此步骤有三个关卡:发布者前缀 → 版本递增 → 部署确认。每个关卡都单独使用一次 AskUserQuestion。
3.0 — 发布者前缀关卡
发布者前缀会成为 Power Platform 中解决方案名称的一部分(例如 pamext_<Pascal>PCF)。它必须为 2–8 个字符——pac pcf push 会拒绝超出此范围的值,并报错 Argument --publisher-prefix has incorrect length。
使用 Read 读取 .extension-state.md,并提取最近一条 Publisher prefix: <value> 记录。如果
文件或记录不存在,则使用 pamext 作为默认值。
然后通过 AskUserQuestion 询问:
此次部署使用什么发布者前缀?(必须为 2–8 个小写字符)
- <LAST_PREFIX>(使用上次部署的前缀)——仅在找到
LAST_PREFIX时显示- pamext(推荐)——6 个字符,意为“PAM Extension”;这是我们为第一方原生扩展 PCF 建议使用的默认值
- mspa — 4 个字符,意为“Microsoft PowerApps”
- 自定义 — 提供你自己的 2–8 个字符前缀(自由文本输入,继续前先验证长度)
验证所选值:
PREFIX="<from user choice>"
PREFIX_LEN=${#PREFIX}
if [ "$PREFIX_LEN" -lt 2 ] || [ "$PREFIX_LEN" -gt 8 ]; then
echo "❌ Publisher prefix '$PREFIX' is $PREFIX_LEN chars; must be 2–8. Try again."
# Re-prompt
fi
if ! [[ "$PREFIX" =~ ^[a-z][a-z0-9]*$ ]]; then
echo "❌ Publisher prefix must start with a lowercase letter and contain only lowercase letters and digits."
# Re-prompt
fi
前缀为何重要: 它会在 Power Platform 的解决方案资源管理器中,将你的 PCF 与同一发布者身份下的其他解决方案归为一组。所有第一方原生扩展 PCF 都应使用相同的前缀,以便它们显示在一起。推荐的 pamext 是项目约定——你的团队可能有自己的约定;在共享环境中选择自定义值前,请先询问。
为何不将其硬编码: 团队或环境可能已经设定了现有的发布者前缀。硬编码“powerapps”有两个问题——它有 9 个字符(超过限制),而且不符合环境约定。
3.1 — 版本升级门槛
使用 AskUserQuestion。根据 CURRENT_VERSION(清单中的当前版本)计算升级目标选项:
当前 PCF 版本:<CURRENT_VERSION>(上次部署:<LAST_DEPLOYED or "never">)
Power Platform 会按版本缓存 PCF。再次推送相同版本可能不会使已使用此控件的应用中的缓存失效。要升级版本吗?
- 补丁版本升级 → <CURRENT major.minor.(patch+1)>(推荐用于修复 bug、内部改进)——通常默认选项
- 次要版本升级 → <CURRENT major.(minor+1).0>(用于新增功能,或添加制作者可选择启用的新输出/可配置输入)
- 主要版本升级 → <(CURRENT major+1).0.0>(用于对绑定输入、输出名称或触发语义进行不兼容更改)
- 不升级 — 按原样以 <CURRENT_VERSION> 推送(仅限初始开发期间的迭代,且接受缓存风险;该技能会打印警告)
使用 Edit 工具应用所选升级,仅替换清单中的 <control version="..."> 属性。
写入前显示确切的版本变更(<CURRENT_VERSION> → <NEW_VERSION>),并保留清单中的其他所有字段。
升级后,必须重新构建(清单已更改,因此 out/ 已过期)。无论用户在下面的 3.2 中如何选择,构建都会作为第 4 步的一部分运行,因此无需担心。
如果用户选择了“不升级”:跳过清单编辑。打印警告:
⚠️ 再次以 <CURRENT_VERSION> 推送。之前加载过此控件的应用,可能要等 PCF 缓存失效后才能看到更改。如果这会造成问题,请在下次推送时升级版本。
3.2 — 部署确认门槛——先说明 ENVIRONMENT
部署到错误环境是已确认的故障模式(曾因环境 URL 埋在冗长的问题中,导致一次发布推送到了 wrap-bug-bash-env,而不是 wrap-player-test-env)。因此,应将目标环境作为此门槛的标题,并明确提供更改环境的选项——绝不能默默复用当前生效的 pac auth。显示当前环境的完整详情(而不只是 URL),让用户能判断这是哪个环境:读取 pac org who(并通过 pac auth list 获取易读的配置文件名称),然后打印:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
►► CURRENT DEPLOY TARGET ◄◄
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Environment: <friendly org name from `pac org who` — e.g. "Contoso Test (default)">
URL: <env-url>
Environment ID:<org/environment id from `pac org who`, if shown>
Signed-in as: <user from `pac org who`>
Auth profile: <active profile name from `pac auth list` (the ★ row)>
Last deployed: <from .extension-state.md PCF deployments — env + timestamp, or "first deploy">
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
然后提出第三个 AskUserQuestion,其问题文本再次逐字写出环境名称,并先让用户决定保留还是更改:
将
<Pascal>PCF@<resolved version>(前缀<PREFIX>)部署到 — 。保留此环境,还是切换环境?
- 是,保留此环境 — 构建并推送(推荐):运行
npm run build,然后运行pac pcf push --publisher-prefix <PREFIX>。- 切换环境——部署前更改目标环境。运行
pac auth list并提供现有配置文件(pac auth select --index <n>),或创建新配置文件(pac auth create --environment <url>),在当前流程中完成——然后重新打印此标题并再次询问。不要让用户退出后重新运行该技能。- 不重新构建,直接推送(仅限未升级版本且信任当前
out/的情况):跳过npm run build。如果 3.1 升级了版本,则禁用此选项——清单升级后必须重新构建。- 取消
环境(易读名称 + URL)和前缀会逐字出现两次(标题区块和问题中)——环境配置中的拼写错误或错误的活动身份验证,最常导致“部署到了错误租户”。即使已有身份验证配置文件,也始终显示当前环境并提供切换选项——绝不要假设当前活动配置文件就是用户想要的配置文件。
第 4 步——执行
4.1 — 按需构建(或始终构建,适用于“是 — 构建并推送”)
使用第 2 步中发现的 $PCF_PROJECT_ROOT——不要硬编码 pcf/<Pascal>PCF:
cd "$PCF_PROJECT_ROOT"
[ -d node_modules ] || npm install --no-audit --no-fund
npm run build --silent
如果构建失败:停止并显示 BLOCKED: pcf-scripts build failed — fix the source and re-run /publish-pcf-companion。请用户前往 /test-native-extension 第 4 层进行诊断。
4.2 — 推送到 Power Platform
cd "$PCF_PROJECT_ROOT"
pac pcf push --publisher-prefix "$PREFIX" # $PREFIX from Step 3.0
前缀 $PREFIX 是用户在步骤 3.0 中选择的,并且已通过长度验证(2–8 个字符)。如果 pac pcf push 仍因 Argument --publisher-prefix has incorrect length 被拒绝,说明下游出现了意外情况(环境配置、较新 pac 版本中的前缀正则表达式变更)——显示原始错误,并重新运行步骤 3.0 选择其他值。
如果目标环境中不存在此前缀对应的发布者,推送会报错:Publisher prefix '$PREFIX' not found。显示此错误,并指引用户选择以下任一操作:
- 请环境管理员添加此前缀:
pac solution publisher-add --prefix "$PREFIX" --name "<publisher name>",或 - 重新运行此技能,并选择环境中已存在的前缀(环境管理员可以通过 Power Platform 管理中心列出这些前缀)。
4.3 — 成功
打印:
🟢 ✓ Deployed <Pascal>PCF to <env-url> at <ISO timestamp>
Solution: <PREFIX>_<Pascal>PCF (verify in https://make.powerapps.com → Solutions)
4.4 — 失败
pac pcf push 可能因多种原因失败。常见原因如下:
| 错误 | 可能的解决方法 |
|---|---|
Publisher prefix '<PREFIX>' not found | 环境管理员需要添加此前缀,或者重新运行步骤 3.0 并选择环境中已存在的前缀 |
Authentication failed / 401 | pac auth 令牌已过期,或配置文件绑定了错误的身份/环境。尝试运行 pac auth select,然后使用 pac auth create --environment <url>(浏览器)重新创建。如果仍然失败,按照 prereq-check.md 中的变体顺序逐一尝试——不要重复尝试相同的变体,也不要默认使用 --deviceCode。 |
Solution import failed: missing dependency | 环境缺少必需的 Power Platform 功能(原生扩展 PCF 很少遇到此问题;显示依赖项名称) |
Build of <Pascal>PCF.csproj failed | PCF 工具尝试运行 dotnet build,但失败了。通常是 out/ 过期所致——运行 rm -rf out/ && npm run build,然后重试。 |
更新 .extension-state.md:在新的 “PCF deployments” 部分下,添加 Deploy: fail — <ISO> — <env-url> — <one-line reason>。停止,并显示 BLOCKED: pac pcf push failed — <reason>。
第 5 步 — 更新状态并总结
推送成功后,更新 ./.extension-state.md:
- 添加(或更新)PCF deployments 部分:
后续每次成功部署时都追加一行。最近的一条放在最底部。## PCF deployments - <ISO timestamp> — <env-url> — Version: <X.Y.Z> — Publisher prefix: <PREFIX> — Result: successVersion:字段的值取自推送时的<control version="..."/>(如果 3.1 更新了版本,则使用更新后的值)。Publisher prefix:字段是用户在步骤 3.0 中选择的值——后续运行会通过 LAST_PREFIX 检测默认使用此值。 - 不要更改 Phase 字段——部署与阶段流程相互独立。
打印最终摘要:
Deploy complete
───────────────
PCF: <Pascal>PCF
Version: <X.Y.Z> ← post-bump if 3.1 bumped; else same as before
Bump: <patch | minor | major | none — re-pushed at same version>
Environment: <env-url>
Publisher prefix: <PREFIX>
Build: <skipped — current out/ used | rebuilt at <time>>
Deployed at: <ISO timestamp>
Where to look next (informational — these are makers-portal steps, not skills):
• Open https://make.powerapps.com → switch to <env> → Solutions → find `<PREFIX>_<Pascal>PCF`.
• In a Canvas app: Insert → Custom → search for `<Pascal>PCF` under the `PowerApps` namespace.
• If a previously-deployed app doesn't show your changes: re-publish that app (File → Save → Publish) to bust the PCF cache.
5.1 后续步骤选择
根据 shared/shared-instructions.md §9.1:通过 AskUserQuestion 提供真正的后续步骤选项,并根据仓库状态提供结合上下文的选项。直接执行,不要描述——用户选择 Run /… 选项时,立即在同一轮中通过 Skill 工具调用该技能(shared-instructions §9.1)。只有退出选项会在不调用任何内容的情况下结束运行。
检测状态以筛选选项:
| 检测条件 | 意味着 |
|---|---|
尚未构建 .ppmplugin 包(ppmplugin/<name>.ppmplugin 不存在) | /generate-ppmplugin 是自然的下一步——已部署调度器 PCF,但它要调度的二进制包仍需构建。 |
.ppmplugin 包已存在(ppmplugin/<name>.ppmplugin 存在) | /audit-ppmplugin 会重新验证已构建的包;/debug-extension 会调试/优化控件。 |
然后调用 AskUserQuestion。典型的部署后选项:
Question: "Dispatcher PCF deployed. What would you like to do next?"
Header: "Next step"
Options:
1. "Run /generate-ppmplugin" description: "Build (or rebuild) the verified .ppmplugin binary bundle end-to-end (manifest → build → assemble → audit) — the bundle this dispatcher PCF routes to over the wrap bridge."
2. "Run /debug-extension" description: "Debug/refine the control (PRD or native/PCF code), then re-deploy with another version bump."
3. "Run /audit-ppmplugin" description: "Re-verify an already-built .ppmplugin bundle against the format spec and the manifest's receiver/method contract."
4. "Stay — I'll verify in Studio" description: "Skill exits. Open make.powerapps.com → your env → find the new PCF in Solutions / insert it in a Canvas app to verify."
说明性信息(不是技能选项): 通过封装向导上传已构建的
.ppmplugin,并将此调度器 PCF 接入画布应用,是第 3 阶段——目前尚无对应技能。构建好包并部署 PCF 后,最后这一步托管需要手动通过 makers 门户 / 封装向导完成。
用户选择 Run /… 选项时,通过 Skill 工具调用该技能。用户选择“Stay”时,输出一行确认部署已完成,然后继续执行返回状态区块。
返回状态协议
| 代码 | 含义 |
|---|---|
DONE | pac pcf push 成功;状态文件已更新部署记录。 |
DONE_WITH_CONCERNS: <list> | Push 成功,但存在注意事项(发布者前缀不匹配且用户接受了替代方案;或 npm run build 产生了用户接受的警告)。 |
NEEDS_CONTEXT: <missing> | 缺少 PRD、尚未搭建 PCF 脚手架,或场景问题中所需的用户输入不完整。 |
BLOCKED: <reason> | 前置条件检查失败(缺少 pac、dotnet 或身份验证),pac pcf push 因非冲突原因(权限、网络)遭拒,npm run build 失败,用户取消,或 pac org who 显示没有活动连接。 |
第一行之后空一行,然后给出便于理解的摘要。
硬性规则
- 未经明确确认环境 URL,绝不推送。 环境 URL 会在第 3 步的问题中原样显示;用户必须针对该 URL 输入
yes。如果环境在第 3 步和第 4 步之间发生变化(例如,并行会话运行了pac auth select),立即停止并重新询问。 - 绝不使用
--force之类的标志来绕过身份验证或解决方案冲突。 如果pac pcf push报错,说明情况并停止——未经用户确认,不要尝试其他前缀或解决方案目标。 - 发布者前缀由用户在部署时选择,不得硬编码。 长度必须为 2–8 个小写字母加数字(在第 3.0 步验证)。如果
.extension-state.md中有上次使用的前缀,则将其设为确认步骤的默认值;否则设为pamext。未经明确确认前缀,绝不推送——环境通常已有既定前缀,使用错误的前缀会产生孤立解决方案。 - 绝不部署到用户未明确授权的环境。 此技能会读取当前激活的
pac auth配置文件;如果用户想使用其他环境,必须先切换环境,再运行此技能。 - 未经确认,不要自动提升版本。 PCF 版本(清单中的
<control version="X.Y.Z">)决定 Power Platform 的缓存失效行为。此技能必须在第 3.1 步通过AskUserQuestion呈现版本提升选项,默认突出显示修补版本提升,并逐字应用用户选择的提升方式。绝不悄悄提升版本,也绝不跳过提示——工程师需要在操作前看到“我们将更改清单版本”。 - 提升清单版本后必须重新构建。 如果第 3.1 步更改了清单,则必须禁用或取消提供第 3.2 步中的“不重新构建直接推送”选项——使用新的清单版本推送过时的
out/是实际错误(部署的捆绑包将与解决方案中声明的版本不一致)。 - 不要在没有 PRD.md 的目录中运行。 此技能需要根据 PRD §2 推导 PCF 文件夹名称;没有该文件时,只能靠猜测。