bama
BAMA: 모든 Mac 앱을 만들 수 있습니다
Claude Code 스킬로 PCF 컨트롤을 만들고, 미리보기·통합·문제해결·패키징·안전 배포
Claude Code skill for creating, previewing, integrating, troubleshooting, packaging, and safely deploying Power Apps Component Framework (PCF) controls.
스킬PowerShellGitHub @dinaomran직접 설치운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
설치형 프로젝트는 배포 도메인 없이도 확인할 수 있습니다. 개인 저장소는 GitHub 로그인으로, 조직 저장소는 위의 저장소 확인 파일로 직접 확인해 주세요.
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
A Claude Code and Codex skill (distributed as a plugin for both) that
turns "build me a PCF control" into a gated, resumable engineering
workflow instead of a one-shot code dump.README 전문 보기 ↗A Claude Code and Codex skill (distributed as a plugin for both) that turns "build me a PCF control" into a gated, resumable engineering workflow instead of a one-shot code dump.
It guides you end-to-end through creating, previewing, integrating,
troubleshooting, packaging, and safely deploying Power Apps Component
Framework (PCF)
controls for Dataverse — field and dataset templates, React virtual
controls, and standard controls — with explicit approval gates the first
time a control's UI is finalized and the first time its manifest is
built. Once a control has cleared those two approvals, later updates
(bug fixes, styling changes, new properties — anything short of an
architectural rewrite) ship without asking again — see
One-time design/manifest approval.
Deployment to test/UAT/staging/production always requires a
separate, explicit confirmation regardless of the above; a
development-classified environment deploys automatically, with no
confirmation step, including its first deployment — see
Automatic deployment to development environments.
Instead of generating a full control in one pass, the skill works through 13 stages with 3 hard approval gates:
S1 Requirement discovery S8 PCF integration
S2 Prerequisite inspection S9 Local validation + test
S3 Scaffold / assessment S10 Deployment preparation
S4 React design + preview S11 ══ GATE C: typed confirmation ══
S5 ══ GATE A: design approval ══ S12 Remote operation
S6 Manifest design proposal S13 Post-deployment verification
S7 ══ GATE B: manifest approval ══
ControlManifest.Input.xml. Also applies once per control.test/UAT/staging/
production, you must type an exact confirmation string naming the
solution, version, and target environment. It's single-use and
invalidated by any subsequent change. One documented exception:
development-classified deployments never go through Gate C, including
the first push to a brand-new dev environment — see
Automatic deployment to development environments
below. pac solution publish (which affects an entire environment, not
just one control) always requires confirmation, for any classification.Between stages, the skill reads your project instead of guessing: it checks
installed tooling versions, reads package.json before running any script,
reads the existing manifest before proposing changes, and never hard-codes
a version number, environment URL, or publisher prefix.
Developers and consultants building or maintaining PCF controls for Dataverse/Power Apps who want an assistant that:
pac command against test/UAT/staging/
production without your explicit, typed confirmation. (Pushes to a
development environment run automatically, by design — see
Automatic deployment to development environments.)It assumes you already have (or are willing to install yourself) the
Power Platform CLI (pac), Node.js/npm, and — for solution packaging — the
.NET SDK or MSBuild. The skill checks for these and reports what's missing;
it never installs anything for you.
Works the same way in the Claude Code CLI and the VS Code / JetBrains extensions.
From the Claude Code chat UI:
/plugin).https://github.com/dinaomran/pcf-control-builder-skillFrom the command line, inside a Claude Code chat:
/plugin marketplace add dinaomran/pcf-control-builder-skill
/plugin install pcf-control-builder@pcf-tools
If Claude Code reports that the plugin needs activating, run
/reload-plugins.
If you'd rather not use the plugin/marketplace system, copy
skills/pcf-control-builder/ into:
~/.claude/skills/pcf-control-builder/ — available in every project, or<your-project>/.claude/skills/pcf-control-builder/ — available in that
project onlyClaude Code picks up skill folders live; no restart is needed.
The same repository is also a Codex plugin, with its own Codex
marketplace (.agents/plugins/marketplace.json).
Codex reads the portable root plugin.json for the
plugin's identity and version, and
.codex-plugin/plugin.json for its Codex
display metadata. Everything points at the same skills/ folder, so
Claude Code and Codex run the identical skill.
codex plugin marketplace add dinaomran/pcf-control-builder-skill
codex plugin add pcf-control-builder@pcf-tools
Or run /plugins in Codex, open the PCF Tools marketplace, and
install PCF Control Builder. The Codex extension for VS Code shares
the CLI's ~/.codex configuration, so a plugin installed either way is
available there too. Start a new Codex chat afterwards: the skill
triggers automatically on PCF requests, and Codex lists it as
pcf-control-builder:pcf-control-builder.
The root plugin.json follows the open
Agent Plugins 1.0 format, which
VS Code's agent plugins detect from its $schema. Run Chat: Install
Plugin From Source from the Command Palette and enter
https://github.com/dinaomran/pcf-control-builder-skill.
Once installed, you don't need a special command — the skill triggers automatically whenever your request matches PCF/Power Apps component framework work. Just describe what you need, for example:
"Build me a PCF field control that lets a user pick a color for a Dataverse text column."
"I have an existing PCF dataset control — add a filter property and refresh the manifest types."
"Package and push my PCF control to my dev environment."
The skill's trigger vocabulary includes terms like PCF, Power Apps
component framework, ControlManifest, pac pcf, pcf-scripts,
refreshTypes, and verbs like design, scaffold, build, version, package,
push, import, and publish. If you want to be explicit, you can also say
"use the PCF control builder skill" at the start of your request.
Claude Code asks for approval before running any shell command that isn't
already allowlisted in your settings. This is a separate layer from the
skill's own Gate C — allowlisting a command here only removes Claude
Code's own popup; it does not by itself grant the skill permission to
deploy anywhere. The skill's chat-level confirmation requirement (typed
DEPLOY ... / CONFIRM PRODUCTION IMPORT ...) still applies on top of
whatever's allowlisted here, for test/UAT/staging/production — see
Automatic deployment to development environments
for the one classification where it doesn't.
Read-only commands (npm run build, node --version, pac auth who,
pac solution list, pac solution check, git status, …) never need a
popup at all — they can't write to anything. Push/import commands can
safely be allowlisted here too, because the skill's own confirmation
requirement is independent of this layer and still governs
test/UAT/staging/production regardless of what's allowlisted. A
starting set:
{
"permissions": {
"allow": [
"Bash(node --version)", "Bash(npm --version)",
"Bash(npm run build*)", "Bash(npm run refreshTypes*)",
"Bash(npm run lint*)", "Bash(npm start*)", "Bash(npm ci*)",
"Bash(pac --version)", "Bash(pac * help)",
"Bash(pac auth list)", "Bash(pac auth who)",
"Bash(pac solution list*)", "Bash(pac solution check*)",
"Bash(dotnet --version)", "Bash(dotnet --list-sdks)",
"Bash(git status*)",
"Bash(pac pcf push*)", "Bash(pac solution import*)"
]
}
}
Deliberately left off: pac solution publish and pac auth create.
Publish affects every customization in an environment, not just this
control, and always requires its own explicit confirmation regardless of
classification — allowlisting it here would remove the only thing still
protecting against an accidental environment-wide publish. Auth-profile
creation is a one-time setup action with no routine-friction benefit to
allowlisting.
Gate A (React design) and Gate B (manifest) apply once per control — the first time it's ever built. The first time you build a new control, you see the actual rendered UI and the full manifest proposal and type approval for both, exactly as always. Once both are approved and recorded for that control, no later update reopens either gate — not a bug fix, not a styling change, not a new or changed manifest property, not a new feature. The change is made, a short summary of what it actually did is shown, and work continues straight through validation and deployment with no "do you approve" question for design or manifest, ever again, for that control.
The one exception: converting a standard control to a React control.
That's an architectural rewrite — a different base interface, a
rewritten index.ts, new platform-library entries — not an update, and
it always requires the full design and manifest approval again regardless
of the control's history.
What's still shown, even though nothing blocks on it: every update is labeled honestly before it runs — a defect correction (the control now finally does what was already approved; e.g. a broken localization string or a data-fetch bug that left a required field blank) or a design change (something new — a restyle, a new state, an interaction nobody had approved yet). Styling/CSS changes default to the design-change label. This labeling doesn't gate anything anymore; it's just honesty about what shipped, and it's recorded in the control's spec file so a later session — or you — can see what changed since the one approval on record.
The trade-off, stated plainly: once a control has cleared its first
design and manifest review, nothing else stops a wrong or unwanted change
from shipping to a development environment before you see it — you'll
learn what happened from the pre-run summary and the post-deployment
report, not from a preview you approved in advance. Deployment to
test/UAT/staging/production is unaffected by any of this — Gate C
still requires its own explicit confirmation there regardless of what
Gate A/B's history looks like, so a genuinely wrong change still has a
backstop before it reaches a shared or production environment, even
though nobody reviewed the design or manifest change itself at that point.
A preview that doesn't render is a failure the skill has to catch and tell you about — not something you should have to discover and report yourself.
Every command in the preview stage has its exit status and output read, and the page itself is checked (mount root non-empty, no console error, no error overlay, screenshots looked at before they're shown). If anything fails — a non-zero exit, an error in the output, a blank page — you're told immediately, with the exact error text and the one targeted change being applied. Then the same command and the same check are re-run, and you're asked to reload and confirm:
"Can you see the preview rendering correctly at
<url>— every state visible, no blank page and no error overlay?"
That loop repeats until you confirm you can see it. Only then does Gate A's approval question get asked, as a separate question — can you see it first, do you approve it second, never merged into one. A design approval given over a preview that never rendered isn't accepted as Gate A approval.
What this rules out: silently retrying a failing command and showing you
only the run that worked, handing over a localhost URL nobody checked,
reporting a partial success as success, or substituting a description of
the intended UI for a preview that didn't come up. The most common cause of
a blank preview — two React copies across the preview/PCF boundary,
producing React error #321 — is now prevented by the generated preview
config and diagnosed by
troubleshooting.md § T28
when it still shows up.
development-classified deployments never require a confirmation step
— not a readiness report, not a typed string, not even on the first
deployment to a brand-new environment. Immediately before running, the
skill shows a one-line heads-up (operation, environment, version) and
runs the command; the full result — including any errors — is reported
afterward. This is true for every push/import to a development target,
first one or the hundredth, same conversation or a new one days later.
What's still asked, and why it isn't a confirmation step: the first time a given environment is used for a project, its URL, and (depending on method) the publisher prefix, the managed/unmanaged choice, or the solution unique name and display name, are genuinely unknown — a wrong guess on any of these would be actively harmful, so they're asked once, as information-gathering. Names of durable artifacts are never invented, whatever the classification: the solution name ends up in the maker portal and in your repo. That's the only thing standing between "just deploy" and the command actually running for a brand-new dev target; once those values are known (from that one ask, or already on record from a prior deployment), nothing else is asked, ever, for that target.
This does not apply to:
test/UAT/staging/production — always the full confirmation flow,
every time, with no exceptions, first deployment or the hundredth.pac solution publish — always its own, separately confirmed operation,
for any classification including development, because it affects the
whole environment rather than this one control.The trade-off, stated plainly: environment classification is
something you tell the skill, not something it can verify against
Dataverse. If an environment is ever misclassified as development,
there is no remaining checkpoint before code reaches it — not even a
first-deployment review. If you'd rather keep the confirmation step for a
specific dev environment anyway, just say so ("always confirm before
deploying to this one") — the skill records that as a per-environment
override and goes back to asking every time for that target.
Automatic (above) is about whether you're asked. This is about which command runs — and the skill asks you one question to decide it:
Is this the first time this control is being deployed to
<url>, or does it already exist there inside a solution?
It shows you what the spec's deployment history suggests, but the answer is
yours — the spec only knows what previous sessions of this project did, not
what a colleague or a pipeline did. If you're not sure, it checks
pac solution list and tells you what's actually there.
pac solution init /
add-reference / dotnet build / pac solution import, unmanaged.
That first deployment is what creates the named, source-controlled
solution your control lives in from then on. The skill asks for the
solution's unique name and display name before creating anything, and
corrects Solution.xml to a four-segment 1.0.0.0 before building —
pac solution init scaffolds a two-segment 1.0, which Dataverse would
otherwise ship verbatim.pac pcf push — the fast inner
loop, updating the control inside the solution that already exists. No
names to ask for, nothing new to create.Why not pac pcf push from the start? It wraps the control in a throwaway
PowerAppsToolsTemp_<prefix> solution, so the solution you actually want
never gets created — and building that temp wrapper is the step that fails
with error MSB3231 ... being used by another process on machines with
real-time antivirus scanning, deterministically rather than occasionally.
The skill recognizes that error, doesn't burn retries on it, and doesn't
touch your antivirus configuration.
pac pcf push always is).
Choose managed for a dev import and the bump applies there too. If a
change doesn't show up after an unmanaged deployment, that's a
hard-refresh (Ctrl+F5), not a version bump.1.0.0.0 when the
solution is created and left there unless you ask for something else.Picking managed for a dev environment is your call; the skill takes the answer and mentions once that the bump now applies and that managed components can't be edited in that environment (and can't be converted back to unmanaged). Then it proceeds — dev still has no confirmation gate.
One thing worth knowing: push rebuilds that temp wrapper on every
run, so the control already being deployed doesn't help. If push has failed
this way on your machine once, it will keep failing until you exclude the
project's obj and bin folders from real-time scanning. The skill records
that it's blocked and stops offering push until a push actually succeeds —
it'll use the package method (rebuild + re-import the solution you already
have) in the meantime rather than walking you into the same wall.
pac CLI errors using evidence (command output) rather than guesses.test/UAT/staging/production,
or automatically for development — see
Automatic deployment to development environments.development,
which deploys automatically without asking — including the first
deployment to a brand-new dev environment — see
Automatic deployment to development environments.
pac solution publish is never automatic, for any environment,
including development.scripts/) only inspect and validate — they never install software or
write to a Dataverse environment.plugin.json — portable Agent Plugins 1.0 manifest (VS Code agent plugins, Codex)
.claude-plugin/
plugin.json — Claude Code plugin manifest
marketplace.json — self-hosted Claude Code marketplace listing (this repo is both)
.codex-plugin/
plugin.json — Codex overlay: interface/display metadata (same skill, same version)
.agents/plugins/
marketplace.json — self-hosted Codex marketplace listing
skills/pcf-control-builder/
SKILL.md — the skill's core workflow, gates, and routing table
references/ — detailed per-topic guidance, loaded on demand
templates/ — the control-spec, manifest-proposal, and deployment-readiness templates
examples/ — worked transcripts
scripts/ — read-only PowerShell inspection/validation scripts
See CHANGELOG.md for what changed in each version.
Issues and pull requests are welcome — see CONTRIBUTING.md.
Released under the MIT License.