Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 7 additions & 56 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,78 +4,29 @@
"name": "Microsoft"
},
"metadata": {
"description": "Plugins for Power Platform development with Claude Code and GitHub Copilot"
"description": "Plugins for Power Platform development with Claude Code and GitHub Copilot",
"pluginRoot": "."
},
"plugins": [
{
"name": "power-pages",
"source": "./plugins/power-pages",
"description": "Power Pages development and management plugin for Claude Code and GitHub Copilot",
"category": "development",
"tags": [
"power platform",
"power pages",
"microsoft power platform",
"microsoft"
]
"source": "./plugins/power-pages"
},
{
"name": "model-apps",
"source": "./plugins/model-apps",
"description": "Build and deploy generative pages for Power Apps model-driven apps",
"category": "development",
"tags": [
"power platform",
"power apps",
"model-driven apps",
"generative pages",
"genux",
"microsoft"
]
"source": "./plugins/model-apps"
},
{
"name": "mcp-apps",
"source": "./plugins/mcp-apps",
"description": "Generate MCP App widgets for MCP tools",
"category": "development",
"tags": [
"mcp",
"mcp-apps",
"widget",
"power platform",
"microsoft"
]
"source": "./plugins/mcp-apps"
},
{
"name": "canvas-apps",
"source": "./plugins/canvas-apps",
"description": "Build Power Apps Canvas Apps using the Canvas Authoring MCP server",
"category": "development",
"tags": [
"power platform",
"power apps",
"canvas apps",
"pa-yaml",
"msapp",
"connectors",
"microsoft"
]
"source": "./plugins/canvas-apps"
},
{
"name": "code-apps-preview",
"source": "./plugins/code-apps",
"description": "Build and deploy Power Apps code apps using React, Vite, and Power Platform connectors",
"category": "development",
"tags": [
"power platform",
"power apps",
"code apps",
"react",
"vite",
"dataverse",
"connectors",
"microsoft"
]
"source": "./plugins/code-apps"
}
]
}
4 changes: 1 addition & 3 deletions .claude/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@
"Bash(dir:*)",
"Read",
"Write",
"Edit",
"mcp__playwright__*",
"mcp__*__browser_*"
"Edit"
]
}
}
12 changes: 12 additions & 0 deletions .github/workflows/power-pages-alm-lint.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# Deliberately separate from `power-pages-script-tests.yml`.
# This workflow runs policy enforcement (gate markers, ALM-aware-by-default,
# discovery coverage) — pure-Node, OS-independent, completes in seconds, so
# it runs on a single OS to surface red checks fast.
# The sibling workflow runs functional unit tests across ubuntu × windows × macos.
# See PLUGIN_DEVELOPMENT_GUIDE.md and references/approval-gates.md.
name: power-pages-alm-lint

on:
Expand All @@ -11,6 +17,12 @@ jobs:
alm-lint:
name: alm-lint
runs-on: ubuntu-latest
# Consistency backstop: keep all power-pages CI opted out of telemetry
# transmission. This job runs only the linter today (no emission), so the
# var is inert here — it guarantees no transmission if an emitting step is
# ever added to this workflow.
env:
POWER_PLATFORM_SKILLS_TELEMETRY_POWER_PAGES_OPTOUT: "1"
steps:
- name: checkout
uses: actions/checkout@v4
Expand Down
13 changes: 13 additions & 0 deletions .github/workflows/power-pages-script-tests.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# Deliberately separate from `power-pages-alm-lint.yml`.
# This workflow runs functional unit tests across ubuntu × windows × macos to
# catch OS-specific regressions in Node scripts. Slow (~30s on macOS).
# The sibling workflow runs fast policy enforcement on a single OS so red
# checks for gate-marker / catalog drift surface before this matrix finishes.
name: power-pages-script-tests

on:
Expand All @@ -11,6 +16,14 @@ jobs:
test-power-pages-scripts:
name: test-power-pages-scripts (${{ matrix.os }})
runs-on: ${{ matrix.os }}
# Defense-in-depth: opt this CI job out of telemetry transmission so even
# a test that forgets to isolate emission (no FAKE_HTTPS probe / temp
# ikey) can never POST to the production collector. Honored end-to-end
# because emit-spawn forwards this var to the detached dispatcher. The two
# positive-emission tests clear it in their own spawn env so they still
# exercise the real emit path.
env:
POWER_PLATFORM_SKILLS_TELEMETRY_POWER_PAGES_OPTOUT: "1"
strategy:
fail-fast: false
matrix:
Expand Down
7 changes: 5 additions & 2 deletions .github/workflows/validate-repository-metadata.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ on:
workflow_dispatch:

permissions:
contents: read
contents: read

jobs:
validate-repository-metadata:
Expand All @@ -22,8 +22,11 @@ jobs:
with:
node-version: 20

- name: validate-kebab-case-plugin-names
- name: validate-open-plugin-names
run: node scripts/validate-plugin-names.js

- name: validate-legacy-compatibility
run: node scripts/validate-legacy-compatibility.js

- name: validate-skill-descriptions
run: node scripts/validate-skill-descriptions.js
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,6 @@ Thumbs.db

.playwright-mcp/

# oh-my-claudecode scratch state
.omc/

36 changes: 28 additions & 8 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,21 @@ This file provides guidance to AI Agents when working with code in this reposito

## What This Repo Is

A **plugin marketplace** for Power Platform development by Microsoft. The marketplace manifest (`.claude-plugin/marketplace.json`) references individual plugins in `plugins/`. Each plugin has its own `AGENTS.md` with plugin-specific guidance.
A **plugin marketplace** for Power Platform development by Microsoft. The Open Plugins marketplace manifest (`marketplace.json`) references individual plugins in `plugins/`. Legacy `.claude-plugin` manifest mirrors are kept for existing subscriptions. Each plugin has its own `AGENTS.md` with plugin-specific guidance.

## Repository Structure

```text
```
power-platform-skills/
├── .claude-plugin/
│ └── marketplace.json # Marketplace manifest (lists all available plugins)
├── marketplace.json # Open Plugins marketplace manifest (lists all available plugins)
├── .claude-plugin/ # Legacy manifest mirrors for existing subscriptions
│ └── marketplace.json
├── plugins/ # Directory containing individual plugins
│ └── <plugin-name>/ # Individual plugin (e.g., power-pages)
│ ├── .plugin/
│ │ └── plugin.json # Open Plugins manifest
│ ├── .claude-plugin/
│ │ └── plugin.json # Plugin manifest
│ │ └── plugin.json # Legacy manifest mirror
│ ├── AGENTS.md # Plugin-specific development guidelines
│ ├── agents/ # Agent persona files
│ ├── commands/ # Command entry points
Expand All @@ -42,7 +45,8 @@ No root-level build, lint, or test commands exist. Build/test tooling lives insi

Each plugin follows this structure:

- `.claude-plugin/plugin.json` — Plugin metadata (name, version, keywords)
- `.plugin/plugin.json` — Open Plugins metadata (name, version, keywords)
- `.claude-plugin/plugin.json` — legacy mirror of `.plugin/plugin.json` kept for existing subscriptions
- `.mcp.json` — MCP server configuration (optional)
- `agents/` — Agent definitions (`.md` files with YAML frontmatter)
- `skills/` — Skill definitions, each in its own subdirectory with a `SKILL.md`
Expand All @@ -59,20 +63,36 @@ Do not mark a plugin as ready for internal publication until it has a completed

## Cross-Plugin Shared Skills

Skills that apply to all plugins live in `shared/skills/<skill-name>/`. The workflow logic is written once in a shared `.md` file, and each plugin has a thin `skills/<skill-name>/SKILL.md` that contains only the YAML frontmatter and a reference to the shared workflow file.
Skills that apply to all plugins live in `shared/skills/<skill-name>/`. The workflow logic is written once in a shared `.md` file, and each plugin has a thin `skills/<skill-name>/SKILL.md` that contains only the YAML frontmatter and a reference to the workflow path bundled inside that plugin at install time.

**Pattern:**

- `shared/skills/<skill-name>/<workflow>.md` — Full workflow (phases, instructions, field definitions)
- `shared/skills/<skill-name>/SKILL.template.md` — Template SKILL.md (frontmatter + reference to workflow); supports `{{PLUGIN_NAME}}` placeholder
- `plugins/<plugin>/skills/<skill-name>/SKILL.md` — Per-plugin wrapper generated from the template above
- `plugins/<plugin>/skills/<skill-name>/<workflow>.md` — Bundled workflow file copied into the plugin so installs work without repo-root shared paths

This keeps the skill discoverable in each plugin while preserving install-time portability. Marketplace installs copy only the plugin directory, so per-plugin wrappers must not reference repo-root `shared/` paths at runtime. Instead, point the wrapper at `${PLUGIN_ROOT}/skills/<skill-name>/<workflow>.md` and keep a physical copy of the shared workflow at that per-plugin path. Do not use Git symlinks for shared content; Windows and plugin-host installs can materialize them as plain link files. When updating a shared skill, edit the workflow file and/or `SKILL.template.md` in `shared/`, then refresh the per-plugin wrappers (frontmatter + bundled workflow reference, with `{{PLUGIN_NAME}}` substituted) and copy the workflow content into each adopting plugin. Commit the shared source and per-plugin copies together.

## Legacy Marketplace Compatibility

This keeps the skill discoverable in each plugin while avoiding content duplication. When updating a shared skill, edit the workflow file and/or `SKILL.template.md` in `shared/`, then update the per-plugin wrappers (frontmatter + reference pointing to the shared workflow, with `{{PLUGIN_NAME}}` substituted) and commit them alongside the shared change.
Keep the root `.claude-plugin/marketplace.json` and each plugin's `.claude-plugin/plugin.json` as JSON mirrors of their Open Plugins counterparts. The shared root marketplace must stay dual-compatible while keeping per-plugin entries minimal: each plugin entry should include only the required `name` and repository-root-relative `source` fields. Keep marketplace-level `owner` and `metadata` because they describe the collection, but store per-plugin display/update metadata (description, version, license, keywords, and similar fields) in each `.plugin/plugin.json` instead of duplicating or overriding it in the marketplace index. Existing marketplace subscriptions may still resolve the legacy paths during auto-update, so removing or drifting these files can force users to reinstall. Because mirrors are committed files, update both source and legacy copies together, then run `node scripts/validate-legacy-compatibility.js` after metadata changes.

## Code Conventions

**DRY (Don't Repeat Yourself):** Never duplicate logic across files. Each plugin has shared utilities (e.g., `scripts/lib/`) and shared reference docs (e.g., `references/`). Always check for and reuse existing helpers before writing new code. When adding shared logic, put it in the plugin's shared modules — not in individual skill directories.

### Code comments

Most code in this repo is Node.js scripts and hooks that shell out to `pac`/`az`, call the Dataverse and Power Platform APIs, and parse loosely structured CLI output. The reasoning behind a line is rarely obvious from the line alone, so comments matter.

- Err on the side of over-commenting when the reasoning is not obvious. Comments should explain **why** code is written a particular way.
- Comment non-obvious implementation details: concurrency hazards, lifecycle constraints, compatibility requirements, platform quirks, upstream PAC CLI or Dataverse workarounds, and intentional deviations from the obvious helper or API.
- When parsing strings, logs, CLI output, OData payloads, or other loosely structured data, include a comment with an example of the raw format being parsed.
- When code follows an external standard, protocol, or Power Platform convention, include links to the relevant documentation so future readers can verify the rule.
- When code touches auth tokens or other privacy/security-sensitive flows, explain the scope and fail-closed behavior.
- Do not add comments that only narrate clear code.

## Maintaining This File

When you add new plugins or change the repository-level structure, update this file. For plugin-specific changes, update the plugin's own `AGENTS.md` (e.g., `plugins/power-pages/AGENTS.md`).
Expand Down
1 change: 1 addition & 0 deletions CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* @microsoft/power-platform-skills-contributors
10 changes: 10 additions & 0 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Microsoft Open Source Code of Conduct

This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).

Resources:

- [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/)
- [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
- Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns
- Employees can reach out at [aka.ms/opensource/moderation-support](https://aka.ms/opensource/moderation-support)
Loading
Loading