Skip to content
Merged
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
1 change: 0 additions & 1 deletion .claude-plugin/marketplace.json

This file was deleted.

132 changes: 132 additions & 0 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
{
"name": "power-platform-skills",
"owner": {
"name": "Microsoft"
},
"metadata": {
"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",
"version": "2.4.0",
"license": "MIT",
"tags": [
"power platform",
"power pages",
"microsoft power platform",
"microsoft"
],
"keywords": [
"power platform",
"power pages",
"microsoft power platform",
"microsoft"
]
},
{
"name": "model-apps",
"source": "./plugins/model-apps",
"description": "Build and deploy generative pages for Power Apps model-driven apps",
"category": "development",
"version": "2.2.0",
"license": "MIT",
"tags": [
"power platform",
"power apps",
"model-driven apps",
"generative pages",
"genux",
"microsoft"
],
"keywords": [
"power platform",
"power apps",
"model-driven apps",
"generative pages",
"genux",
"microsoft"
]
},
{
"name": "mcp-apps",
"source": "./plugins/mcp-apps",
"description": "Generate MCP App widgets for MCP tools",
"category": "development",
"version": "1.0.0",
"license": "MIT",
"tags": [
"mcp",
"mcp-apps",
"widget",
"power platform",
"microsoft"
],
"keywords": [
"mcp",
"mcp-apps",
"widget",
"power platform",
"microsoft"
]
},
{
"name": "canvas-apps",
"source": "./plugins/canvas-apps",
"description": "Build Power Apps Canvas Apps using the Canvas Authoring MCP server",
"category": "development",
"version": "2.1.0",
"license": "MIT",
"tags": [
"power platform",
"power apps",
"canvas apps",
"pa-yaml",
"msapp",
"connectors",
"microsoft"
],
"keywords": [
"power platform",
"power apps",
"canvas apps",
"pa-yaml",
"msapp",
"connectors",
"microsoft"
]
},
{
"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",
"version": "1.0.0",
"license": "MIT",
"tags": [
"power platform",
"power apps",
"code apps",
"react",
"vite",
"dataverse",
"connectors",
"microsoft"
],
"keywords": [
"power platform",
"power apps",
"code apps",
"react",
"vite",
"dataverse",
"connectors",
"microsoft"
]
}
]
}
19 changes: 10 additions & 9 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ A **plugin marketplace** for Power Platform development by Microsoft. The Open P
```
power-platform-skills/
├── marketplace.json # Open Plugins marketplace manifest (lists all available plugins)
├── .claude-plugin/ # Legacy symlinks for existing subscriptions
├── .claude-plugin/ # Legacy manifest mirrors for existing subscriptions
│ └── marketplace.json
├── plugins/ # Directory containing individual plugins
│ └── <plugin-name>/ # Individual plugin (e.g., power-pages)
Expand Down Expand Up @@ -46,7 +46,7 @@ No root-level build, lint, or test commands exist. Build/test tooling lives insi
Each plugin follows this structure:

- `.plugin/plugin.json` — Open Plugins metadata (name, version, keywords)
- `.claude-plugin/plugin.json` — legacy symlink to `.plugin/plugin.json` kept for existing subscriptions
- `.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 Down Expand Up @@ -96,13 +96,14 @@ Current adopters: `power-pages`. Others adopt on demand.

## Legacy Marketplace Compatibility

Keep the root `.claude-plugin/marketplace.json` as a symlink to
`../marketplace.json`, and keep each plugin's `.claude-plugin/plugin.json` as a
symlink to `../.plugin/plugin.json`. The shared root marketplace must stay
dual-compatible: use repository-root-relative plugin `source` paths and preserve
legacy `category`/`tags` fields alongside Open Plugins metadata. Existing
marketplace subscriptions may still resolve the legacy paths during auto-update,
so removing or drifting these files can force users to reinstall. Run
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: use repository-root-relative
plugin `source` paths and preserve legacy `category`/`tags` fields alongside Open
Plugins metadata. 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 (not symlinks), update both source
and legacy copies together, then run
`node scripts/validate-legacy-compatibility.js` after metadata changes.

## Code Conventions
Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,12 +205,12 @@ power-platform-skills/
└── README.md
```

The `.claude-plugin` files are compatibility symlinks for users who subscribed
before the Open Plugins migration. The root legacy marketplace points to
`../marketplace.json`, and per-plugin legacy manifests point to
`../.plugin/plugin.json`. The shared marketplace uses repository-root-relative
plugin `source` paths so existing subscriptions can auto-update without
requiring users to remove and reinstall the marketplace or plugins.
The `.claude-plugin` files are compatibility mirrors for users who subscribed
before the Open Plugins migration. The root legacy marketplace mirrors
`marketplace.json`, and per-plugin legacy manifests mirror `.plugin/plugin.json`.
The shared marketplace uses repository-root-relative plugin `source` paths so
existing subscriptions can auto-update without requiring users to remove and
reinstall the marketplace or plugins.

## Documentation

Expand Down
1 change: 0 additions & 1 deletion plugins/canvas-apps/.claude-plugin/plugin.json

This file was deleted.

19 changes: 19 additions & 0 deletions plugins/canvas-apps/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "canvas-apps",
"version": "2.1.0",
"description": "Build Power Apps Canvas Apps using the Canvas Authoring MCP server.",
"author": {
"name": "Microsoft",
"url": "https://www.microsoft.com"
},
"homepage": "https://github.com/microsoft/power-platform-skills/",
"repository": "https://github.com/microsoft/power-platform-skills/",
"license": "MIT",
"keywords": [
"canvas-apps",
"power-apps",
"canvas",
"pa-yaml",
"msapp"
]
}
1 change: 0 additions & 1 deletion plugins/code-apps/.claude-plugin/plugin.json

This file was deleted.

22 changes: 22 additions & 0 deletions plugins/code-apps/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "code-apps-preview",
"version": "1.0.0",
"description": "Build and deploy Power Apps code apps using React, Vite, and Power Platform connectors.",
"author": {
"name": "Microsoft",
"url": "https://www.microsoft.com"
},
"homepage": "https://github.com/microsoft/power-platform-skills/",
"repository": "https://github.com/microsoft/power-platform-skills/",
"license": "MIT",
"keywords": [
"power-apps",
"code-apps",
"react",
"vite",
"dataverse",
"connectors",
"pac-cli",
"power-platform"
]
}
1 change: 0 additions & 1 deletion plugins/mcp-apps/.claude-plugin/plugin.json

This file was deleted.

21 changes: 21 additions & 0 deletions plugins/mcp-apps/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "mcp-apps",
"version": "1.0.0",
"description": "Generate MCP App widgets for MCP tools. Produces self-contained HTML widgets using the MCP Apps protocol.",
"author": {
"name": "Microsoft",
"url": "https://www.microsoft.com"
},
"homepage": "https://github.com/microsoft/power-platform-skills/",
"repository": "https://github.com/microsoft/power-platform-skills/",
"license": "MIT",
"keywords": [
"mcp-apps",
"mcp",
"widget",
"ext-apps",
"fluent-ui",
"html",
"tool-visualization"
]
}
1 change: 0 additions & 1 deletion plugins/model-apps/.claude-plugin/plugin.json

This file was deleted.

23 changes: 23 additions & 0 deletions plugins/model-apps/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "model-apps",
"version": "2.2.0",
"description": "Build and deploy Power Apps generative pages for model-driven apps with specialist agents for planning, entity creation, and parallel code generation. Requires PAC CLI >= 2.7.0 and Azure CLI (`az`). See CHANGELOG.md for v1.x -> v2.x migration.",
"author": {
"name": "Microsoft",
"url": "https://www.microsoft.com"
},
"homepage": "https://github.com/microsoft/power-platform-skills/",
"repository": "https://github.com/microsoft/power-platform-skills/",
"license": "MIT",
"keywords": [
"model-apps",
"generative-pages",
"genux",
"genpage",
"react",
"fluent-ui",
"dataverse",
"pac-cli",
"model-driven"
]
}
1 change: 0 additions & 1 deletion plugins/power-pages/.claude-plugin/plugin.json

This file was deleted.

39 changes: 39 additions & 0 deletions plugins/power-pages/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"name": "power-pages",
"version": "2.4.0",
"description": "Create and deploy Power Pages sites using modern development approaches. Supports code sites (SPAs) with React, Angular, Vue, or Astro. Includes ALM orchestration (plan-alm) with a solution-splitting decision tree, per-solution pipelines, Azure Blob asset advisory, manifest schema v2 for multi-solution deployments, and force-link remediation for cross-host pipeline migrations.",
"author": {
"name": "Microsoft",
"url": "https://www.microsoft.com"
},
"homepage": "https://github.com/microsoft/power-platform-skills/",
"repository": "https://github.com/microsoft/power-platform-skills/",
"license": "MIT",
"keywords": [
"power-pages",
"site-builder",
"code-sites",
"spa",
"react",
"angular",
"vue",
"astro",
"pac-cli",
"dataverse",
"odata",
"web-api",
"tables",
"schema",
"solution",
"alm",
"plan-alm",
"ci-cd",
"pipeline",
"pipelines-host",
"force-link",
"diagnostics",
"shared-lib",
"solution-splitting",
"asset-advisory"
]
}
22 changes: 9 additions & 13 deletions scripts/validate-legacy-compatibility.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
#!/usr/bin/env node

/**
* Validates that legacy .claude-plugin manifests symlink to the Open Plugins
* metadata. These symlinks allow existing marketplace subscriptions to
* auto-update without requiring users to remove and reinstall the marketplace.
* Validates that legacy .claude-plugin manifests mirror the Open Plugins
* metadata. Existing marketplace subscriptions still resolve the legacy paths
* during auto-update, so these files must stay in sync. Mirrors are committed
* files (not links), so this guard must pass whenever marketplace/plugin
* metadata changes.
*/

const fs = require('fs');
Expand Down Expand Up @@ -31,13 +33,8 @@ function expectedLegacySource(pluginDirectory) {
return `./${normalizeRelative(path.relative(ROOT, pluginDirectory))}`;
}

function assertSymlinkTarget(linkPath, expectedTarget) {
const stat = fs.lstatSync(linkPath);
assert.ok(stat.isSymbolicLink(), 'legacy plugin manifest must be a symlink');
assert.equal(
normalizeRelative(fs.readlinkSync(linkPath)),
normalizeRelative(expectedTarget)
);
function assertJsonMirror(legacyPath, sourcePath) {
assert.deepEqual(readJson(legacyPath), readJson(sourcePath));
}
Comment on lines +36 to 38

const errors = [];
Expand All @@ -52,7 +49,7 @@ function check(label, fn) {

check('legacy marketplace manifest', () => {
assert.ok(fs.existsSync(LEGACY_MARKETPLACE_PATH), 'missing .claude-plugin/marketplace.json');
assertSymlinkTarget(LEGACY_MARKETPLACE_PATH, path.join('..', 'marketplace.json'));
assertJsonMirror(LEGACY_MARKETPLACE_PATH, OPEN_MARKETPLACE_PATH);
});

if (errors.length === 0) {
Expand Down Expand Up @@ -88,8 +85,7 @@ if (errors.length === 0) {

check(relativeLegacyManifestPath, () => {
assert.ok(fs.existsSync(legacyManifestPath), 'missing legacy plugin manifest');
assertSymlinkTarget(legacyManifestPath, path.join('..', '.plugin', 'plugin.json'));
assert.deepEqual(readJson(legacyManifestPath), readJson(openManifestPath));
assertJsonMirror(legacyManifestPath, openManifestPath);
});
}

Expand Down