Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
110 changes: 5 additions & 105 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,123 +10,23 @@
"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.6.0",
"license": "MIT",
"tags": [
"power platform",
"power pages",
"microsoft power platform",
"microsoft"
],
"keywords": [
"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",
"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"
]
"source": "./plugins/model-apps"
},
{
"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"
]
"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",
"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"
]
"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",
"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"
]
"source": "./plugins/code-apps"
}
]
}
23 changes: 13 additions & 10 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,15 @@ Skills that apply to all plugins live in `shared/skills/<skill-name>/`. The work
- `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` — Symlink to the shared workflow when the plugin must work after installing only its own plugin directory
- `plugins/<plugin>/skills/<skill-name>/<workflow>.md` — Copied workflow file bundled with the plugin so it works after installing only its own plugin directory

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 symlink from that per-plugin path to the repo-root shared workflow; marketplace installers dereference same-marketplace symlinks into the installed plugin cache. When updating a shared skill, edit the workflow file and/or `SKILL.template.md` in `shared/`, then update the per-plugin wrappers (frontmatter + bundled workflow reference, with `{{PLUGIN_NAME}}` substituted) and ensure any per-plugin symlinks still resolve under `plugins/<plugin>/skills/<skill-name>/`. Commit the shared source and per-plugin symlinks together.
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.

## Shared Telemetry

1DS telemetry code for all plugins lives at `shared/telemetry/`. Each adopting plugin **symlinks** the library into its own tree `plugins/<plugin>/scripts/lib/telemetry/lib` is a symlink to `shared/telemetry/lib`. The marketplace installer dereferences that symlink into the installed plugin at install time, so the shared code ships without copying it into each plugin. Each plugin keeps its own real `ikey.json` next to the symlink.
1DS telemetry code for all plugins lives at `shared/telemetry/`. Each adopting plugin keeps a physical copy of the library in its own tree at `plugins/<plugin>/scripts/lib/telemetry/lib`, alongside that plugin's real `ikey.json`. Do not use Git symlinks for this copy; plugin hosts may not dereference them reliably.

Edit `shared/telemetry/` directly — the symlink makes changes live for every adopting plugin immediately; there is nothing to re-sync.
Edit `shared/telemetry/` first, then refresh every adopting plugin's copied `scripts/lib/telemetry/lib` directory in the same change so the canonical source and bundled plugin content stay in sync.

Per-plugin iKey/collector routing is pluggable via a `resolver.js` placed next to the plugin's `ikey.json` (implementing the `resolve`/`isProvisioned` contract); the shared library ships only that contract plus a static-key fallback, not any routing logic. A per-plugin opt-out env var `POWER_PLATFORM_SKILLS_TELEMETRY_<PLUGIN>_OPTOUT` (derived as the uppercased plugin name with non-alphanumerics collapsed to `_`, suffixed `_OPTOUT`) disables transmission for automation when set to `1`/`true` (dotnet `*_TELEMETRY_OPTOUT` convention); it has the **highest precedence**, overriding both the persisted `config.json` choice and `/<plugin>:telemetry on`.

Expand All @@ -98,12 +98,15 @@ Current adopters: `power-pages`. Others adopt on demand.

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
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, etc.) 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 (not symlinks), update both source and legacy copies together, then run
`node scripts/validate-legacy-compatibility.js` after metadata changes.

## Code Conventions
Expand Down
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,9 +208,11 @@ power-platform-skills/
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.
The shared marketplace keeps marketplace-level `owner` and `metadata`, while each
plugin entry is intentionally just `name` plus repository-root-relative `source`.
Plugin descriptions, versions, licenses, and keywords are controlled from each
plugin's `.plugin/plugin.json`. This keeps existing subscriptions updating without
duplicating display/update metadata.

## Documentation

Expand Down
110 changes: 5 additions & 105 deletions marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,123 +10,23 @@
"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.6.0",
"license": "MIT",
"tags": [
"power platform",
"power pages",
"microsoft power platform",
"microsoft"
],
"keywords": [
"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",
"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"
]
"source": "./plugins/model-apps"
},
{
"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"
]
"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",
"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"
]
"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",
"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"
]
"source": "./plugins/code-apps"
}
]
}

This file was deleted.

Loading
Loading