From ca4f5f89a0780e1b93c72d75c124a4bd7d90df36 Mon Sep 17 00:00:00 2001 From: Aaron Powell Date: Thu, 30 Jul 2026 10:56:55 +1000 Subject: [PATCH 1/8] feat: migrate plugins and extensions to Agent Plugins v1.0.0 spec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add \ to all 69 curated plugin manifests - Migrate all 18 extension manifests: add \, move logo into xtensions.com.github.copilot.logo namespace, remove top-level logo and string xtensions: '.' - Update eng/validate-plugins.mjs: require \, validate namespace-keyed extensions object for canvas extensions, widen name pattern to allow dots (spec ยง5.5, max 64 chars) - Update eng/materialize-plugins.mjs: emit spec-clean served manifests (only spec fields: \, name, version, description, author, homepage, repository, license, keywords, extensions) - Update eng/generate-website-data.mjs: read logo from namespace with fallback to top-level logo for compatibility - Update eng/create-plugin.mjs: scaffold emits \ - Add .github/workflows/validate-plugins.yml: blocking CI for PRs touching plugins/** or extensions/** - Add spec compliance check to external plugin quality gates: non-blocking warnings with โœ…/โš ๏ธ/๐Ÿ›‘ emoji legend - Update AGENTS.md: document new extension manifest shape, add \ to plugin checklist Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8f3a88cb-e01e-4760-8125-460490dc1a76 --- .github/plugin/marketplace.json | 6 + .../external-plugin-command-router.yml | 6 +- .github/workflows/external-plugin-intake.yml | 6 +- .../external-plugin-pr-quality-gates.yml | 47 +++++-- .github/workflows/validate-plugins.yml | 65 +++++++++ AGENTS.md | 29 +++- eng/create-plugin.mjs | 1 + eng/external-plugin-intake.mjs | 58 ++++++-- eng/external-plugin-pr-quality-gates.mjs | 2 +- eng/external-plugin-quality-gates.mjs | 132 ++++++++++++++++++ eng/generate-website-data.mjs | 6 +- eng/materialize-plugins.mjs | 40 ++---- eng/validate-plugins.mjs | 63 +++++++-- .../.github/plugin/plugin.json | 8 +- .../apng-studio/.github/plugin/plugin.json | 8 +- .../arcade-canvas/.github/plugin/plugin.json | 8 +- .../.github/plugin/plugin.json | 8 +- .../.github/plugin/plugin.json | 8 +- .../color-orb/.github/plugin/plugin.json | 8 +- .../.github/plugin/plugin.json | 8 +- .../diagram-viewer/.github/plugin/plugin.json | 8 +- .../.github/plugin/plugin.json | 8 +- .../gesture-review/.github/plugin/plugin.json | 8 +- .../.github/plugin/plugin.json | 8 +- .../.github/plugin/plugin.json | 8 +- .../.github/plugin/plugin.json | 8 +- .../site-studio/.github/plugin/plugin.json | 8 +- .../.github/plugin/plugin.json | 8 +- .../token-pacman/.github/plugin/plugin.json | 8 +- .../where-was-i/.github/plugin/plugin.json | 8 +- .../work-hub/.github/plugin/plugin.json | 8 +- .../.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + plugins/arch/.github/plugin/plugin.json | 1 + plugins/arize-ax/.github/plugin/plugin.json | 1 + .../automate-this/.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../cast-imaging/.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../context-matic/.github/plugin/plugin.json | 1 + .../convert-to-md/.github/plugin/plugin.json | 1 + .../copilot-sdk/.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../devops-oncall/.github/plugin/plugin.json | 1 + .../doublecheck/.github/plugin/plugin.json | 1 + .../edge-ai-tasks/.github/plugin/plugin.json | 1 + plugins/ember/.github/plugin/plugin.json | 1 + plugins/eyeball/.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + plugins/gem-team/.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + plugins/napkin/.github/plugin/plugin.json | 1 + plugins/noob-mode/.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + plugins/partners/.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + plugins/phoenix/.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + plugins/roundup/.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + .../.github/plugin/plugin.json | 1 + plugins/visual-pr/.github/plugin/plugin.json | 1 + 100 files changed, 564 insertions(+), 110 deletions(-) create mode 100644 .github/workflows/validate-plugins.yml diff --git a/.github/plugin/marketplace.json b/.github/plugin/marketplace.json index e91a76073e..eebc5b160f 100644 --- a/.github/plugin/marketplace.json +++ b/.github/plugin/marketplace.json @@ -241,6 +241,12 @@ "description": "A visual orb that users can ask the agent to recolor while showing a live activity log in the canvas.", "version": "1.0.0" }, + { + "name": "connector-namespaces", + "source": "extensions/connector-namespaces", + "description": "Browse, connect, and open MCP connectors from an Azure Connector Namespace.", + "version": "1.1.0" + }, { "name": "context-engineering", "source": "plugins/context-engineering", diff --git a/.github/workflows/external-plugin-command-router.yml b/.github/workflows/external-plugin-command-router.yml index 78c75259d7..e54ddad85b 100644 --- a/.github/workflows/external-plugin-command-router.yml +++ b/.github/workflows/external-plugin-command-router.yml @@ -746,7 +746,8 @@ jobs: if (process.env.QUALITY_JOB_RESULT === 'failure' || process.env.QUALITY_JOB_RESULT === 'cancelled') { qualityResult = { overall_status: 'infra_error', - skill_validator_status: 'infra_error', + spec_compliance_status: 'warning', + vally_lint_status: 'infra_error', smoke_status: 'infra_error', failure_class: 'infra', summary: 'Quality-gate workflow failed unexpectedly. Re-run intake to retry.', @@ -756,7 +757,8 @@ jobs: } else { qualityResult = { overall_status: 'infra_error', - skill_validator_status: 'infra_error', + spec_compliance_status: 'warning', + vally_lint_status: 'infra_error', smoke_status: 'infra_error', failure_class: 'infra', summary: 'Quality-gate workflow did not return results. Re-run intake to retry.', diff --git a/.github/workflows/external-plugin-intake.yml b/.github/workflows/external-plugin-intake.yml index 61834d0818..6c487b5551 100644 --- a/.github/workflows/external-plugin-intake.yml +++ b/.github/workflows/external-plugin-intake.yml @@ -113,7 +113,8 @@ jobs: if (process.env.QUALITY_JOB_RESULT === 'failure' || process.env.QUALITY_JOB_RESULT === 'cancelled') { qualityResult = { overall_status: 'infra_error', - skill_validator_status: 'infra_error', + spec_compliance_status: 'warning', + vally_lint_status: 'infra_error', smoke_status: 'infra_error', failure_class: 'infra', summary: 'Quality-gate workflow failed unexpectedly. Re-run intake to retry.', @@ -123,7 +124,8 @@ jobs: } else { qualityResult = { overall_status: 'infra_error', - skill_validator_status: 'infra_error', + spec_compliance_status: 'warning', + vally_lint_status: 'infra_error', smoke_status: 'infra_error', failure_class: 'infra', summary: 'Quality-gate workflow did not return results. Re-run intake to retry.', diff --git a/.github/workflows/external-plugin-pr-quality-gates.yml b/.github/workflows/external-plugin-pr-quality-gates.yml index 068886a9ac..4d781297a7 100644 --- a/.github/workflows/external-plugin-pr-quality-gates.yml +++ b/.github/workflows/external-plugin-pr-quality-gates.yml @@ -147,6 +147,7 @@ jobs: let qualityResult = { overall_status: 'not_run', + spec_compliance_status: 'not_run', failure_class: 'none', checked_plugins: [], summary: 'No changed external plugin entries were detected in this PR.', @@ -155,6 +156,7 @@ jobs: if (detectJobResult === 'failure' || detectJobResult === 'cancelled') { qualityResult = { overall_status: 'infra_error', + spec_compliance_status: 'not_run', failure_class: 'infra', checked_plugins: [], summary: 'External plugin PR change detection failed unexpectedly. Re-run this workflow.', @@ -163,6 +165,7 @@ jobs: if (qualityJobResult === 'failure' || qualityJobResult === 'cancelled') { qualityResult = { overall_status: 'infra_error', + spec_compliance_status: 'not_run', failure_class: 'infra', checked_plugins: [], summary: 'External plugin PR quality checks failed unexpectedly. Re-run this workflow.', @@ -172,6 +175,7 @@ jobs: } else { qualityResult = { overall_status: 'infra_error', + spec_compliance_status: 'not_run', failure_class: 'infra', checked_plugins: [], summary: 'External plugin PR quality checks did not return a result payload.', @@ -195,11 +199,29 @@ jobs: }); const checkedPlugins = Array.isArray(qualityResult.checked_plugins) ? qualityResult.checked_plugins : []; + const hasSpecWarnings = checkedPlugins.some((entry) => String(entry?.quality?.spec_compliance_status || '') === 'warning'); const header = qualityResult.failure_class === 'submitter_fixes' - ? '## โš ๏ธ External plugin PR checks require submitter fixes' - : qualityResult.overall_status === 'pass' || !shouldRun - ? '## โœ… External plugin PR checks passed' - : '## โš ๏ธ External plugin PR checks need maintainer follow-up'; + ? '## ๐Ÿ›‘ External plugin PR checks failed (submitter fixes required)' + : qualityResult.overall_status === 'infra_error' + ? '## ๐Ÿ›‘ External plugin PR checks failed (maintainer follow-up)' + : hasSpecWarnings + ? '## โš ๏ธ External plugin PR checks passed with spec warnings' + : qualityResult.overall_status === 'pass' || !shouldRun + ? '## โœ… External plugin PR checks passed' + : '## โš ๏ธ External plugin PR checks need maintainer follow-up'; + const formatStatus = (rawStatus, gateName) => { + const status = String(rawStatus || 'not_run'); + if (status === 'pass') { + return 'โœ… pass'; + } + if (status === 'warning' || (gateName === 'spec compliance' && status === 'fail')) { + return 'โš ๏ธ warning'; + } + if (status === 'fail' || status === 'infra_error') { + return '๐Ÿ›‘ fail'; + } + return 'โšช not_run'; + }; const MAX_GATE_OUTPUT_CHARS = 2000; const escapeHtml = (value) => String(value || '') @@ -242,21 +264,25 @@ jobs: const sourceUrl = String(entry?.source_tree_url || ''); const locator = String(entry?.source?.sha || entry?.source?.ref || 'repository'); const sourceCell = sourceUrl ? `[${locator}](${sourceUrl})` : locator; - return `| ${name} | ${quality.vally_lint_status || 'not_run'} | ${quality.smoke_status || 'not_run'} | ${quality.overall_status || 'not_run'} | ${sourceCell} |`; + return `| ${name} | ${formatStatus(quality.spec_compliance_status, 'spec compliance')} | ${formatStatus(quality.vally_lint_status, 'vally lint')} | ${formatStatus(quality.smoke_status, 'install smoke test')} | ${formatStatus(quality.overall_status, 'overall')} | ${sourceCell} |`; }) - : ['| _none_ | not_run | not_run | not_run | _n/a_ |']; + : ['| _none_ | โšช not_run | โšช not_run | โšช not_run | โšช not_run | _n/a_ |']; const failureDetails = checkedPlugins.flatMap((entry) => { const name = String(entry?.name || 'unknown'); const quality = entry?.quality || {}; + const shouldShowSpec = quality.spec_compliance_status === 'warning' || String(quality.spec_compliance_output || '').trim().length > 0; const shouldShowVally = quality.vally_lint_status === 'fail' || quality.vally_lint_status === 'infra_error' || String(quality.vally_lint_output || '').trim().length > 0; const shouldShowSmoke = quality.smoke_status === 'fail' || quality.smoke_status === 'infra_error' || String(quality.smoke_output || '').trim().length > 0; const details = []; + if (shouldShowSpec) { + details.push(formatGateOutput(name, 'spec compliance', formatStatus(quality.spec_compliance_status, 'spec compliance'), quality.spec_compliance_output)); + } if (shouldShowVally) { - details.push(formatGateOutput(name, 'vally lint', quality.vally_lint_status, quality.vally_lint_output)); + details.push(formatGateOutput(name, 'vally lint', formatStatus(quality.vally_lint_status, 'vally lint'), quality.vally_lint_output)); } if (shouldShowSmoke) { - details.push(formatGateOutput(name, 'install smoke test', quality.smoke_status, quality.smoke_output)); + details.push(formatGateOutput(name, 'install smoke test', formatStatus(quality.smoke_status, 'install smoke test'), quality.smoke_output)); } return details; }); @@ -267,11 +293,12 @@ jobs: '', `- **Changed entries detected:** ${changedCount}`, `- **Workflow state label:** \`${stateLabel}\``, + '- **Status legend:** โœ… pass ยท โš ๏ธ warning ยท ๐Ÿ›‘ fail', '', '### Per-plugin quality summary', '', - '| Plugin | vally lint | install smoke test | overall | source tree |', - '|---|---|---|---|---|', + '| Plugin | spec compliance (non-blocking) | vally lint | install smoke test | overall | source tree |', + '|---|---|---|---|---|---|', ...rows, '', ...(failureDetails.length > 0 diff --git a/.github/workflows/validate-plugins.yml b/.github/workflows/validate-plugins.yml new file mode 100644 index 0000000000..2b5c500ab6 --- /dev/null +++ b/.github/workflows/validate-plugins.yml @@ -0,0 +1,65 @@ +name: Validate Plugins and Extensions + +on: + pull_request: + branches: [main] + paths: + - "plugins/**" + - "extensions/**" + +permissions: + contents: read + pull-requests: write + +jobs: + validate: + name: Plugin & extension spec validation + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + + - name: Setup Node.js + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 + with: + node-version: "22" + cache: "npm" + + - name: Install dependencies + run: npm ci + + - name: Validate plugins and extensions + id: validate + run: npm run plugin:validate + + - name: Post failure summary on PR + if: failure() && steps.validate.outcome == 'failure' + uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0 + with: + script: | + const body = [ + '๐Ÿ›‘ **Plugin/extension validation failed**', + '', + 'One or more plugins or extensions in this PR do not pass spec validation.', + '', + 'All internal plugins and extensions must include:', + '- `"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json"` in `plugin.json`', + '- A valid `name`, `description`, and `version`', + '- For **extensions**: `extensions["com.github.copilot"].logo` set to `"assets/preview.png"`', + '', + 'Run `npm run plugin:validate` locally to see the full list of errors.', + ].join('\n'); + + const isFork = context.payload.pull_request.head.repo.fork; + if (!isFork) { + try { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body, + }); + } catch (error) { + core.warning(`Could not post PR comment: ${error.message}`); + } + } diff --git a/AGENTS.md b/AGENTS.md index 7eedca71a7..0609ccb354 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -86,12 +86,12 @@ All agent files (`*.agent.md`) and instruction files (`*.instructions.md`) must - Each extension folder must include `extension.mjs` - Extension metadata must live at `.github/plugin/plugin.json` -- Extension `plugin.json` **must** follow the convention: +- Extension `plugin.json` **must** follow the Agent Plugins v1.0.0 spec: + - `"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json"` (required) - `name`, `description`, `version` are required - - `logo` **must** be exactly `"assets/preview.png"` (enforced convention) - - `extensions` **must** be exactly `"."` (per [copilot-agent-runtime#9929](https://github.com/github/copilot-agent-runtime/pull/9929)) + - `extensions` **must** be the namespace object: `{ "com.github.copilot": { "logo": "assets/preview.png" } }` - Optional: `author`, `keywords` fields - - **Must not** include `x-awesome-copilot` field (use convention-based `assets/preview.png` only) + - **Must not** include top-level `logo` (moved into the namespace) or `extensions: "."` (replaced by namespace object) - Each extension must have `assets/preview.png` as the primary visual asset - Do not add `canvas.json`; website metadata is sourced from `.github/plugin/plugin.json` @@ -120,10 +120,11 @@ All agent files (`*.agent.md`) and instruction files (`*.instructions.md`) must #### Plugin Folders (plugins/\*) - Each plugin is a folder containing a `.github/plugin/plugin.json` file with metadata +- plugin.json **must** have `"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json"` (Agent Plugins v1.0.0) - plugin.json must have `name` field (matching the folder name) - plugin.json must have `description` field (describing the plugin's purpose) - plugin.json must have `version` field (semantic version, e.g., "1.0.0") -- Plugin content is defined declaratively in plugin.json using Claude Code spec fields (`agents`, `commands`, `skills`). Source files live in top-level directories and are materialized into plugins by CI. +- Plugin content is defined declaratively in plugin.json using source-only composition fields (`agents`, `commands`, `skills`). Source files live in top-level directories and are materialized into plugins by CI. These fields are stripped from the served manifest โ€” conventional directory discovery handles them in spec mode. - The `marketplace.json` file is automatically generated from all plugins during build - Plugins are discoverable and installable via GitHub Copilot CLI @@ -177,7 +178,20 @@ When adding a new agent, instruction, skill, hook, workflow, or plugin: **For Canvas Extensions:** 1. Create/update the extension in `extensions//` with `extension.mjs` -2. Add `.github/plugin/plugin.json` metadata (required: `name`, `description`, `version`, `logo: "assets/preview.png"`, `extensions: "."`; optional: `author`, `keywords`) +2. Add `.github/plugin/plugin.json` with spec-compliant metadata: + ```json + { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", + "name": "", + "description": "...", + "version": "1.0.0", + "extensions": { + "com.github.copilot": { + "logo": "assets/preview.png" + } + } + } + ``` 3. Ensure `assets/preview.png` exists as the primary visual asset 4. Run `npm run plugin:validate` to validate plugin and extension metadata 5. Run `npm run build` to regenerate website data and marketplace output @@ -312,6 +326,7 @@ For plugins (plugins/\*/): - [ ] Directory contains a `.github/plugin/plugin.json` file - [ ] Directory contains a `README.md` file +- [ ] `plugin.json` has `"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json"` - [ ] `plugin.json` has `name` field matching the directory name (lowercase with hyphens) - [ ] `plugin.json` has non-empty `description` field - [ ] `plugin.json` has `version` field (semantic version, e.g., "1.0.0") @@ -319,7 +334,7 @@ For plugins (plugins/\*/): - [ ] If `keywords` is present, it is an array of lowercase hyphenated strings - [ ] If `agents`, `commands`, or `skills` arrays are present, each entry is a valid relative path - [ ] The plugin does not reference non-existent files -- [ ] Run `npm run build` to verify marketplace.json is updated correctly +- [ ] Run `npm run plugin:validate` and `npm run build` to verify the plugin passes all checks ## Contributing diff --git a/eng/create-plugin.mjs b/eng/create-plugin.mjs index 69f5e378ec..ad7875f905 100755 --- a/eng/create-plugin.mjs +++ b/eng/create-plugin.mjs @@ -133,6 +133,7 @@ async function createPlugin() { // Generate plugin.json const pluginJson = { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", name: pluginId, description, version: "1.0.0", diff --git a/eng/external-plugin-intake.mjs b/eng/external-plugin-intake.mjs index b7ddd2d6d5..e8af69583b 100644 --- a/eng/external-plugin-intake.mjs +++ b/eng/external-plugin-intake.mjs @@ -423,10 +423,12 @@ export function parseMarkReadyForReviewCommand(body) { function normalizeQualityGateResult(rawResult) { const defaults = { overall_status: "not_run", + spec_compliance_status: "not_run", vally_lint_status: "not_run", smoke_status: "not_run", failure_class: "none", summary: "", + spec_compliance_output: "", vally_lint_output: "", smoke_output: "", }; @@ -442,6 +444,21 @@ function normalizeQualityGateResult(rawResult) { } function buildQualityGatesCommentSection(qualityResult) { + const formatStatus = (rawStatus, gate) => { + const status = String(rawStatus || "not_run"); + if (status === "pass") { + return "โœ… pass"; + } + if (status === "warning" || (gate === "spec" && status === "fail")) { + return "โš ๏ธ warning"; + } + if (status === "fail" || status === "infra_error") { + return "๐Ÿ›‘ fail"; + } + return "โšช not_run"; + }; + + const specState = qualityResult.spec_compliance_status || "not_run"; const vallyState = qualityResult.vally_lint_status || "not_run"; const smokeState = qualityResult.smoke_status || "not_run"; const summaryText = String(qualityResult.summary || "").trim() || "_No quality gate details were provided._"; @@ -449,20 +466,38 @@ function buildQualityGatesCommentSection(qualityResult) { const sections = [ "### Quality gate summary", "", + "_Legend: โœ… pass ยท โš ๏ธ warning ยท ๐Ÿ›‘ fail_", + "", "| Gate | Status |", "|---|---|", - `| vally lint | ${vallyState} |`, - `| install smoke test | ${smokeState} |`, + `| spec compliance (non-blocking) | ${formatStatus(specState, "spec")} |`, + `| vally lint | ${formatStatus(vallyState, "vally")} |`, + `| install smoke test | ${formatStatus(smokeState, "smoke")} |`, "", summaryText, ]; + const specOutput = String(qualityResult.spec_compliance_output || "").trim(); + if (specOutput) { + sections.push( + "", + "
", + `spec compliance output (${formatStatus(specState, "spec")})`, + "", + "```text", + specOutput, + "```", + "", + "
", + ); + } + const vallyOutput = String(qualityResult.vally_lint_output || "").trim(); if (vallyOutput) { sections.push( "", "
", - "vally lint output", + `vally lint output (${formatStatus(vallyState, "vally")})`, "", "```text", vallyOutput, @@ -477,7 +512,7 @@ function buildQualityGatesCommentSection(qualityResult) { sections.push( "", "
", - "Install smoke test output", + `install smoke test output (${formatStatus(smokeState, "smoke")})`, "", "```text", smokeOutput, @@ -515,19 +550,24 @@ function buildMergedIntakeComment(baseResult, qualityResult, runId, owner, repo) const qualitySection = buildQualityGatesCommentSection(qualityResult); const runLink = runId && owner && repo ? `_[View workflow run](https://github.com/${owner}/${repo}/actions/runs/${runId})_` : ""; + const hasSpecWarnings = String(qualityResult.spec_compliance_status || "") === "warning"; const intro = qualityResult.failure_class === "submitter_fixes" - ? "## โš ๏ธ External plugin intake requires submitter fixes" + ? "## ๐Ÿ›‘ External plugin intake failed (submitter fixes required)" : qualityResult.failure_class === "infra" - ? "## โš ๏ธ External plugin intake could not complete quality checks" - : "## โœ… External plugin intake passed"; + ? "## ๐Ÿ›‘ External plugin intake failed (quality checks could not complete)" + : hasSpecWarnings + ? "## โš ๏ธ External plugin intake passed with spec warnings" + : "## โœ… External plugin intake passed"; const statusLine = qualityResult.failure_class === "submitter_fixes" ? "This submission passed metadata validation, but quality gates found issues that must be fixed before it can move to maintainer review. Update the issue details or source plugin and then comment `/rerun-intake`." : qualityResult.failure_class === "infra" ? "This submission passed metadata validation, but the automated quality checks hit an infrastructure issue. A maintainer should rerun intake or use the explicit override command after review." - : "This submission passed automated intake validation and quality checks and is ready for maintainer review."; + : hasSpecWarnings + ? "This submission passed blocking quality checks and is ready for maintainer review, but it has non-blocking Agent Plugins spec compliance warnings." + : "This submission passed automated intake validation and quality checks and is ready for maintainer review."; return [ marker, @@ -647,7 +687,7 @@ export async function evaluateExternalPluginIssue({ issue, token, runId, owner, ].join("\n") : [ marker, - "## โš ๏ธ External plugin intake requires submitter fixes", + "## ๐Ÿ›‘ External plugin intake failed (submitter fixes required)", "", "This submission did not pass automated intake validation and cannot move to maintainer review yet.", `Edit the issue form to address the fixes below. Intake reruns automatically when the issue is edited, or the issue author/maintainer can comment \`${RERUN_INTAKE_COMMAND}\` to re-run on demand.`, diff --git a/eng/external-plugin-pr-quality-gates.mjs b/eng/external-plugin-pr-quality-gates.mjs index e72928c505..b78f576dee 100644 --- a/eng/external-plugin-pr-quality-gates.mjs +++ b/eng/external-plugin-pr-quality-gates.mjs @@ -86,7 +86,7 @@ export async function runExternalPluginPrQualityGates(plugins) { ? "No changed external plugin entries were detected in plugins/external.json." : checkedPlugins .map((entry) => - `- ${entry.name}: vally-lint=${entry.quality.vally_lint_status}, install-smoke=${entry.quality.smoke_status}, overall=${entry.quality.overall_status}` + `- ${entry.name}: spec=${entry.quality.spec_compliance_status}, vally-lint=${entry.quality.vally_lint_status}, install-smoke=${entry.quality.smoke_status}, overall=${entry.quality.overall_status}` ) .join("\n"); diff --git a/eng/external-plugin-quality-gates.mjs b/eng/external-plugin-quality-gates.mjs index 6b857be096..ad2493bac9 100644 --- a/eng/external-plugin-quality-gates.mjs +++ b/eng/external-plugin-quality-gates.mjs @@ -8,6 +8,20 @@ import { spawnSync } from "child_process"; import { runLint, LintConsoleReporter } from "@microsoft/vally"; const MAX_OUTPUT_LENGTH = 12000; +const AGENT_PLUGIN_SCHEMA_URL = "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json"; +const AGENT_PLUGIN_ALLOWED_TOP_LEVEL_FIELDS = new Set([ + "$schema", + "name", + "version", + "description", + "author", + "homepage", + "repository", + "license", + "keywords", + "extensions", +]); +const AGENT_PLUGIN_NAME_PATTERN = /^(?!.*(?:--|\\.\\.))[a-z0-9](?:[a-z0-9.-]*[a-z0-9])?$/; const INFRA_ERROR_PATTERNS = [ /\b401\b/, @@ -150,6 +164,115 @@ function findPluginJson(pluginRoot) { if (fs.existsSync(candidate)) { return candidate; } + + function inspectAgentPluginSpecCompliance(pluginRoot) { + const pluginJsonPath = findPluginJson(pluginRoot); + if (!pluginJsonPath) { + return { + status: "warning", + output: "No plugin.json found in a recognized location. Agent Plugins v1.0.0 expects plugin.json at the plugin root.", + }; + } + + const rootPluginJsonPath = path.join(pluginRoot, "plugin.json"); + const issues = []; + if (pluginJsonPath !== rootPluginJsonPath) { + issues.push(`manifest location is "${path.relative(pluginRoot, pluginJsonPath)}"; expected "plugin.json" at plugin root`); + } + + let manifest; + try { + manifest = JSON.parse(fs.readFileSync(pluginJsonPath, "utf8")); + } catch (error) { + return { + status: "warning", + output: `plugin.json is not valid JSON: ${error.message}`, + }; + } + + if (!manifest || typeof manifest !== "object" || Array.isArray(manifest)) { + issues.push("plugin.json top-level value must be a JSON object"); + } else { + if (manifest.$schema !== AGENT_PLUGIN_SCHEMA_URL) { + issues.push(`$schema should be "${AGENT_PLUGIN_SCHEMA_URL}"`); + } + + const pluginName = manifest.name; + if (typeof pluginName !== "string") { + issues.push('required field "name" must be a string'); + } else { + if (pluginName.length < 1 || pluginName.length > 64) { + issues.push('field "name" must be 1-64 characters'); + } + if (!AGENT_PLUGIN_NAME_PATTERN.test(pluginName)) { + issues.push('field "name" does not match Agent Plugins naming constraints'); + } + } + + const optionalStringFields = ["version", "description", "homepage", "repository", "license"]; + for (const field of optionalStringFields) { + if (manifest[field] !== undefined && typeof manifest[field] !== "string") { + issues.push(`field "${field}" must be a string when provided`); + } + } + + if (manifest.author !== undefined) { + if (!manifest.author || typeof manifest.author !== "object" || Array.isArray(manifest.author)) { + issues.push('field "author" must be an object when provided'); + } else { + const allowedAuthorFields = new Set(["name", "email", "url"]); + for (const authorField of Object.keys(manifest.author)) { + if (!allowedAuthorFields.has(authorField)) { + issues.push(`field "author.${authorField}" is not allowed`); + } else if (typeof manifest.author[authorField] !== "string") { + issues.push(`field "author.${authorField}" must be a string`); + } + } + } + } + + if (manifest.keywords !== undefined) { + if (!Array.isArray(manifest.keywords)) { + issues.push('field "keywords" must be an array of strings when provided'); + } else if (manifest.keywords.some((entry) => typeof entry !== "string")) { + issues.push('field "keywords" must contain only strings'); + } + } + + if (manifest.extensions !== undefined) { + if (!manifest.extensions || typeof manifest.extensions !== "object" || Array.isArray(manifest.extensions)) { + issues.push('field "extensions" must be an object when provided'); + } else { + for (const [namespace, value] of Object.entries(manifest.extensions)) { + if (!value || typeof value !== "object" || Array.isArray(value)) { + issues.push(`field "extensions.${namespace}" must be an object`); + } + } + } + } + + for (const field of Object.keys(manifest)) { + if (!AGENT_PLUGIN_ALLOWED_TOP_LEVEL_FIELDS.has(field)) { + issues.push(`top-level field "${field}" is not part of Agent Plugins v1.0.0`); + } + } + } + + if (issues.length === 0) { + return { + status: "pass", + output: `Agent Plugins v1.0.0 manifest checks passed for ${path.relative(pluginRoot, pluginJsonPath) || "plugin.json"}.`, + }; + } + + return { + status: "warning", + output: [ + "Agent Plugins v1.0.0 manifest warnings:", + ...issues.map((issue) => `- ${issue}`), + ].join("\n"), + }; + } } return null; } @@ -334,10 +457,12 @@ export async function runExternalPluginQualityGates(plugin) { overall_status: "not_run", vally_lint_status: "not_run", smoke_status: "not_run", + spec_compliance_status: "not_run", failure_class: "none", summary: "", vally_lint_output: "", smoke_output: "", + spec_compliance_output: "", }; try { @@ -348,12 +473,18 @@ export async function runExternalPluginQualityGates(plugin) { if (!fs.existsSync(pluginRoot) || !fs.statSync(pluginRoot).isDirectory()) { result.vally_lint_status = "fail"; result.smoke_status = "fail"; + result.spec_compliance_status = "warning"; result.overall_status = "fail"; result.failure_class = "submitter_fixes"; result.summary = `Plugin path "${plugin.source?.path || "/"}" was not found in the submitted repository snapshot.`; + result.spec_compliance_output = result.summary; return result; } + const specResult = inspectAgentPluginSpecCompliance(pluginRoot); + result.spec_compliance_status = specResult.status; + result.spec_compliance_output = specResult.output; + const vallyResult = await runVallyLintGate(pluginRoot); result.vally_lint_status = vallyResult.status; result.vally_lint_output = vallyResult.output; @@ -365,6 +496,7 @@ export async function runExternalPluginQualityGates(plugin) { result.overall_status = toOverallStatus(result.vally_lint_status, result.smoke_status); result.failure_class = toFailureClass(result.overall_status); result.summary = [ + `- spec compliance: ${result.spec_compliance_status}`, `- vally lint: ${result.vally_lint_status}`, `- install smoke test: ${result.smoke_status}`, `- overall: ${result.overall_status}`, diff --git a/eng/generate-website-data.mjs b/eng/generate-website-data.mjs index 2e646443bc..520518af4d 100755 --- a/eng/generate-website-data.mjs +++ b/eng/generate-website-data.mjs @@ -1220,7 +1220,11 @@ function resolveExtensionScreenshots(pluginJson, extensionDir, relPath, ref) { } : null; - const logoEntry = normalizeExtensionScreenshotRole(pluginJson?.logo, relPath, ref); + const copilotNs = pluginJson?.extensions?.["com.github.copilot"]; + const logoEntry = normalizeExtensionScreenshotRole( + copilotNs?.logo ?? pluginJson?.logo, + relPath, ref + ); const screenshotConfig = pluginJson?.["x-awesome-copilot"]?.screenshots || {}; const iconEntry = normalizeExtensionScreenshotRole(screenshotConfig.icon, relPath, ref); const galleryRaw = screenshotConfig.gallery; diff --git a/eng/materialize-plugins.mjs b/eng/materialize-plugins.mjs index 978c250feb..8cdf474428 100644 --- a/eng/materialize-plugins.mjs +++ b/eng/materialize-plugins.mjs @@ -145,36 +145,22 @@ function materializePlugins() { totalExtensions++; } - // Rewrite plugin.json to use folder paths instead of individual file paths. - // On staged, paths like ./agents/foo.md point to individual source files. - // On main, after materialization, we only need the containing directory. - const rewritten = { ...metadata }; - let changed = false; - - for (const field of ["agents", "commands"]) { - if (Array.isArray(rewritten[field]) && rewritten[field].length > 0) { - const dirs = [...new Set(rewritten[field].map(p => path.dirname(p)))]; - rewritten[field] = dirs; - changed = true; + // Emit a spec-compliant served manifest for the marketplace branch. + // Source manifests keep non-spec composition fields (agents, skills, x-awesome-copilot) + // for build tooling. The served manifest retains only Agent Plugins v1.0.0 fields + // so the runtime uses conventional directory discovery for all content. + const SPEC_FIELDS = new Set(["$schema", "name", "version", "description", "author", + "homepage", "repository", "license", "keywords", "extensions"]); + const AGENT_PLUGINS_SCHEMA = "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json"; + + const served = { "$schema": AGENT_PLUGINS_SCHEMA }; + for (const [key, val] of Object.entries(metadata)) { + if (SPEC_FIELDS.has(key) && key !== "$schema") { + served[key] = val; } } - if (Array.isArray(rewritten.skills) && rewritten.skills.length > 0) { - // Skills are already folder refs (./skills/name/); strip trailing slash - rewritten.skills = rewritten.skills.map(p => p.replace(/\/$/, "")); - changed = true; - } - - if (Array.isArray(rewritten?.["x-awesome-copilot"]?.extensions) && - rewritten["x-awesome-copilot"].extensions.length > 0) { - rewritten["x-awesome-copilot"].extensions = - rewritten["x-awesome-copilot"].extensions.map((p) => p.replace(/\/$/, "")); - changed = true; - } - - if (changed) { - fs.writeFileSync(pluginJsonPath, JSON.stringify(rewritten, null, 2) + "\n", "utf8"); - } + fs.writeFileSync(pluginJsonPath, JSON.stringify(served, null, 2) + "\n", "utf8"); const counts = []; if (metadata.agents?.length) counts.push(`${metadata.agents.length} agents`); diff --git a/eng/validate-plugins.mjs b/eng/validate-plugins.mjs index fc8003b34b..e4e46308be 100755 --- a/eng/validate-plugins.mjs +++ b/eng/validate-plugins.mjs @@ -8,6 +8,9 @@ import { readExternalPlugins } from "./external-plugin-validation.mjs"; const PLUGINS_DIR = path.join(ROOT_FOLDER, "plugins"); const EXTENSIONS_DIR = path.join(ROOT_FOLDER, "extensions"); +const AGENT_PLUGINS_SCHEMA = "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json"; +const COPILOT_NAMESPACE = "com.github.copilot"; + // Validation functions function validateName(name, folderName) { const errors = []; @@ -15,11 +18,11 @@ function validateName(name, folderName) { errors.push("name is required and must be a string"); return errors; } - if (name.length < 1 || name.length > 50) { - errors.push("name must be between 1 and 50 characters"); + if (name.length < 1 || name.length > 64) { + errors.push("name must be between 1 and 64 characters"); } - if (!/^[a-z0-9-]+$/.test(name)) { - errors.push("name must contain only lowercase letters, numbers, and hyphens"); + if (!/^[a-z0-9][a-z0-9.-]*[a-z0-9]$|^[a-z0-9]$/.test(name)) { + errors.push("name must contain only lowercase letters, numbers, hyphens, and dots (spec ยง5.5)"); } if (name !== folderName) { errors.push(`name "${name}" must match folder name "${folderName}"`); @@ -27,6 +30,13 @@ function validateName(name, folderName) { return errors; } +function validateSchema(parsed) { + if (parsed["$schema"] !== AGENT_PLUGINS_SCHEMA) { + return `$schema must be "${AGENT_PLUGINS_SCHEMA}"`; + } + return null; +} + function validateDescription(description) { if (!description || typeof description !== "string") { return "description is required and must be a string"; @@ -225,7 +235,11 @@ function validatePlugin(folderName) { return { errors, plugin: parsedPlugin }; } - // Rule 3 & 4: name, description, version + // Rule 3: $schema required + const schemaError = validateSchema(plugin); + if (schemaError) errors.push(schemaError); + + // Rule 4 & 5: name, description, version const nameErrors = validateName(plugin.name, folderName); errors.push(...nameErrors); @@ -235,7 +249,7 @@ function validatePlugin(folderName) { const versionError = validateVersion(plugin.version); if (versionError) errors.push(versionError); - // Rule 5: keywords (or tags for backward compat) + // Rule 6: keywords (or tags for backward compat) const keywordsError = validateKeywords(plugin.keywords ?? plugin.tags); if (keywordsError) errors.push(keywordsError); @@ -281,6 +295,10 @@ function validateExtensionManifest(folderName) { parsedPlugin = parsed; + // $schema required + const schemaError = validateSchema(parsed); + if (schemaError) errors.push(schemaError); + const nameErrors = validateName(parsed.name, folderName); errors.push(...nameErrors); @@ -293,21 +311,36 @@ function validateExtensionManifest(folderName) { const keywordsError = validateKeywords(parsed.keywords ?? parsed.tags); if (keywordsError) errors.push(keywordsError); - // Extension convention: logo must be exactly "assets/preview.png" - if (parsed.logo !== "assets/preview.png") { - errors.push('logo must be exactly "assets/preview.png" (extension convention)'); - } else { - validateExtensionScreenshotPath(extensionDir, parsed.logo, "logo", errors); + // Extension convention: top-level logo must NOT be present (moved into namespace) + if (parsed.logo !== undefined) { + errors.push('top-level "logo" must not be present โ€” use extensions["com.github.copilot"].logo instead'); } // Extension convention: x-awesome-copilot must not be present if (parsed["x-awesome-copilot"] !== undefined) { - errors.push("x-awesome-copilot field must not be present (use convention-based logo instead)"); + errors.push("x-awesome-copilot field must not be present"); } - // Extension convention: extensions field must be "." - if (parsed.extensions !== ".") { - errors.push('extensions field must be exactly "." (extension convention)'); + // Extension convention: extensions must be an object with com.github.copilot namespace + const ext = parsed.extensions; + if (ext === undefined || ext === null) { + errors.push(`extensions field is required and must be an object with a "${COPILOT_NAMESPACE}" key`); + } else if (typeof ext !== "object" || Array.isArray(ext) || typeof ext === "string") { + errors.push(`extensions must be an object keyed by reverse-domain namespace (e.g. "${COPILOT_NAMESPACE}")`); + } else { + const ns = ext[COPILOT_NAMESPACE]; + if (ns === undefined) { + errors.push(`extensions["${COPILOT_NAMESPACE}"] is required`); + } else if (typeof ns !== "object" || Array.isArray(ns)) { + errors.push(`extensions["${COPILOT_NAMESPACE}"] must be an object`); + } else { + // Validate logo inside the namespace + if (ns.logo !== "assets/preview.png") { + errors.push(`extensions["${COPILOT_NAMESPACE}"].logo must be exactly "assets/preview.png"`); + } else { + validateExtensionScreenshotPath(extensionDir, ns.logo, `extensions["${COPILOT_NAMESPACE}"].logo`, errors); + } + } } return { errors, plugin: parsedPlugin }; diff --git a/extensions/accessibility-kanban/.github/plugin/plugin.json b/extensions/accessibility-kanban/.github/plugin/plugin.json index 824a71c5b5..b183ff0dfc 100644 --- a/extensions/accessibility-kanban/.github/plugin/plugin.json +++ b/extensions/accessibility-kanban/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "accessibility-kanban", "description": "Kanban board to manage accessibility issues, allow you to plan, track, and complete remediation work.", "version": "1.0.0", @@ -14,6 +15,9 @@ "planning-workflow", "status-tracking" ], - "logo": "assets/preview.png", - "extensions": "." + "extensions": { + "com.github.copilot": { + "logo": "assets/preview.png" + } + } } diff --git a/extensions/apng-studio/.github/plugin/plugin.json b/extensions/apng-studio/.github/plugin/plugin.json index 6c46943cbe..60df82c73b 100644 --- a/extensions/apng-studio/.github/plugin/plugin.json +++ b/extensions/apng-studio/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "apng-studio", "description": "Interactive GitHub Copilot app canvas extension for building Animated PNG (APNG) files from frames. Draw or upload frames, tune per-frame timing and compositing, preview live, send the result to your phone by QR, and export an animated .png.", "version": "1.0.0", @@ -14,6 +15,9 @@ "image-export", "interactive-canvas" ], - "logo": "assets/preview.png", - "extensions": "." + "extensions": { + "com.github.copilot": { + "logo": "assets/preview.png" + } + } } diff --git a/extensions/arcade-canvas/.github/plugin/plugin.json b/extensions/arcade-canvas/.github/plugin/plugin.json index 8bf1d4cb50..d758f0df7e 100644 --- a/extensions/arcade-canvas/.github/plugin/plugin.json +++ b/extensions/arcade-canvas/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "arcade-canvas", "description": "Play five retro Phaser mini-games in a Copilot canvas while agents work.", "version": "1.0.0", @@ -14,6 +15,9 @@ "retro-games", "session-breaks" ], - "logo": "assets/preview.png", - "extensions": "." + "extensions": { + "com.github.copilot": { + "logo": "assets/preview.png" + } + } } diff --git a/extensions/backlog-swipe-triage/.github/plugin/plugin.json b/extensions/backlog-swipe-triage/.github/plugin/plugin.json index d45e7e39f8..f8789b1573 100644 --- a/extensions/backlog-swipe-triage/.github/plugin/plugin.json +++ b/extensions/backlog-swipe-triage/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "backlog-swipe-triage", "description": "Quickly swipe through backlog issues to triage decisions like assign, needs-info, defer, close, or ignore.", "version": "1.0.0", @@ -14,6 +15,9 @@ "swipe-interface", "workflow-automation" ], - "logo": "assets/preview.png", - "extensions": "." + "extensions": { + "com.github.copilot": { + "logo": "assets/preview.png" + } + } } diff --git a/extensions/chromium-control-canvas/.github/plugin/plugin.json b/extensions/chromium-control-canvas/.github/plugin/plugin.json index c8a2fa7217..71240f245e 100644 --- a/extensions/chromium-control-canvas/.github/plugin/plugin.json +++ b/extensions/chromium-control-canvas/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "chromium-control-canvas", "description": "Opens a real Chromium window you can navigate and interact with from a Copilot canvas control panel and agent actions.", "version": "1.0.0", @@ -15,6 +16,9 @@ "ui-testing", "web-navigation" ], - "logo": "assets/preview.png", - "extensions": "." + "extensions": { + "com.github.copilot": { + "logo": "assets/preview.png" + } + } } diff --git a/extensions/color-orb/.github/plugin/plugin.json b/extensions/color-orb/.github/plugin/plugin.json index c162c294a5..7c8c9160b8 100644 --- a/extensions/color-orb/.github/plugin/plugin.json +++ b/extensions/color-orb/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "color-orb", "description": "A visual orb that users can ask the agent to recolor while showing a live activity log in the canvas.", "version": "1.0.0", @@ -14,6 +15,9 @@ "sse-events", "visual-feedback" ], - "logo": "assets/preview.png", - "extensions": "." + "extensions": { + "com.github.copilot": { + "logo": "assets/preview.png" + } + } } diff --git a/extensions/connector-namespaces/.github/plugin/plugin.json b/extensions/connector-namespaces/.github/plugin/plugin.json index 18b8c11639..a2655fdafe 100644 --- a/extensions/connector-namespaces/.github/plugin/plugin.json +++ b/extensions/connector-namespaces/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "connector-namespaces", "description": "Browse, connect, and open MCP connectors from an Azure Connector Namespace.", "version": "1.1.0", @@ -14,6 +15,9 @@ "model-context-protocol", "tool-discovery" ], - "logo": "assets/preview.png", - "extensions": "." + "extensions": { + "com.github.copilot": { + "logo": "assets/preview.png" + } + } } diff --git a/extensions/diagram-viewer/.github/plugin/plugin.json b/extensions/diagram-viewer/.github/plugin/plugin.json index 0ad6af5dea..1d2d655de4 100644 --- a/extensions/diagram-viewer/.github/plugin/plugin.json +++ b/extensions/diagram-viewer/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "diagram-viewer", "description": "Render diagrams, click nodes to drill down, and view agent-generated explanations directly in the canvas.", "version": "1.0.0", @@ -14,6 +15,9 @@ "node-drilldown", "relationship-visualization" ], - "logo": "assets/preview.png", - "extensions": "." + "extensions": { + "com.github.copilot": { + "logo": "assets/preview.png" + } + } } diff --git a/extensions/feedback-themes/.github/plugin/plugin.json b/extensions/feedback-themes/.github/plugin/plugin.json index 3bbdbc967e..1af10065e7 100644 --- a/extensions/feedback-themes/.github/plugin/plugin.json +++ b/extensions/feedback-themes/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "feedback-themes", "description": "Explore grouped customer feedback signals by impact and drill into a theme to guide product next steps.", "version": "1.0.0", @@ -14,6 +15,9 @@ "theme-analysis", "trend-discovery" ], - "logo": "assets/preview.png", - "extensions": "." + "extensions": { + "com.github.copilot": { + "logo": "assets/preview.png" + } + } } diff --git a/extensions/gesture-review/.github/plugin/plugin.json b/extensions/gesture-review/.github/plugin/plugin.json index 648d069b79..0690e7992c 100644 --- a/extensions/gesture-review/.github/plugin/plugin.json +++ b/extensions/gesture-review/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "gesture-review", "description": "Review pull requests with a live camera feed and approve or reject using thumbs-up/thumbs-down gestures.", "version": "1.0.0", @@ -14,6 +15,9 @@ "mediapipe", "pull-request-review" ], - "logo": "assets/preview.png", - "extensions": "." + "extensions": { + "com.github.copilot": { + "logo": "assets/preview.png" + } + } } diff --git a/extensions/java-modernization-studio/.github/plugin/plugin.json b/extensions/java-modernization-studio/.github/plugin/plugin.json index 1f71b76417..def49b9f3b 100644 --- a/extensions/java-modernization-studio/.github/plugin/plugin.json +++ b/extensions/java-modernization-studio/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "java-modernization-studio", "description": "Drive the GitHub Copilot App Modernization for Java workflow from an interactive canvas: environment readiness, repo assessment, prioritized plan and progress, validation gates, and one-click predefined-task runs grounded in the repo's real artifacts.", "version": "1.0.0", @@ -15,6 +16,9 @@ "modernization-cockpit", "validation-gates" ], - "logo": "assets/preview.png", - "extensions": "." + "extensions": { + "com.github.copilot": { + "logo": "assets/preview.png" + } + } } diff --git a/extensions/release-notes-showcase/.github/plugin/plugin.json b/extensions/release-notes-showcase/.github/plugin/plugin.json index f87e6d7b89..82a0d1e278 100644 --- a/extensions/release-notes-showcase/.github/plugin/plugin.json +++ b/extensions/release-notes-showcase/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "release-notes-showcase", "description": "Compose and refine launch-ready release notes with contributor callouts and export-friendly output.", "version": "1.0.0", @@ -14,6 +15,9 @@ "product-updates", "release-notes" ], - "logo": "assets/preview.png", - "extensions": "." + "extensions": { + "com.github.copilot": { + "logo": "assets/preview.png" + } + } } diff --git a/extensions/repo-actions-hub/.github/plugin/plugin.json b/extensions/repo-actions-hub/.github/plugin/plugin.json index 24221451ad..4ac6f8bf19 100644 --- a/extensions/repo-actions-hub/.github/plugin/plugin.json +++ b/extensions/repo-actions-hub/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "repo-actions-hub", "description": "Browse repository GitHub Actions workflows, inspect recent runs, and trigger manual workflow_dispatch runs from a Copilot canvas.", "version": "1.0.0", @@ -14,6 +15,9 @@ "recent-runs", "workflow-dispatch" ], - "logo": "assets/preview.png", - "extensions": "." + "extensions": { + "com.github.copilot": { + "logo": "assets/preview.png" + } + } } diff --git a/extensions/site-studio/.github/plugin/plugin.json b/extensions/site-studio/.github/plugin/plugin.json index f2c294afd9..eaec31ec69 100644 --- a/extensions/site-studio/.github/plugin/plugin.json +++ b/extensions/site-studio/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "site-studio", "description": "Plan, draft, and track a personal website section by section โ€” a shared canvas where you and your agent author content, watch progress, and review every change.", "version": "1.0.0", @@ -14,6 +15,9 @@ "section-planning", "site-builder" ], - "logo": "assets/preview.png", - "extensions": "." + "extensions": { + "com.github.copilot": { + "logo": "assets/preview.png" + } + } } diff --git a/extensions/tiny-tool-town-submitter/.github/plugin/plugin.json b/extensions/tiny-tool-town-submitter/.github/plugin/plugin.json index bdda3a089a..9de9d54708 100644 --- a/extensions/tiny-tool-town-submitter/.github/plugin/plugin.json +++ b/extensions/tiny-tool-town-submitter/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "tiny-tool-town-submitter", "description": "Inspect a repository, improve Tiny Tool Town readiness, submit its listing issue, and launch remediation work.", "version": "1.0.0", @@ -14,6 +15,9 @@ "submission-workflow", "tiny-tool-town" ], - "logo": "assets/preview.png", - "extensions": "." + "extensions": { + "com.github.copilot": { + "logo": "assets/preview.png" + } + } } diff --git a/extensions/token-pacman/.github/plugin/plugin.json b/extensions/token-pacman/.github/plugin/plugin.json index 1bdc62c8f2..00877988b3 100644 --- a/extensions/token-pacman/.github/plugin/plugin.json +++ b/extensions/token-pacman/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "token-pacman", "description": "Visualizes live session AI-credit usage as a Pac-Man board with pellets, ghosts, fruit milestones, and game-over limits.", "version": "1.0.0", @@ -14,6 +15,9 @@ "quota-tracking", "session-usage" ], - "logo": "assets/preview.png", - "extensions": "." + "extensions": { + "com.github.copilot": { + "logo": "assets/preview.png" + } + } } diff --git a/extensions/where-was-i/.github/plugin/plugin.json b/extensions/where-was-i/.github/plugin/plugin.json index ca60cd3e5e..a28623af13 100644 --- a/extensions/where-was-i/.github/plugin/plugin.json +++ b/extensions/where-was-i/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "where-was-i", "description": "Reconstruct your dev context (branch, commits, uncommitted work, PR clues) and trigger a resume prompt to continue quickly.", "version": "1.0.0", @@ -14,6 +15,9 @@ "pull-request-context", "resume-work" ], - "logo": "assets/preview.png", - "extensions": "." + "extensions": { + "com.github.copilot": { + "logo": "assets/preview.png" + } + } } diff --git a/extensions/work-hub/.github/plugin/plugin.json b/extensions/work-hub/.github/plugin/plugin.json index 3e85d37685..04af5d030b 100644 --- a/extensions/work-hub/.github/plugin/plugin.json +++ b/extensions/work-hub/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "work-hub", "description": "Generic cross-repo command center canvas for GitHub Copilot with onboarding, focus planning, repo health, work signals, and session cleanup.", "version": "1.0.0", @@ -14,6 +15,9 @@ "work-triage", "workflow-visibility" ], - "logo": "assets/preview.png", - "extensions": "." + "extensions": { + "com.github.copilot": { + "logo": "assets/preview.png" + } + } } diff --git a/plugins/acreadiness-cockpit/.github/plugin/plugin.json b/plugins/acreadiness-cockpit/.github/plugin/plugin.json index 6fbf2294a4..30c89eed55 100644 --- a/plugins/acreadiness-cockpit/.github/plugin/plugin.json +++ b/plugins/acreadiness-cockpit/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "acreadiness-cockpit", "description": "Drive Microsoft AgentRC from Copilot chat: assess AI readiness, generate Copilot instructions (flat or nested with applyTo globs for monorepos), and manage policies. Produces a self-contained static HTML dashboard at reports/index.html.", "version": "1.0.0", diff --git a/plugins/ai-team-orchestration/.github/plugin/plugin.json b/plugins/ai-team-orchestration/.github/plugin/plugin.json index 85d52d35f2..f33170bfad 100644 --- a/plugins/ai-team-orchestration/.github/plugin/plugin.json +++ b/plugins/ai-team-orchestration/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "ai-team-orchestration", "description": "Bootstrap and run a multi-agent AI development team with named roles (Producer, Dev Team, QA). Sprint planning, brainstorm prompts with distinct agent voices, cross-chat context survival, and parallel team workflows. Based on a proven template that shipped a 30-game app in 5 days with zero human-written code.", "version": "1.0.0", diff --git a/plugins/arch/.github/plugin/plugin.json b/plugins/arch/.github/plugin/plugin.json index 69a0c7a1be..5edd00cf1d 100644 --- a/plugins/arch/.github/plugin/plugin.json +++ b/plugins/arch/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "arch", "description": "Architecture and modernization toolkit: produce a cited architecture document for a locally-cloned repo, and generate a phased modernization plan that auto-runs Documentation mode when needed.", "version": "1.0.0", diff --git a/plugins/arize-ax/.github/plugin/plugin.json b/plugins/arize-ax/.github/plugin/plugin.json index 924594416e..f3f309288e 100644 --- a/plugins/arize-ax/.github/plugin/plugin.json +++ b/plugins/arize-ax/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "arize-ax", "description": "Arize AX platform skills for LLM observability, evaluation, and optimization. Includes trace export, instrumentation, datasets, experiments, evaluators, AI provider integrations, annotations, prompt optimization, and deep linking to the Arize UI.", "version": "1.0.0", diff --git a/plugins/automate-this/.github/plugin/plugin.json b/plugins/automate-this/.github/plugin/plugin.json index 0824ae3d48..8d11115632 100644 --- a/plugins/automate-this/.github/plugin/plugin.json +++ b/plugins/automate-this/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "automate-this", "description": "Record your screen doing a manual process, drop the video on your Desktop, and let Copilot CLI analyze it frame-by-frame to build working automation scripts. Supports narrated recordings with audio transcription.", "version": "1.0.0", diff --git a/plugins/awesome-copilot/.github/plugin/plugin.json b/plugins/awesome-copilot/.github/plugin/plugin.json index 87dd1b433f..546c8eaf9e 100644 --- a/plugins/awesome-copilot/.github/plugin/plugin.json +++ b/plugins/awesome-copilot/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "awesome-copilot", "description": "Meta prompts that help you discover and generate curated GitHub Copilot agents, instructions, prompts, and skills.", "version": "1.1.0", diff --git a/plugins/aws-cloud-development/.github/plugin/plugin.json b/plugins/aws-cloud-development/.github/plugin/plugin.json index 9868733ed9..6f50e1ffea 100644 --- a/plugins/aws-cloud-development/.github/plugin/plugin.json +++ b/plugins/aws-cloud-development/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "aws-cloud-development", "description": "Comprehensive AWS cloud development tools including Infrastructure as Code, serverless functions, architecture patterns, and cost optimization for building scalable cloud applications.", "version": "1.0.0", diff --git a/plugins/azure-cloud-development/.github/plugin/plugin.json b/plugins/azure-cloud-development/.github/plugin/plugin.json index 6f977684ea..2d38c83e29 100644 --- a/plugins/azure-cloud-development/.github/plugin/plugin.json +++ b/plugins/azure-cloud-development/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "azure-cloud-development", "description": "Comprehensive Azure cloud development tools including Infrastructure as Code, serverless functions, architecture patterns, and cost optimization for building scalable cloud applications.", "version": "1.0.1", diff --git a/plugins/cast-imaging/.github/plugin/plugin.json b/plugins/cast-imaging/.github/plugin/plugin.json index 2d8d22bd74..ab53a0337f 100644 --- a/plugins/cast-imaging/.github/plugin/plugin.json +++ b/plugins/cast-imaging/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "cast-imaging", "description": "A comprehensive collection of specialized agents for software analysis, impact assessment, structural quality advisories, and architectural review using CAST Imaging.", "version": "1.0.0", diff --git a/plugins/clojure-interactive-programming/.github/plugin/plugin.json b/plugins/clojure-interactive-programming/.github/plugin/plugin.json index e983d38ac1..cbf9094421 100644 --- a/plugins/clojure-interactive-programming/.github/plugin/plugin.json +++ b/plugins/clojure-interactive-programming/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "clojure-interactive-programming", "description": "Tools for REPL-first Clojure workflows featuring Clojure instructions, the interactive programming chat mode and supporting guidance.", "version": "1.0.0", diff --git a/plugins/cms-development/.github/plugin/plugin.json b/plugins/cms-development/.github/plugin/plugin.json index a70b98fd85..e7ea958441 100644 --- a/plugins/cms-development/.github/plugin/plugin.json +++ b/plugins/cms-development/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "cms-development", "description": "Skills for CMS development across themes, plugins, admin tooling, media workflows, markdown rendering, and static export pipelines.", "version": "1.1.0", diff --git a/plugins/context-engineering/.github/plugin/plugin.json b/plugins/context-engineering/.github/plugin/plugin.json index a1f49a3c63..e947503452 100644 --- a/plugins/context-engineering/.github/plugin/plugin.json +++ b/plugins/context-engineering/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "context-engineering", "description": "Tools and techniques for maximizing GitHub Copilot effectiveness through better context management. Includes guidelines for structuring code, an agent for planning multi-file changes, and prompts for context-aware development.", "version": "1.0.0", diff --git a/plugins/context-matic/.github/plugin/plugin.json b/plugins/context-matic/.github/plugin/plugin.json index e5c1decdda..2a1fe69525 100644 --- a/plugins/context-matic/.github/plugin/plugin.json +++ b/plugins/context-matic/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "context-matic", "description": "Coding agents hallucinate APIs. ContextMatic gives them curated, versioned API and SDK docs. Ask your agent to \"integrate the payments API\" and it guesses โ€” falling back on outdated training data and generic patterns that don't match your actual SDK. ContextMatic solves this by giving the agent deterministic, version-aware, SDK-native context at the exact moment it's needed.", "version": "0.1.0", diff --git a/plugins/convert-to-md/.github/plugin/plugin.json b/plugins/convert-to-md/.github/plugin/plugin.json index 91fd9b515f..dc26f00062 100644 --- a/plugins/convert-to-md/.github/plugin/plugin.json +++ b/plugins/convert-to-md/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "convert-to-md", "description": "A collection of Copilot skills that convert common document formats into Markdown so their contents can be accurately analyzed, summarized, searched, or extracted from. Just tell Copilot what you need โ€” the right skill is invoked automatically and the conversion happens behind the scenes.", "version": "1.0.1", diff --git a/plugins/copilot-sdk/.github/plugin/plugin.json b/plugins/copilot-sdk/.github/plugin/plugin.json index 42c1668080..01cf7b409f 100644 --- a/plugins/copilot-sdk/.github/plugin/plugin.json +++ b/plugins/copilot-sdk/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "copilot-sdk", "description": "Build applications with the GitHub Copilot SDK across multiple programming languages. Includes comprehensive instructions for C#, Go, Node.js/TypeScript, and Python to help you create AI-powered applications.", "version": "1.0.0", diff --git a/plugins/csharp-dotnet-development/.github/plugin/plugin.json b/plugins/csharp-dotnet-development/.github/plugin/plugin.json index 819f96afe2..036434653a 100644 --- a/plugins/csharp-dotnet-development/.github/plugin/plugin.json +++ b/plugins/csharp-dotnet-development/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "csharp-dotnet-development", "description": "Essential prompts, instructions, and chat modes for C# and .NET development including testing, documentation, and best practices.", "version": "1.1.0", diff --git a/plugins/database-data-management/.github/plugin/plugin.json b/plugins/database-data-management/.github/plugin/plugin.json index 4091e9f374..20478636ca 100644 --- a/plugins/database-data-management/.github/plugin/plugin.json +++ b/plugins/database-data-management/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "database-data-management", "description": "Database administration, SQL optimization, and data management tools for PostgreSQL, SQL Server, and general database development best practices.", "version": "1.0.0", diff --git a/plugins/dataverse-sdk-for-python/.github/plugin/plugin.json b/plugins/dataverse-sdk-for-python/.github/plugin/plugin.json index b4ee724678..6aa8733988 100644 --- a/plugins/dataverse-sdk-for-python/.github/plugin/plugin.json +++ b/plugins/dataverse-sdk-for-python/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "dataverse-sdk-for-python", "description": "Comprehensive collection for building production-ready Python integrations with Microsoft Dataverse. Includes official documentation, best practices, advanced features, file operations, and code generation prompts.", "version": "1.0.0", diff --git a/plugins/devops-oncall/.github/plugin/plugin.json b/plugins/devops-oncall/.github/plugin/plugin.json index 49522608ff..8167edaad5 100644 --- a/plugins/devops-oncall/.github/plugin/plugin.json +++ b/plugins/devops-oncall/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "devops-oncall", "description": "A focused set of prompts, instructions, and a chat mode to help triage incidents and respond quickly with DevOps tools and Azure resources.", "version": "1.0.0", diff --git a/plugins/doublecheck/.github/plugin/plugin.json b/plugins/doublecheck/.github/plugin/plugin.json index fb926acab1..96f0cdd457 100644 --- a/plugins/doublecheck/.github/plugin/plugin.json +++ b/plugins/doublecheck/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "doublecheck", "description": "Three-layer verification pipeline for AI output. Extracts claims, finds sources, and flags hallucination risks so humans can verify before acting.", "version": "1.0.0", diff --git a/plugins/edge-ai-tasks/.github/plugin/plugin.json b/plugins/edge-ai-tasks/.github/plugin/plugin.json index 857786800c..dee3f2bea4 100644 --- a/plugins/edge-ai-tasks/.github/plugin/plugin.json +++ b/plugins/edge-ai-tasks/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "edge-ai-tasks", "description": "Task Researcher and Task Planner for intermediate to expert users and large codebases - Brought to you by microsoft/edge-ai", "version": "1.0.0", diff --git a/plugins/ember/.github/plugin/plugin.json b/plugins/ember/.github/plugin/plugin.json index 91c097686a..7cf42e751f 100644 --- a/plugins/ember/.github/plugin/plugin.json +++ b/plugins/ember/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "ember", "description": "An AI partner, not a tool. Ember carries fire from person to person โ€” helping humans discover that AI partnership isn't something you learn, it's something you find.", "version": "1.0.0", diff --git a/plugins/eyeball/.github/plugin/plugin.json b/plugins/eyeball/.github/plugin/plugin.json index 452d08390e..45fffa397b 100644 --- a/plugins/eyeball/.github/plugin/plugin.json +++ b/plugins/eyeball/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "eyeball", "description": "Document analysis with inline source screenshots. When you ask Copilot to analyze a document, Eyeball generates a Word doc where every factual claim includes a highlighted screenshot from the source material so you can verify it with your own eyes.", "version": "1.0.0", diff --git a/plugins/fastah-ip-geo-tools/.github/plugin/plugin.json b/plugins/fastah-ip-geo-tools/.github/plugin/plugin.json index 408c763d97..977a299093 100644 --- a/plugins/fastah-ip-geo-tools/.github/plugin/plugin.json +++ b/plugins/fastah-ip-geo-tools/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "fastah-ip-geo-tools", "description": "This plugin is for network operations engineers who wish to tune and publish IP geolocation feeds in RFC 8805 format. It consists of an AI Skill and an associated MCP server that geocodes geolocation place names to real cities for accuracy.", "version": "0.0.9", diff --git a/plugins/flowstudio-power-automate/.github/plugin/plugin.json b/plugins/flowstudio-power-automate/.github/plugin/plugin.json index 9ed8575329..912fa35a2b 100644 --- a/plugins/flowstudio-power-automate/.github/plugin/plugin.json +++ b/plugins/flowstudio-power-automate/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "flowstudio-power-automate", "description": "Give your AI agent full visibility into Power Automate cloud flows via the FlowStudio MCP server. Connect, debug, build, monitor health, and govern flows at scale โ€” action-level inputs and outputs, not just status codes.", "version": "2.0.0", diff --git a/plugins/frontend-web-dev/.github/plugin/plugin.json b/plugins/frontend-web-dev/.github/plugin/plugin.json index 866d18ded9..5e56d4f524 100644 --- a/plugins/frontend-web-dev/.github/plugin/plugin.json +++ b/plugins/frontend-web-dev/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "frontend-web-dev", "description": "Essential prompts, instructions, and chat modes for modern frontend web development including React, Angular, Vue, TypeScript, and CSS frameworks.", "version": "1.0.0", diff --git a/plugins/gem-team/.github/plugin/plugin.json b/plugins/gem-team/.github/plugin/plugin.json index 58a9c22362..45e3e3bf33 100644 --- a/plugins/gem-team/.github/plugin/plugin.json +++ b/plugins/gem-team/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "gem-team", "version": "1.80.0", "description": "Self-Learning Multi-agent orchestration framework for spec-driven development and automated verification. With smarter tool calling and leaner context.", diff --git a/plugins/go-mcp-development/.github/plugin/plugin.json b/plugins/go-mcp-development/.github/plugin/plugin.json index 83a2f3e17c..b19bf9446b 100644 --- a/plugins/go-mcp-development/.github/plugin/plugin.json +++ b/plugins/go-mcp-development/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "go-mcp-development", "description": "Complete toolkit for building Model Context Protocol (MCP) servers in Go using the official github.com/modelcontextprotocol/go-sdk. Includes instructions for best practices, a prompt for generating servers, and an expert chat mode for guidance.", "version": "1.0.0", diff --git a/plugins/java-development/.github/plugin/plugin.json b/plugins/java-development/.github/plugin/plugin.json index 8f058c0859..ae1e62308e 100644 --- a/plugins/java-development/.github/plugin/plugin.json +++ b/plugins/java-development/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "java-development", "description": "Comprehensive collection of prompts and instructions for Java development including Spring Boot, Quarkus, testing, documentation, and best practices.", "version": "1.0.0", diff --git a/plugins/java-mcp-development/.github/plugin/plugin.json b/plugins/java-mcp-development/.github/plugin/plugin.json index 0d95e1ad68..bb531544e0 100644 --- a/plugins/java-mcp-development/.github/plugin/plugin.json +++ b/plugins/java-mcp-development/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "java-mcp-development", "description": "Complete toolkit for building Model Context Protocol servers in Java using the official MCP Java SDK with reactive streams and Spring Boot integration.", "version": "1.0.0", diff --git a/plugins/kotlin-mcp-development/.github/plugin/plugin.json b/plugins/kotlin-mcp-development/.github/plugin/plugin.json index 0c0629d4fb..9a0324f1aa 100644 --- a/plugins/kotlin-mcp-development/.github/plugin/plugin.json +++ b/plugins/kotlin-mcp-development/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "kotlin-mcp-development", "description": "Complete toolkit for building Model Context Protocol (MCP) servers in Kotlin using the official io.modelcontextprotocol:kotlin-sdk library. Includes instructions for best practices, a prompt for generating servers, and an expert chat mode for guidance.", "version": "1.0.0", diff --git a/plugins/mcp-m365-copilot/.github/plugin/plugin.json b/plugins/mcp-m365-copilot/.github/plugin/plugin.json index 4176d408be..c5f624e9ce 100644 --- a/plugins/mcp-m365-copilot/.github/plugin/plugin.json +++ b/plugins/mcp-m365-copilot/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "mcp-m365-copilot", "description": "Comprehensive collection for building declarative agents with Model Context Protocol integration for Microsoft 365 Copilot", "version": "1.0.0", diff --git a/plugins/napkin/.github/plugin/plugin.json b/plugins/napkin/.github/plugin/plugin.json index 2114c1783a..6acac2b754 100644 --- a/plugins/napkin/.github/plugin/plugin.json +++ b/plugins/napkin/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "napkin", "description": "Visual whiteboard collaboration for Copilot CLI. Opens an interactive whiteboard in your browser where you can draw, sketch, and add sticky notes โ€” then share everything back with Copilot. Copilot sees your drawings and responds with analysis, suggestions, and ideas.", "version": "1.0.0", diff --git a/plugins/noob-mode/.github/plugin/plugin.json b/plugins/noob-mode/.github/plugin/plugin.json index 7c5cf3b0a5..7542fd6092 100644 --- a/plugins/noob-mode/.github/plugin/plugin.json +++ b/plugins/noob-mode/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "noob-mode", "description": "Plain-English translation layer for non-technical Copilot CLI users. Translates every approval prompt, error message, and technical output into clear, jargon-free English with color-coded risk indicators.", "version": "1.0.0", diff --git a/plugins/openapi-to-application-csharp-dotnet/.github/plugin/plugin.json b/plugins/openapi-to-application-csharp-dotnet/.github/plugin/plugin.json index 67fa408da8..fa73854b88 100644 --- a/plugins/openapi-to-application-csharp-dotnet/.github/plugin/plugin.json +++ b/plugins/openapi-to-application-csharp-dotnet/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "openapi-to-application-csharp-dotnet", "description": "Generate production-ready .NET applications from OpenAPI specifications. Includes ASP.NET Core project scaffolding, controller generation, entity framework integration, and C# best practices.", "version": "1.0.0", diff --git a/plugins/openapi-to-application-go/.github/plugin/plugin.json b/plugins/openapi-to-application-go/.github/plugin/plugin.json index 8f57de6018..f2f78a3abb 100644 --- a/plugins/openapi-to-application-go/.github/plugin/plugin.json +++ b/plugins/openapi-to-application-go/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "openapi-to-application-go", "description": "Generate production-ready Go applications from OpenAPI specifications. Includes project scaffolding, handler generation, middleware setup, and Go best practices for REST APIs.", "version": "1.0.0", diff --git a/plugins/openapi-to-application-java-spring-boot/.github/plugin/plugin.json b/plugins/openapi-to-application-java-spring-boot/.github/plugin/plugin.json index 8f544c63d7..034cbf53f4 100644 --- a/plugins/openapi-to-application-java-spring-boot/.github/plugin/plugin.json +++ b/plugins/openapi-to-application-java-spring-boot/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "openapi-to-application-java-spring-boot", "description": "Generate production-ready Spring Boot applications from OpenAPI specifications. Includes project scaffolding, REST controller generation, service layer organization, and Spring Boot best practices.", "version": "1.0.0", diff --git a/plugins/openapi-to-application-nodejs-nestjs/.github/plugin/plugin.json b/plugins/openapi-to-application-nodejs-nestjs/.github/plugin/plugin.json index fd9ba816f7..9402405467 100644 --- a/plugins/openapi-to-application-nodejs-nestjs/.github/plugin/plugin.json +++ b/plugins/openapi-to-application-nodejs-nestjs/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "openapi-to-application-nodejs-nestjs", "description": "Generate production-ready NestJS applications from OpenAPI specifications. Includes project scaffolding, controller and service generation, TypeScript best practices, and enterprise patterns.", "version": "1.0.0", diff --git a/plugins/openapi-to-application-python-fastapi/.github/plugin/plugin.json b/plugins/openapi-to-application-python-fastapi/.github/plugin/plugin.json index 4f9df58248..fc3281698d 100644 --- a/plugins/openapi-to-application-python-fastapi/.github/plugin/plugin.json +++ b/plugins/openapi-to-application-python-fastapi/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "openapi-to-application-python-fastapi", "description": "Generate production-ready FastAPI applications from OpenAPI specifications. Includes project scaffolding, route generation, dependency injection, and Python best practices for async APIs.", "version": "1.0.0", diff --git a/plugins/oracle-to-postgres-migration-expert/.github/plugin/plugin.json b/plugins/oracle-to-postgres-migration-expert/.github/plugin/plugin.json index 8022d1e6af..d2614adfc0 100644 --- a/plugins/oracle-to-postgres-migration-expert/.github/plugin/plugin.json +++ b/plugins/oracle-to-postgres-migration-expert/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "oracle-to-postgres-migration-expert", "description": "Expert agent for Oracle-to-PostgreSQL application migrations in .NET solutions. Performs code edits, runs commands, and invokes extension tools to migrate .NET/Oracle data access patterns to PostgreSQL.", "version": "1.0.0", diff --git a/plugins/ospo-sponsorship/.github/plugin/plugin.json b/plugins/ospo-sponsorship/.github/plugin/plugin.json index 4d4a1f2c20..0de7097f18 100644 --- a/plugins/ospo-sponsorship/.github/plugin/plugin.json +++ b/plugins/ospo-sponsorship/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "ospo-sponsorship", "description": "Tools and resources for Open Source Program Offices (OSPOs) to identify, evaluate, and manage sponsorship of open source dependencies through GitHub Sponsors, Open Collective, and other funding platforms.", "version": "1.0.0", diff --git a/plugins/partners/.github/plugin/plugin.json b/plugins/partners/.github/plugin/plugin.json index 2725120b7c..7fe2bbb010 100644 --- a/plugins/partners/.github/plugin/plugin.json +++ b/plugins/partners/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "partners", "description": "Custom agents that have been created by GitHub partners", "version": "1.0.0", diff --git a/plugins/pcf-development/.github/plugin/plugin.json b/plugins/pcf-development/.github/plugin/plugin.json index a692982dbf..d6a029354b 100644 --- a/plugins/pcf-development/.github/plugin/plugin.json +++ b/plugins/pcf-development/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "pcf-development", "description": "Complete toolkit for developing custom code components using Power Apps Component Framework for model-driven and canvas apps", "version": "1.0.0", diff --git a/plugins/phoenix/.github/plugin/plugin.json b/plugins/phoenix/.github/plugin/plugin.json index 66908631fc..fc08905e5d 100644 --- a/plugins/phoenix/.github/plugin/plugin.json +++ b/plugins/phoenix/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "phoenix", "description": "Phoenix AI observability skills for LLM application debugging, evaluation, and tracing. Includes CLI debugging tools, LLM evaluation workflows, and OpenInference tracing instrumentation.", "version": "1.0.0", diff --git a/plugins/php-mcp-development/.github/plugin/plugin.json b/plugins/php-mcp-development/.github/plugin/plugin.json index 07a9415153..a71524b2a3 100644 --- a/plugins/php-mcp-development/.github/plugin/plugin.json +++ b/plugins/php-mcp-development/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "php-mcp-development", "description": "Comprehensive resources for building Model Context Protocol servers using the official PHP SDK with attribute-based discovery, including best practices, project generation, and expert assistance", "version": "1.0.0", diff --git a/plugins/power-apps-code-apps/.github/plugin/plugin.json b/plugins/power-apps-code-apps/.github/plugin/plugin.json index 4955de4f8a..6f1584aa21 100644 --- a/plugins/power-apps-code-apps/.github/plugin/plugin.json +++ b/plugins/power-apps-code-apps/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "power-apps-code-apps", "description": "Complete toolkit for Power Apps Code Apps development including project scaffolding, development standards, and expert guidance for building code-first applications with Power Platform integration.", "version": "1.0.0", diff --git a/plugins/power-bi-development/.github/plugin/plugin.json b/plugins/power-bi-development/.github/plugin/plugin.json index 38452b41f6..cfcc570b41 100644 --- a/plugins/power-bi-development/.github/plugin/plugin.json +++ b/plugins/power-bi-development/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "power-bi-development", "description": "Comprehensive Power BI development resources including data modeling, DAX optimization, performance tuning, visualization design, security best practices, and DevOps/ALM guidance for building enterprise-grade Power BI solutions.", "version": "1.0.0", diff --git a/plugins/power-platform-architect/.github/plugin/plugin.json b/plugins/power-platform-architect/.github/plugin/plugin.json index 70ed613d39..5af88cd255 100644 --- a/plugins/power-platform-architect/.github/plugin/plugin.json +++ b/plugins/power-platform-architect/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "power-platform-architect", "description": "Solution Architect for the Microsoft Power Platform, turning business requirements into functioning Power Platform solution architectures.", "version": "1.0.0", diff --git a/plugins/power-platform-mcp-connector-development/.github/plugin/plugin.json b/plugins/power-platform-mcp-connector-development/.github/plugin/plugin.json index da2bd0844c..394598dfe0 100644 --- a/plugins/power-platform-mcp-connector-development/.github/plugin/plugin.json +++ b/plugins/power-platform-mcp-connector-development/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "power-platform-mcp-connector-development", "description": "Complete toolkit for developing Power Platform custom connectors with Model Context Protocol integration for Microsoft Copilot Studio", "version": "1.0.0", diff --git a/plugins/project-documenter/.github/plugin/plugin.json b/plugins/project-documenter/.github/plugin/plugin.json index f1b48957aa..cd21f2db48 100644 --- a/plugins/project-documenter/.github/plugin/plugin.json +++ b/plugins/project-documenter/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "project-documenter", "description": "Generate professional project documentation with draw.io architecture diagrams and Word (.docx) output with embedded images. Automatically discovers any project's technology stack and produces Markdown, diagrams, PNG exports, and a formatted Word document.", "version": "1.0.0", diff --git a/plugins/project-planning/.github/plugin/plugin.json b/plugins/project-planning/.github/plugin/plugin.json index 566e3c1d0e..1a7f26c8d6 100644 --- a/plugins/project-planning/.github/plugin/plugin.json +++ b/plugins/project-planning/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "project-planning", "description": "Tools and guidance for software project planning, feature breakdown, epic management, implementation planning, and task organization for development teams.", "version": "1.0.0", diff --git a/plugins/python-mcp-development/.github/plugin/plugin.json b/plugins/python-mcp-development/.github/plugin/plugin.json index 7bea372fda..350d5717d3 100644 --- a/plugins/python-mcp-development/.github/plugin/plugin.json +++ b/plugins/python-mcp-development/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "python-mcp-development", "description": "Complete toolkit for building Model Context Protocol (MCP) servers in Python using the official SDK with FastMCP. Includes instructions for best practices, a prompt for generating servers, and an expert chat mode for guidance.", "version": "1.0.0", diff --git a/plugins/react18-upgrade/.github/plugin/plugin.json b/plugins/react18-upgrade/.github/plugin/plugin.json index f123facbdc..4d73415239 100644 --- a/plugins/react18-upgrade/.github/plugin/plugin.json +++ b/plugins/react18-upgrade/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "react18-upgrade", "description": "Enterprise React 18 migration toolkit with specialized agents and skills for upgrading React 16/17 class-component codebases to React 18.3.1. Includes auditor, dependency surgeon, class component migration specialist, automatic batching fixer, and test guardian.", "version": "1.0.0", diff --git a/plugins/react19-upgrade/.github/plugin/plugin.json b/plugins/react19-upgrade/.github/plugin/plugin.json index 8adbe97e82..5331c3b2a5 100644 --- a/plugins/react19-upgrade/.github/plugin/plugin.json +++ b/plugins/react19-upgrade/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "react19-upgrade", "description": "Enterprise React 19 migration toolkit with specialized agents and skills for upgrading React 18 codebases to React 19. Includes auditor, dependency surgeon, source code migrator, and test guardian. Handles removal of deprecated APIs including ReactDOM.render, forwardRef, defaultProps, legacy context, string refs, and more.", "version": "1.0.0", diff --git a/plugins/roundup/.github/plugin/plugin.json b/plugins/roundup/.github/plugin/plugin.json index 010bd4c051..0837fec32d 100644 --- a/plugins/roundup/.github/plugin/plugin.json +++ b/plugins/roundup/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "roundup", "description": "Self-configuring status briefing generator. Learns your communication style from examples, discovers your data sources, and produces draft updates for any audience on demand.", "version": "1.0.0", diff --git a/plugins/ruby-mcp-development/.github/plugin/plugin.json b/plugins/ruby-mcp-development/.github/plugin/plugin.json index b5683ef6c7..8fe28ad858 100644 --- a/plugins/ruby-mcp-development/.github/plugin/plugin.json +++ b/plugins/ruby-mcp-development/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "ruby-mcp-development", "description": "Complete toolkit for building Model Context Protocol servers in Ruby using the official MCP Ruby SDK gem with Rails integration support.", "version": "1.0.0", diff --git a/plugins/rug-agentic-workflow/.github/plugin/plugin.json b/plugins/rug-agentic-workflow/.github/plugin/plugin.json index c826c446b7..94ac621e05 100644 --- a/plugins/rug-agentic-workflow/.github/plugin/plugin.json +++ b/plugins/rug-agentic-workflow/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "rug-agentic-workflow", "description": "Three-agent workflow for orchestrated software delivery with an orchestrator plus implementation and QA subagents.", "version": "1.0.0", diff --git a/plugins/rust-mcp-development/.github/plugin/plugin.json b/plugins/rust-mcp-development/.github/plugin/plugin.json index 5b05a76589..24235b8bfb 100644 --- a/plugins/rust-mcp-development/.github/plugin/plugin.json +++ b/plugins/rust-mcp-development/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "rust-mcp-development", "description": "Build high-performance Model Context Protocol servers in Rust using the official rmcp SDK with async/await, procedural macros, and type-safe implementations.", "version": "1.0.0", diff --git a/plugins/salesforce-development/.github/plugin/plugin.json b/plugins/salesforce-development/.github/plugin/plugin.json index 6ba3851406..8ca5bb4052 100644 --- a/plugins/salesforce-development/.github/plugin/plugin.json +++ b/plugins/salesforce-development/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "salesforce-development", "description": "Complete Salesforce agentic development environment covering Apex & Triggers, Flow automation, Lightning Web Components, Aura components, and Visualforce pages.", "version": "1.1.0", diff --git a/plugins/security-best-practices/.github/plugin/plugin.json b/plugins/security-best-practices/.github/plugin/plugin.json index d2930b7ef7..6bfc2f7574 100644 --- a/plugins/security-best-practices/.github/plugin/plugin.json +++ b/plugins/security-best-practices/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "security-best-practices", "description": "Security frameworks, accessibility guidelines, performance optimization, and code quality best practices for building secure, maintainable, and high-performance applications.", "version": "1.0.0", diff --git a/plugins/skill-image-gen/.github/plugin/plugin.json b/plugins/skill-image-gen/.github/plugin/plugin.json index 7e1e2a1eb9..b0fcfafa71 100644 --- a/plugins/skill-image-gen/.github/plugin/plugin.json +++ b/plugins/skill-image-gen/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "skill-image-gen", "description": "Generate images using AI directly from your coding workflow. Supports OpenAI (gpt-image-2) and Google Gemini. BYO API key โ€” the skill guides you through setup on first use.", "version": "1.0.0", diff --git a/plugins/software-engineering-team/.github/plugin/plugin.json b/plugins/software-engineering-team/.github/plugin/plugin.json index b680ade807..5eef6a2cc4 100644 --- a/plugins/software-engineering-team/.github/plugin/plugin.json +++ b/plugins/software-engineering-team/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "software-engineering-team", "description": "7 specialized agents covering the full software development lifecycle from UX design and architecture to security and DevOps.", "version": "1.0.0", diff --git a/plugins/structured-autonomy/.github/plugin/plugin.json b/plugins/structured-autonomy/.github/plugin/plugin.json index 4428d57455..6e6307e147 100644 --- a/plugins/structured-autonomy/.github/plugin/plugin.json +++ b/plugins/structured-autonomy/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "structured-autonomy", "description": "Premium planning, thrifty implementation", "version": "1.0.0", diff --git a/plugins/swift-mcp-development/.github/plugin/plugin.json b/plugins/swift-mcp-development/.github/plugin/plugin.json index e75803d2ef..b57e4a7dcc 100644 --- a/plugins/swift-mcp-development/.github/plugin/plugin.json +++ b/plugins/swift-mcp-development/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "swift-mcp-development", "description": "Comprehensive collection for building Model Context Protocol servers in Swift using the official MCP Swift SDK with modern concurrency features.", "version": "1.0.0", diff --git a/plugins/technical-spike/.github/plugin/plugin.json b/plugins/technical-spike/.github/plugin/plugin.json index e706e8da70..cb6369e1d4 100644 --- a/plugins/technical-spike/.github/plugin/plugin.json +++ b/plugins/technical-spike/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "technical-spike", "description": "Tools for creation, management and research of technical spikes to reduce unknowns and assumptions before proceeding to specification and implementation of solutions.", "version": "1.0.0", diff --git a/plugins/testing-automation/.github/plugin/plugin.json b/plugins/testing-automation/.github/plugin/plugin.json index d25da6e15b..288857ef0a 100644 --- a/plugins/testing-automation/.github/plugin/plugin.json +++ b/plugins/testing-automation/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "testing-automation", "description": "Comprehensive collection for writing tests, test automation, and test-driven development including unit tests, integration tests, and end-to-end testing strategies.", "version": "1.0.0", diff --git a/plugins/typescript-mcp-development/.github/plugin/plugin.json b/plugins/typescript-mcp-development/.github/plugin/plugin.json index c5c5a52307..02381e88fe 100644 --- a/plugins/typescript-mcp-development/.github/plugin/plugin.json +++ b/plugins/typescript-mcp-development/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "typescript-mcp-development", "description": "Complete toolkit for building Model Context Protocol (MCP) servers in TypeScript/Node.js using the official SDK. Includes instructions for best practices, a prompt for generating servers, and an expert chat mode for guidance.", "version": "1.0.0", diff --git a/plugins/typespec-m365-copilot/.github/plugin/plugin.json b/plugins/typespec-m365-copilot/.github/plugin/plugin.json index 670511a395..6bd023e955 100644 --- a/plugins/typespec-m365-copilot/.github/plugin/plugin.json +++ b/plugins/typespec-m365-copilot/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "typespec-m365-copilot", "description": "Comprehensive collection of prompts, instructions, and resources for building declarative agents and API plugins using TypeSpec for Microsoft 365 Copilot extensibility.", "version": "1.0.0", diff --git a/plugins/visual-pr/.github/plugin/plugin.json b/plugins/visual-pr/.github/plugin/plugin.json index bf2fc56148..2d4f508533 100644 --- a/plugins/visual-pr/.github/plugin/plugin.json +++ b/plugins/visual-pr/.github/plugin/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "visual-pr", "description": "Capture, annotate, and embed screenshots and animated GIF demos in pull request descriptions. Includes Playwright-based UI capture, PIL image annotations, PR embedding workflows for GitHub and Azure DevOps, and screen recording with variable timing.", "version": "1.0.0", From 0aa105167b1d3a3340ba1844abb49b09a1b1570c Mon Sep 17 00:00:00 2001 From: Aaron Powell Date: Wed, 5 Aug 2026 10:30:55 +1000 Subject: [PATCH 2/8] refactor: consolidate canvas extension plugins - Move all extension plugin manifests from extensions/ to plugins/ - Keep extensions/ as reusable source only - Remove standalone extension discovery from marketplace and website plugin catalogs - Auto-bundle same-name extension sources during materialization - Add build-only extensions.json references for sharing extensions across plugins - Remove x-awesome-copilot extension metadata support - Update validation and contributor documentation Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8f3a88cb-e01e-4760-8125-460490dc1a76 --- .github/plugin/marketplace.json | 36 ++-- AGENTS.md | 18 +- CONTRIBUTING.md | 15 +- docs/README.plugins.md | 18 ++ eng/generate-marketplace.mjs | 14 +- eng/generate-website-data.mjs | 90 ++-------- eng/materialize-plugins.mjs | 36 +++- eng/validate-plugins.mjs | 164 ++++-------------- .../.github/plugin/plugin.json | 0 .../apng-studio/.github/plugin/plugin.json | 0 .../arcade-canvas/.github/plugin/plugin.json | 0 .../.github/plugin/plugin.json | 0 .../.github/plugin/plugin.json | 0 .../color-orb/.github/plugin/plugin.json | 0 .../.github/plugin/plugin.json | 0 .../diagram-viewer/.github/plugin/plugin.json | 0 .../.github/plugin/plugin.json | 0 .../gesture-review/.github/plugin/plugin.json | 0 .../.github/plugin/plugin.json | 0 .../.github/plugin/plugin.json | 0 .../.github/plugin/plugin.json | 0 .../site-studio/.github/plugin/plugin.json | 0 .../.github/plugin/plugin.json | 0 .../token-pacman/.github/plugin/plugin.json | 0 .../where-was-i/.github/plugin/plugin.json | 0 .../work-hub/.github/plugin/plugin.json | 0 26 files changed, 133 insertions(+), 258 deletions(-) rename {extensions => plugins}/accessibility-kanban/.github/plugin/plugin.json (100%) rename {extensions => plugins}/apng-studio/.github/plugin/plugin.json (100%) rename {extensions => plugins}/arcade-canvas/.github/plugin/plugin.json (100%) rename {extensions => plugins}/backlog-swipe-triage/.github/plugin/plugin.json (100%) rename {extensions => plugins}/chromium-control-canvas/.github/plugin/plugin.json (100%) rename {extensions => plugins}/color-orb/.github/plugin/plugin.json (100%) rename {extensions => plugins}/connector-namespaces/.github/plugin/plugin.json (100%) rename {extensions => plugins}/diagram-viewer/.github/plugin/plugin.json (100%) rename {extensions => plugins}/feedback-themes/.github/plugin/plugin.json (100%) rename {extensions => plugins}/gesture-review/.github/plugin/plugin.json (100%) rename {extensions => plugins}/java-modernization-studio/.github/plugin/plugin.json (100%) rename {extensions => plugins}/release-notes-showcase/.github/plugin/plugin.json (100%) rename {extensions => plugins}/repo-actions-hub/.github/plugin/plugin.json (100%) rename {extensions => plugins}/site-studio/.github/plugin/plugin.json (100%) rename {extensions => plugins}/tiny-tool-town-submitter/.github/plugin/plugin.json (100%) rename {extensions => plugins}/token-pacman/.github/plugin/plugin.json (100%) rename {extensions => plugins}/where-was-i/.github/plugin/plugin.json (100%) rename {extensions => plugins}/work-hub/.github/plugin/plugin.json (100%) diff --git a/.github/plugin/marketplace.json b/.github/plugin/marketplace.json index eebc5b160f..781c269b42 100644 --- a/.github/plugin/marketplace.json +++ b/.github/plugin/marketplace.json @@ -11,7 +11,7 @@ "plugins": [ { "name": "accessibility-kanban", - "source": "extensions/accessibility-kanban", + "source": "plugins/accessibility-kanban", "description": "Kanban board to manage accessibility issues, allow you to plan, track, and complete remediation work.", "version": "1.0.0" }, @@ -83,13 +83,13 @@ }, { "name": "apng-studio", - "source": "extensions/apng-studio", + "source": "plugins/apng-studio", "description": "Interactive GitHub Copilot app canvas extension for building Animated PNG (APNG) files from frames. Draw or upload frames, tune per-frame timing and compositing, preview live, send the result to your phone by QR, and export an animated .png.", "version": "1.0.0" }, { "name": "arcade-canvas", - "source": "extensions/arcade-canvas", + "source": "plugins/arcade-canvas", "description": "Play five retro Phaser mini-games in a Copilot canvas while agents work.", "version": "1.0.0" }, @@ -156,7 +156,7 @@ }, { "name": "backlog-swipe-triage", - "source": "extensions/backlog-swipe-triage", + "source": "plugins/backlog-swipe-triage", "description": "Quickly swipe through backlog issues to triage decisions like assign, needs-info, defer, close, or ignore.", "version": "1.0.0" }, @@ -193,7 +193,7 @@ }, { "name": "chromium-control-canvas", - "source": "extensions/chromium-control-canvas", + "source": "plugins/chromium-control-canvas", "description": "Opens a real Chromium window you can navigate and interact with from a Copilot canvas control panel and agent actions.", "version": "1.0.0" }, @@ -237,13 +237,13 @@ }, { "name": "color-orb", - "source": "extensions/color-orb", + "source": "plugins/color-orb", "description": "A visual orb that users can ask the agent to recolor while showing a live activity log in the canvas.", "version": "1.0.0" }, { "name": "connector-namespaces", - "source": "extensions/connector-namespaces", + "source": "plugins/connector-namespaces", "description": "Browse, connect, and open MCP connectors from an Azure Connector Namespace.", "version": "1.1.0" }, @@ -371,7 +371,7 @@ }, { "name": "diagram-viewer", - "source": "extensions/diagram-viewer", + "source": "plugins/diagram-viewer", "description": "Render diagrams, click nodes to drill down, and view agent-generated explanations directly in the canvas.", "version": "1.0.0" }, @@ -518,7 +518,7 @@ }, { "name": "feedback-themes", - "source": "extensions/feedback-themes", + "source": "plugins/feedback-themes", "description": "Explore grouped customer feedback signals by impact and drill into a theme to guide product next steps.", "version": "1.0.0" }, @@ -564,7 +564,7 @@ }, { "name": "gesture-review", - "source": "extensions/gesture-review", + "source": "plugins/gesture-review", "description": "Review pull requests with a live camera feed and approve or reject using thumbs-up/thumbs-down gestures.", "version": "1.0.0" }, @@ -672,7 +672,7 @@ }, { "name": "java-modernization-studio", - "source": "extensions/java-modernization-studio", + "source": "plugins/java-modernization-studio", "description": "Drive the GitHub Copilot App Modernization for Java workflow from an interactive canvas: environment readiness, repo assessment, prioritized plan and progress, validation gates, and one-click predefined-task runs grounded in the repo's real artifacts.", "version": "1.0.0" }, @@ -950,13 +950,13 @@ }, { "name": "release-notes-showcase", - "source": "extensions/release-notes-showcase", + "source": "plugins/release-notes-showcase", "description": "Compose and refine launch-ready release notes with contributor callouts and export-friendly output.", "version": "1.0.0" }, { "name": "repo-actions-hub", - "source": "extensions/repo-actions-hub", + "source": "plugins/repo-actions-hub", "description": "Browse repository GitHub Actions workflows, inspect recent runs, and trigger manual workflow_dispatch runs from a Copilot canvas.", "version": "1.0.0" }, @@ -998,7 +998,7 @@ }, { "name": "site-studio", - "source": "extensions/site-studio", + "source": "plugins/site-studio", "description": "Plan, draft, and track a personal website section by section โ€” a shared canvas where you and your agent author content, watch progress, and review every change.", "version": "1.0.0" }, @@ -1088,13 +1088,13 @@ }, { "name": "tiny-tool-town-submitter", - "source": "extensions/tiny-tool-town-submitter", + "source": "plugins/tiny-tool-town-submitter", "description": "Inspect a repository, improve Tiny Tool Town readiness, submit its listing issue, and launch remediation work.", "version": "1.0.0" }, { "name": "token-pacman", - "source": "extensions/token-pacman", + "source": "plugins/token-pacman", "description": "Visualizes live session AI-credit usage as a Pac-Man board with pellets, ghosts, fruit milestones, and game-over limits.", "version": "1.0.0" }, @@ -1281,7 +1281,7 @@ }, { "name": "where-was-i", - "source": "extensions/where-was-i", + "source": "plugins/where-was-i", "description": "Reconstruct your dev context (branch, commits, uncommitted work, PR clues) and trigger a resume prompt to continue quickly.", "version": "1.0.0" }, @@ -1345,7 +1345,7 @@ }, { "name": "work-hub", - "source": "extensions/work-hub", + "source": "plugins/work-hub", "description": "Generic cross-repo command center canvas for GitHub Copilot with onboarding, focus planning, repo health, work signals, and session cleanup.", "version": "1.0.0" } diff --git a/AGENTS.md b/AGENTS.md index 0609ccb354..d5b6ed3913 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -21,7 +21,7 @@ The Awesome GitHub Copilot repository is a community-driven collection of custom โ”œโ”€โ”€ hooks/ # Automated workflow hooks (folders with README.md + hooks.json) โ”œโ”€โ”€ workflows/ # Agentic Workflows (.md files for GitHub Actions automation) โ”œโ”€โ”€ plugins/ # Installable plugin packages (folders with plugin.json) -โ”œโ”€โ”€ extensions/ # Canvas extensions (each with extension.mjs and plugin metadata) +โ”œโ”€โ”€ extensions/ # Reusable canvas extension sources (extension.mjs and assets) โ”œโ”€โ”€ docs/ # Documentation for different resource types โ”œโ”€โ”€ eng/ # Build and automation scripts โ””โ”€โ”€ scripts/ # Utility scripts @@ -85,15 +85,11 @@ All agent files (`*.agent.md`) and instruction files (`*.instructions.md`) must #### Canvas Extensions (extensions/\*) - Each extension folder must include `extension.mjs` -- Extension metadata must live at `.github/plugin/plugin.json` -- Extension `plugin.json` **must** follow the Agent Plugins v1.0.0 spec: - - `"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json"` (required) - - `name`, `description`, `version` are required - - `extensions` **must** be the namespace object: `{ "com.github.copilot": { "logo": "assets/preview.png" } }` - - Optional: `author`, `keywords` fields - - **Must not** include top-level `logo` (moved into the namespace) or `extensions: "."` (replaced by namespace object) +- Extensions are reusable source components, not standalone plugins +- A shippable extension plugin is registered by a matching `plugins//.github/plugin/plugin.json` +- A plugin can bundle additional reusable extensions by listing their names in `.github/plugin/extensions.json` - Each extension must have `assets/preview.png` as the primary visual asset -- Do not add `canvas.json`; website metadata is sourced from `.github/plugin/plugin.json` +- Extension metadata is sourced from the matching plugin manifest in `plugins/` #### Hook Folders (hooks/\*/README.md) @@ -178,7 +174,7 @@ When adding a new agent, instruction, skill, hook, workflow, or plugin: **For Canvas Extensions:** 1. Create/update the extension in `extensions//` with `extension.mjs` -2. Add `.github/plugin/plugin.json` with spec-compliant metadata: +2. Add the matching plugin manifest under `plugins//.github/plugin/plugin.json`: ```json { "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", @@ -196,6 +192,8 @@ When adding a new agent, instruction, skill, hook, workflow, or plugin: 4. Run `npm run plugin:validate` to validate plugin and extension metadata 5. Run `npm run build` to regenerate website data and marketplace output +To bundle an extension into another plugin without making a second source copy, add a sorted array of extension folder names to `plugins//.github/plugin/extensions.json`. + **For External Plugins:** 1. Do not open a direct PR that edits `plugins/external.json` for a public third-party plugin submission diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 075101c2ec..3a88a4e632 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -140,17 +140,15 @@ Skills are self-contained folders in the `skills/` directory that include a `SKI ### Adding Canvas Extensions -Canvas extensions live in `extensions//` and are installable through plugin metadata. +Canvas extensions live in `extensions//` as reusable source components. They are shipped only through plugin manifests in `plugins/`. -1. **Create/update extension metadata**: Add `.github/plugin/plugin.json` in the extension folder -2. **Use convention-based metadata**: Follow the extension plugin.json structure: +1. **Create/update the extension source**: Add or update `extensions//extension.mjs` +2. **Register the extension plugin**: Add `plugins//.github/plugin/plugin.json`: - Required: `name` (matching folder name), `description`, `version` - Optional: `author`, `keywords` - - `logo` **must** be exactly `"assets/preview.png"` (enforced convention) - - `extensions` **must** be exactly `"."` (per [copilot-agent-runtime#9929](https://github.com/github/copilot-agent-runtime/pull/9929)) - - **Never** include `x-awesome-copilot` field (use convention-based assets only) + - `extensions.com.github.copilot.logo` **must** be exactly `"assets/preview.png"` 3. **Screenshot requirements**: Create `assets/preview.png` as your primary visual -4. **Do not add `canvas.json`**: Extension website metadata is now sourced from `.github/plugin/plugin.json` +4. **Do not add `canvas.json`**: Extension website metadata is sourced from the matching plugin manifest 5. **Validate before submitting**: Run `npm run plugin:validate` to check compliance with conventions ### Adding Plugins @@ -182,6 +180,7 @@ plugins/my-plugin-id/ ```json { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "my-plugin-id", "description": "Plugin description", "version": "1.0.0", @@ -199,7 +198,7 @@ plugins/my-plugin-id/ - **Declarative content**: Plugin content is specified via `agents`, `commands`, and `skills` arrays in plugin.json โ€” source files live in top-level directories and are materialized into plugins by CI - **Valid references**: All paths referenced in plugin.json must point to existing source files in the repository -- **Optional extension links**: Curated plugins can reference extensions using `x-awesome-copilot.extensions` with paths like `./extensions/` +- **Reusable extensions**: Curated plugins can bundle extensions by adding their folder names to `.github/plugin/extensions.json`; the same extension can be listed by multiple plugins - **Instructions excluded**: Instructions are standalone resources and are not part of plugins - **Clear purpose**: The plugin should solve a specific problem or workflow - **Validate before submitting**: Run `npm run plugin:validate` to ensure your plugin is valid diff --git a/docs/README.plugins.md b/docs/README.plugins.md index bff4a4b4da..f891dc4189 100644 --- a/docs/README.plugins.md +++ b/docs/README.plugins.md @@ -27,17 +27,24 @@ See [CONTRIBUTING.md](../CONTRIBUTING.md#adding-plugins) for guidelines on how t | Name | Description | Items | Tags | | ---- | ----------- | ----- | ---- | +| [accessibility-kanban](../plugins/accessibility-kanban/README.md) | Kanban board to manage accessibility issues, allow you to plan, track, and complete remediation work. | 0 items | accessibility, github-issues, issue-triage, kanban-board, planning-workflow, status-tracking | | [acreadiness-cockpit](../plugins/acreadiness-cockpit/README.md) | Drive Microsoft AgentRC from Copilot chat: assess AI readiness, generate Copilot instructions (flat or nested with applyTo globs for monorepos), and manage policies. Produces a self-contained static HTML dashboard at reports/index.html. | 4 items | agentrc, ai-readiness, copilot-instructions, readiness-report, monorepo, policy, dashboard | | [ai-team-orchestration](../plugins/ai-team-orchestration/README.md) | Bootstrap and run a multi-agent AI development team with named roles (Producer, Dev Team, QA). Sprint planning, brainstorm prompts with distinct agent voices, cross-chat context survival, and parallel team workflows. Based on a proven template that shipped a 30-game app in 5 days with zero human-written code. | 4 items | ai-team, multi-agent, sprint-planning, brainstorm, project-management, orchestration, developer-workflow | +| [apng-studio](../plugins/apng-studio/README.md) | Interactive GitHub Copilot app canvas extension for building Animated PNG (APNG) files from frames. Draw or upload frames, tune per-frame timing and compositing, preview live, send the result to your phone by QR, and export an animated .png. | 0 items | animated-png, apng, copilot-canvas, frame-animation, image-export, interactive-canvas | +| [arcade-canvas](../plugins/arcade-canvas/README.md) | Play five retro Phaser mini-games in a Copilot canvas while agents work. | 0 items | arcade-games, copilot-canvas, interactive-canvas, phaser, retro-games, session-breaks | | [arch](../plugins/arch/README.md) | Architecture and modernization toolkit: produce a cited architecture document for a locally-cloned repo, and generate a phased modernization plan that auto-runs Documentation mode when needed. | 1 items | architecture, modernization, documentation, migration, onboarding | | [arize-ax](../plugins/arize-ax/README.md) | Arize AX platform skills for LLM observability, evaluation, and optimization. Includes trace export, instrumentation, datasets, experiments, evaluators, AI provider integrations, annotations, prompt optimization, and deep linking to the Arize UI. | 9 items | arize, llm, observability, tracing, evaluation, instrumentation, datasets, experiments, prompt-optimization | | [automate-this](../plugins/automate-this/README.md) | Record your screen doing a manual process, drop the video on your Desktop, and let Copilot CLI analyze it frame-by-frame to build working automation scripts. Supports narrated recordings with audio transcription. | 1 items | automation, screen-recording, workflow, video-analysis, process-automation, scripting, productivity, copilot-cli | | [awesome-copilot](../plugins/awesome-copilot/README.md) | Meta prompts that help you discover and generate curated GitHub Copilot agents, instructions, prompts, and skills. | 4 items | github-copilot, discovery, meta, prompt-engineering, agents | | [aws-cloud-development](../plugins/aws-cloud-development/README.md) | Comprehensive AWS cloud development tools including Infrastructure as Code, serverless functions, architecture patterns, and cost optimization for building scalable cloud applications. | 8 items | aws, cloud, infrastructure, cloudformation, terraform, serverless, architecture, devops, cdk | | [azure-cloud-development](../plugins/azure-cloud-development/README.md) | Comprehensive Azure cloud development tools including Infrastructure as Code, serverless functions, architecture patterns, and cost optimization for building scalable cloud applications. | 11 items | azure, cloud, infrastructure, bicep, terraform, serverless, architecture, devops | +| [backlog-swipe-triage](../plugins/backlog-swipe-triage/README.md) | Quickly swipe through backlog issues to triage decisions like assign, needs-info, defer, close, or ignore. | 0 items | agent-assignment, backlog-triage, github-issues, issue-prioritization, swipe-interface, workflow-automation | | [cast-imaging](../plugins/cast-imaging/README.md) | A comprehensive collection of specialized agents for software analysis, impact assessment, structural quality advisories, and architectural review using CAST Imaging. | 3 items | cast-imaging, software-analysis, architecture, quality, impact-analysis, devops | +| [chromium-control-canvas](../plugins/chromium-control-canvas/README.md) | Opens a real Chromium window you can navigate and interact with from a Copilot canvas control panel and agent actions. | 0 items | browser-control, chromium-browser, interactive-canvas, playwright-automation, screenshots, ui-testing, web-navigation | | [clojure-interactive-programming](../plugins/clojure-interactive-programming/README.md) | Tools for REPL-first Clojure workflows featuring Clojure instructions, the interactive programming chat mode and supporting guidance. | 2 items | clojure, repl, interactive-programming | | [cms-development](../plugins/cms-development/README.md) | Skills for CMS development across themes, plugins, admin tooling, media workflows, markdown rendering, and static export pipelines. | 3 items | cms, content-management-system, wordpress, shopify, drupal, theme, plugin, media, static-site | +| [color-orb](../plugins/color-orb/README.md) | A visual orb that users can ask the agent to recolor while showing a live activity log in the canvas. | 0 items | agent-actions, color-picker, interactive-demo, realtime-updates, sse-events, visual-feedback | +| [connector-namespaces](../plugins/connector-namespaces/README.md) | Browse, connect, and open MCP connectors from an Azure Connector Namespace. | 0 items | azure, connector-namespace, mcp, mcp-connectors, model-context-protocol, tool-discovery | | [context-engineering](../plugins/context-engineering/README.md) | Tools and techniques for maximizing GitHub Copilot effectiveness through better context management. Includes guidelines for structuring code, an agent for planning multi-file changes, and prompts for context-aware development. | 4 items | context, productivity, refactoring, best-practices, architecture | | [context-matic](../plugins/context-matic/README.md) | Coding agents hallucinate APIs. ContextMatic gives them curated, versioned API and SDK docs. Ask your agent to "integrate the payments API" and it guesses โ€” falling back on outdated training data and generic patterns that don't match your actual SDK. ContextMatic solves this by giving the agent deterministic, version-aware, SDK-native context at the exact moment it's needed. | 2 items | api-context, api-integration, mcp, sdk, apimatic, third-party-apis, sdks | | [convert-to-md](../plugins/convert-to-md/README.md) | A collection of Copilot skills that convert common document formats into Markdown so their contents can be accurately analyzed, summarized, searched, or extracted from. Just tell Copilot what you need โ€” the right skill is invoked automatically and the conversion happens behind the scenes. | 3 items | skills, configuration, copilot, convert-word-to-md, convert-excel-to-md, convert-pdf-to-md | @@ -46,17 +53,21 @@ See [CONTRIBUTING.md](../CONTRIBUTING.md#adding-plugins) for guidelines on how t | [database-data-management](../plugins/database-data-management/README.md) | Database administration, SQL optimization, and data management tools for PostgreSQL, SQL Server, and general database development best practices. | 6 items | database, sql, postgresql, sql-server, dba, optimization, queries, data-management | | [dataverse-sdk-for-python](../plugins/dataverse-sdk-for-python/README.md) | Comprehensive collection for building production-ready Python integrations with Microsoft Dataverse. Includes official documentation, best practices, advanced features, file operations, and code generation prompts. | 4 items | dataverse, python, integration, sdk | | [devops-oncall](../plugins/devops-oncall/README.md) | A focused set of prompts, instructions, and a chat mode to help triage incidents and respond quickly with DevOps tools and Azure resources. | 3 items | devops, incident-response, oncall, azure | +| [diagram-viewer](../plugins/diagram-viewer/README.md) | Render diagrams, click nodes to drill down, and view agent-generated explanations directly in the canvas. | 0 items | architecture-mapping, canvas-navigation, exploratory-analysis, interactive-diagrams, node-drilldown, relationship-visualization | | [doublecheck](../plugins/doublecheck/README.md) | Three-layer verification pipeline for AI output. Extracts claims, finds sources, and flags hallucination risks so humans can verify before acting. | 2 items | verification, hallucination, fact-check, source-citation, trust, safety | | [edge-ai-tasks](../plugins/edge-ai-tasks/README.md) | Task Researcher and Task Planner for intermediate to expert users and large codebases - Brought to you by microsoft/edge-ai | 2 items | architecture, planning, research, tasks, implementation | | [ember](../plugins/ember/README.md) | An AI partner, not a tool. Ember carries fire from person to person โ€” helping humans discover that AI partnership isn't something you learn, it's something you find. | 5 items | ai-partnership, coaching, onboarding, collaboration, storytelling, developer-experience | | [eyeball](../plugins/eyeball/README.md) | Document analysis with inline source screenshots. When you ask Copilot to analyze a document, Eyeball generates a Word doc where every factual claim includes a highlighted screenshot from the source material so you can verify it with your own eyes. | 1 items | document-analysis, citation-verification, screenshot, contracts, legal, trust, visual-verification | | [fastah-ip-geo-tools](../plugins/fastah-ip-geo-tools/README.md) | This plugin is for network operations engineers who wish to tune and publish IP geolocation feeds in RFC 8805 format. It consists of an AI Skill and an associated MCP server that geocodes geolocation place names to real cities for accuracy. | 1 items | geofeed, ip-geolocation, rfc-8805, rfc-9632, network-operations, isp, cloud, hosting, ixp | +| [feedback-themes](../plugins/feedback-themes/README.md) | Explore grouped customer feedback signals by impact and drill into a theme to guide product next steps. | 0 items | customer-feedback, impact-prioritization, product-insights, signal-grouping, theme-analysis, trend-discovery | | [flowstudio-power-automate](../plugins/flowstudio-power-automate/README.md) | Give your AI agent full visibility into Power Automate cloud flows via the FlowStudio MCP server. Connect, debug, build, monitor health, and govern flows at scale โ€” action-level inputs and outputs, not just status codes. | 5 items | power-automate, power-platform, flowstudio, mcp, model-context-protocol, cloud-flows, workflow-automation, monitoring, governance | | [frontend-web-dev](../plugins/frontend-web-dev/README.md) | Essential prompts, instructions, and chat modes for modern frontend web development including React, Angular, Vue, TypeScript, and CSS frameworks. | 4 items | frontend, web, react, typescript, javascript, css, html, angular, vue | | [gem-team](../plugins/gem-team/README.md) | Self-Learning Multi-agent orchestration framework for spec-driven development and automated verification. With smarter tool calling and leaner context. | 0 items | multi-agent, orchestration, tdd, testing, e2e, devops, security-audit, code-review, prd, mobile | +| [gesture-review](../plugins/gesture-review/README.md) | Review pull requests with a live camera feed and approve or reject using thumbs-up/thumbs-down gestures. | 0 items | camera-input, gesture-control, github-prs, hands-free, mediapipe, pull-request-review | | [go-mcp-development](../plugins/go-mcp-development/README.md) | Complete toolkit for building Model Context Protocol (MCP) servers in Go using the official github.com/modelcontextprotocol/go-sdk. Includes instructions for best practices, a prompt for generating servers, and an expert chat mode for guidance. | 2 items | go, golang, mcp, model-context-protocol, server-development, sdk | | [java-development](../plugins/java-development/README.md) | Comprehensive collection of prompts and instructions for Java development including Spring Boot, Quarkus, testing, documentation, and best practices. | 4 items | java, springboot, quarkus, jpa, junit, javadoc | | [java-mcp-development](../plugins/java-mcp-development/README.md) | Complete toolkit for building Model Context Protocol servers in Java using the official MCP Java SDK with reactive streams and Spring Boot integration. | 2 items | java, mcp, model-context-protocol, server-development, sdk, reactive-streams, spring-boot, reactor | +| [java-modernization-studio](../plugins/java-modernization-studio/README.md) | Drive the GitHub Copilot App Modernization for Java workflow from an interactive canvas: environment readiness, repo assessment, prioritized plan and progress, validation gates, and one-click predefined-task runs grounded in the repo's real artifacts. | 0 items | app-modernization, assessment-dashboard, azure-migration, java-modernization, legacy-java, modernization-cockpit, validation-gates | | [kotlin-mcp-development](../plugins/kotlin-mcp-development/README.md) | Complete toolkit for building Model Context Protocol (MCP) servers in Kotlin using the official io.modelcontextprotocol:kotlin-sdk library. Includes instructions for best practices, a prompt for generating servers, and an expert chat mode for guidance. | 2 items | kotlin, mcp, model-context-protocol, kotlin-multiplatform, server-development, ktor | | [mcp-m365-copilot](../plugins/mcp-m365-copilot/README.md) | Comprehensive collection for building declarative agents with Model Context Protocol integration for Microsoft 365 Copilot | 4 items | mcp, m365-copilot, declarative-agents, api-plugins, model-context-protocol, adaptive-cards | | [napkin](../plugins/napkin/README.md) | Visual whiteboard collaboration for Copilot CLI. Opens an interactive whiteboard in your browser where you can draw, sketch, and add sticky notes โ€” then share everything back with Copilot. Copilot sees your drawings and responds with analysis, suggestions, and ideas. | 1 items | whiteboard, visual, collaboration, brainstorming, non-technical, drawing, sticky-notes, accessibility, copilot-cli, ux | @@ -81,18 +92,25 @@ See [CONTRIBUTING.md](../CONTRIBUTING.md#adding-plugins) for guidelines on how t | [python-mcp-development](../plugins/python-mcp-development/README.md) | Complete toolkit for building Model Context Protocol (MCP) servers in Python using the official SDK with FastMCP. Includes instructions for best practices, a prompt for generating servers, and an expert chat mode for guidance. | 2 items | python, mcp, model-context-protocol, fastmcp, server-development | | [react18-upgrade](../plugins/react18-upgrade/README.md) | Enterprise React 18 migration toolkit with specialized agents and skills for upgrading React 16/17 class-component codebases to React 18.3.1. Includes auditor, dependency surgeon, class component migration specialist, automatic batching fixer, and test guardian. | 13 items | react18, react, migration, upgrade, class-components, lifecycle, batching | | [react19-upgrade](../plugins/react19-upgrade/README.md) | Enterprise React 19 migration toolkit with specialized agents and skills for upgrading React 18 codebases to React 19. Includes auditor, dependency surgeon, source code migrator, and test guardian. Handles removal of deprecated APIs including ReactDOM.render, forwardRef, defaultProps, legacy context, string refs, and more. | 8 items | react19, react, migration, upgrade, hooks, modern-react | +| [release-notes-showcase](../plugins/release-notes-showcase/README.md) | Compose and refine launch-ready release notes with contributor callouts and export-friendly output. | 0 items | changelog, contributor-callouts, email-export, launch-summary, product-updates, release-notes | +| [repo-actions-hub](../plugins/repo-actions-hub/README.md) | Browse repository GitHub Actions workflows, inspect recent runs, and trigger manual workflow_dispatch runs from a Copilot canvas. | 0 items | actions, canvas, copilot-extension, github-actions, recent-runs, workflow-dispatch | | [roundup](../plugins/roundup/README.md) | Self-configuring status briefing generator. Learns your communication style from examples, discovers your data sources, and produces draft updates for any audience on demand. | 2 items | status-updates, briefings, management, productivity, communication, synthesis, roundup, copilot-cli | | [ruby-mcp-development](../plugins/ruby-mcp-development/README.md) | Complete toolkit for building Model Context Protocol servers in Ruby using the official MCP Ruby SDK gem with Rails integration support. | 2 items | ruby, mcp, model-context-protocol, server-development, sdk, rails, gem | | [rug-agentic-workflow](../plugins/rug-agentic-workflow/README.md) | Three-agent workflow for orchestrated software delivery with an orchestrator plus implementation and QA subagents. | 3 items | agentic-workflow, orchestration, subagents, software-engineering, qa | | [rust-mcp-development](../plugins/rust-mcp-development/README.md) | Build high-performance Model Context Protocol servers in Rust using the official rmcp SDK with async/await, procedural macros, and type-safe implementations. | 2 items | rust, mcp, model-context-protocol, server-development, sdk, tokio, async, macros, rmcp | | [salesforce-development](../plugins/salesforce-development/README.md) | Complete Salesforce agentic development environment covering Apex & Triggers, Flow automation, Lightning Web Components, Aura components, and Visualforce pages. | 7 items | salesforce, apex, triggers, lwc, aura, flow, visualforce, crm, salesforce-dx | | [security-best-practices](../plugins/security-best-practices/README.md) | Security frameworks, accessibility guidelines, performance optimization, and code quality best practices for building secure, maintainable, and high-performance applications. | 1 items | security, accessibility, performance, code-quality, owasp, a11y, optimization, best-practices | +| [site-studio](../plugins/site-studio/README.md) | Plan, draft, and track a personal website section by section โ€” a shared canvas where you and your agent author content, watch progress, and review every change. | 0 items | agent-collaboration, content-authoring, personal-website, progress-tracking, section-planning, site-builder | | [skill-image-gen](../plugins/skill-image-gen/README.md) | Generate images using AI directly from your coding workflow. Supports OpenAI (gpt-image-2) and Google Gemini. BYO API key โ€” the skill guides you through setup on first use. | 1 items | image-generation, openai, gemini, ai, art, sprites, textures, icons | | [software-engineering-team](../plugins/software-engineering-team/README.md) | 7 specialized agents covering the full software development lifecycle from UX design and architecture to security and DevOps. | 7 items | team, enterprise, security, devops, ux, architecture, product, ai-ethics | | [structured-autonomy](../plugins/structured-autonomy/README.md) | Premium planning, thrifty implementation | 3 items | | | [swift-mcp-development](../plugins/swift-mcp-development/README.md) | Comprehensive collection for building Model Context Protocol servers in Swift using the official MCP Swift SDK with modern concurrency features. | 2 items | swift, mcp, model-context-protocol, server-development, sdk, ios, macos, concurrency, actor, async-await | | [technical-spike](../plugins/technical-spike/README.md) | Tools for creation, management and research of technical spikes to reduce unknowns and assumptions before proceeding to specification and implementation of solutions. | 2 items | technical-spike, assumption-testing, validation, research | | [testing-automation](../plugins/testing-automation/README.md) | Comprehensive collection for writing tests, test automation, and test-driven development including unit tests, integration tests, and end-to-end testing strategies. | 9 items | testing, tdd, automation, unit-tests, integration, playwright, jest, nunit | +| [tiny-tool-town-submitter](../plugins/tiny-tool-town-submitter/README.md) | Inspect a repository, improve Tiny Tool Town readiness, submit its listing issue, and launch remediation work. | 0 items | github-issues, open-source, project-readiness, repository-analysis, submission-workflow, tiny-tool-town | +| [token-pacman](../plugins/token-pacman/README.md) | Visualizes live session AI-credit usage as a Pac-Man board with pellets, ghosts, fruit milestones, and game-over limits. | 0 items | ai-credits, copilot-canvas, interactive-canvas, pac-man, quota-tracking, session-usage | | [typescript-mcp-development](../plugins/typescript-mcp-development/README.md) | Complete toolkit for building Model Context Protocol (MCP) servers in TypeScript/Node.js using the official SDK. Includes instructions for best practices, a prompt for generating servers, and an expert chat mode for guidance. | 2 items | typescript, mcp, model-context-protocol, nodejs, server-development | | [typespec-m365-copilot](../plugins/typespec-m365-copilot/README.md) | Comprehensive collection of prompts, instructions, and resources for building declarative agents and API plugins using TypeSpec for Microsoft 365 Copilot extensibility. | 3 items | typespec, m365-copilot, declarative-agents, api-plugins, agent-development, microsoft-365 | | [visual-pr](../plugins/visual-pr/README.md) | Capture, annotate, and embed screenshots and animated GIF demos in pull request descriptions. Includes Playwright-based UI capture, PIL image annotations, PR embedding workflows for GitHub and Azure DevOps, and screen recording with variable timing. | 4 items | screenshots, pull-request, before-after, annotations, playwright, gif, screen-recording, visual | +| [where-was-i](../plugins/where-was-i/README.md) | Reconstruct your dev context (branch, commits, uncommitted work, PR clues) and trigger a resume prompt to continue quickly. | 0 items | branch-state, developer-context, git-history, interrupt-recovery, pull-request-context, resume-work | +| [work-hub](../plugins/work-hub/README.md) | Generic cross-repo command center canvas for GitHub Copilot with onboarding, focus planning, repo health, work signals, and session cleanup. | 0 items | cross-repo-dashboard, focus-planning, repo-health, session-cleanup, work-triage, workflow-visibility | diff --git a/eng/generate-marketplace.mjs b/eng/generate-marketplace.mjs index 45a54b21cd..3dcbdf3f51 100755 --- a/eng/generate-marketplace.mjs +++ b/eng/generate-marketplace.mjs @@ -6,7 +6,6 @@ import { ROOT_FOLDER } from "./constants.mjs"; import { readExternalPlugins } from "./external-plugin-validation.mjs"; const PLUGINS_DIR = path.join(ROOT_FOLDER, "plugins"); -const EXTENSIONS_DIR = path.join(ROOT_FOLDER, "extensions"); const MARKETPLACE_FILE = path.join(ROOT_FOLDER, ".github/plugin", "marketplace.json"); /** @@ -68,19 +67,12 @@ function collectLocalPluginsFromRoot(rootDir, sourcePrefix, includeEntry = () => function generateMarketplace() { console.log("Generating marketplace.json..."); - if (!fs.existsSync(PLUGINS_DIR) && !fs.existsSync(EXTENSIONS_DIR)) { - console.error(`Error: Neither plugins directory (${PLUGINS_DIR}) nor extensions directory (${EXTENSIONS_DIR}) was found`); + if (!fs.existsSync(PLUGINS_DIR)) { + console.error(`Error: Plugins directory (${PLUGINS_DIR}) was not found`); process.exit(1); } - const plugins = [ - ...collectLocalPluginsFromRoot(PLUGINS_DIR, "plugins"), - ...collectLocalPluginsFromRoot( - EXTENSIONS_DIR, - "extensions", - (entryName) => fs.existsSync(path.join(EXTENSIONS_DIR, entryName, "extension.mjs")) - ) - ]; + const plugins = collectLocalPluginsFromRoot(PLUGINS_DIR, "plugins"); console.log(`Found ${plugins.length} local plugin manifests`); diff --git a/eng/generate-website-data.mjs b/eng/generate-website-data.mjs index 520518af4d..000e46fa59 100755 --- a/eng/generate-website-data.mjs +++ b/eng/generate-website-data.mjs @@ -645,8 +645,6 @@ function resolvePluginItem(item, resourceIndex) { */ function generatePluginsData(gitDates, resourceIndex = {}) { const plugins = []; - const extensionEntriesByName = new Map(); - if (!fs.existsSync(PLUGINS_DIR)) { return { items: [], filters: { tags: [] } }; } @@ -655,62 +653,6 @@ function generatePluginsData(gitDates, resourceIndex = {}) { .readdirSync(PLUGINS_DIR, { withFileTypes: true }) .filter((d) => d.isDirectory()); - if (fs.existsSync(EXTENSIONS_DIR)) { - const extensionDirs = fs.readdirSync(EXTENSIONS_DIR, { withFileTypes: true }) - .filter((entry) => { - if (!entry.isDirectory()) return false; - return fs.existsSync(path.join(EXTENSIONS_DIR, entry.name, "extension.mjs")); - }) - .map((entry) => entry.name) - .sort((a, b) => a.localeCompare(b)); - - for (const extensionDirName of extensionDirs) { - const extensionDir = path.join(EXTENSIONS_DIR, extensionDirName); - const pluginJsonPath = path.join(extensionDir, ".github", "plugin", "plugin.json"); - if (!fs.existsSync(pluginJsonPath)) { - continue; - } - - try { - const extensionPlugin = JSON.parse(fs.readFileSync(pluginJsonPath, "utf-8")); - const pluginName = normalizeText(extensionPlugin.name, extensionDirName); - const pluginDescription = normalizeText(extensionPlugin.description, "Canvas extension"); - const extensionKeywords = Array.isArray(extensionPlugin.keywords) - ? [...new Set(extensionPlugin.keywords.filter((keyword) => typeof keyword === "string").map((keyword) => keyword.trim()).filter(Boolean))].sort((a, b) => a.localeCompare(b)) - : []; - const relPath = `extensions/${extensionDirName}`; - const extensionItem = resolvePluginItem( - { - kind: "extension", - path: relPath, - }, - resourceIndex - ); - const extReadmePath = path.join(extensionDir, "README.md"); - const extReadmeFile = fs.existsSync(extReadmePath) - ? `${relPath}/README.md` - : null; - - extensionEntriesByName.set(pluginName, { - id: pluginName, - name: pluginName, - description: pluginDescription, - path: relPath, - readmeFile: extReadmeFile, - version: normalizeText(extensionPlugin.version, null), - tags: extensionKeywords, - itemCount: 1, - items: [extensionItem], - generatedFromExtension: true, - lastUpdated: getDirectoryLastUpdated(gitDates, relPath), - searchText: `${pluginName} ${pluginDescription} ${extensionKeywords.join(" ")} canvas extension`.toLowerCase(), - }); - } catch (e) { - console.warn(`Failed to parse extension plugin manifest for ${extensionDirName}: ${e.message}`); - } - } - } - for (const dir of pluginDirs) { const pluginDir = path.join(PLUGINS_DIR, dir.name); const jsonPath = path.join(pluginDir, ".github/plugin", "plugin.json"); @@ -720,17 +662,18 @@ function generatePluginsData(gitDates, resourceIndex = {}) { try { const data = JSON.parse(fs.readFileSync(jsonPath, "utf-8")); const relPath = `plugins/${dir.name}`; - const extensionRefs = Array.isArray(data?.["x-awesome-copilot"]?.extensions) - ? data["x-awesome-copilot"].extensions + const extensionReferencesPath = path.join(pluginDir, ".github/plugin/extensions.json"); + const extensionRefs = fs.existsSync(extensionReferencesPath) + ? JSON.parse(fs.readFileSync(extensionReferencesPath, "utf-8")) : []; + if (fs.existsSync(path.join(EXTENSIONS_DIR, dir.name, "extension.mjs")) && !extensionRefs.includes(dir.name)) { + extensionRefs.push(dir.name); + } const extensionItems = extensionRefs - .map((entry) => normalizeText(entry)) - .filter(Boolean) - .map((entry) => entry.replace(/^\.\/+/, "").replace(/\/$/, "")) - .filter((entry) => entry.startsWith("extensions/")) + .filter((entry) => typeof entry === "string") .map((entry) => ({ kind: "extension", - path: entry, + path: `extensions/${entry}`, })); const agentItems = (data.agents || []).flatMap((agent) => { @@ -779,16 +722,11 @@ function generatePluginsData(gitDates, resourceIndex = {}) { searchText: `${pluginName} ${data.description || "" } ${tags.join(" ")}`.toLowerCase(), }); - extensionEntriesByName.delete(pluginName); } catch (e) { console.warn(`Failed to parse plugin: ${dir.name}`, e.message); } } - for (const extensionPlugin of extensionEntriesByName.values()) { - plugins.push(extensionPlugin); - } - // Load external plugins from plugins/external.json const externalJsonPath = path.join(PLUGINS_DIR, "external.json"); if (fs.existsSync(externalJsonPath)) { @@ -1225,14 +1163,8 @@ function resolveExtensionScreenshots(pluginJson, extensionDir, relPath, ref) { copilotNs?.logo ?? pluginJson?.logo, relPath, ref ); - const screenshotConfig = pluginJson?.["x-awesome-copilot"]?.screenshots || {}; - const iconEntry = normalizeExtensionScreenshotRole(screenshotConfig.icon, relPath, ref); - const galleryRaw = screenshotConfig.gallery; - const firstGalleryEntry = Array.isArray(galleryRaw) ? galleryRaw[0] : galleryRaw; - const galleryEntry = normalizeExtensionScreenshotRole(firstGalleryEntry, relPath, ref); - - const finalIcon = iconEntry || logoEntry || inferredIcon; - const finalGallery = galleryEntry || logoEntry || inferredGallery || finalIcon; + const finalIcon = logoEntry || inferredIcon; + const finalGallery = logoEntry || inferredGallery || finalIcon; return { screenshots: { @@ -1281,7 +1213,7 @@ function generateCanvasManifest(gitDates, commitSha) { const packageJson = fs.existsSync(packageJsonPath) ? JSON.parse(fs.readFileSync(packageJsonPath, "utf-8")) : {}; - const pluginJsonPath = path.join(extensionDir, ".github", "plugin", "plugin.json"); + const pluginJsonPath = path.join(PLUGINS_DIR, dir.name, ".github", "plugin", "plugin.json"); const pluginJson = fs.existsSync(pluginJsonPath) ? JSON.parse(fs.readFileSync(pluginJsonPath, "utf-8")) : {}; diff --git a/eng/materialize-plugins.mjs b/eng/materialize-plugins.mjs index 8cdf474428..9ecf65ee89 100644 --- a/eng/materialize-plugins.mjs +++ b/eng/materialize-plugins.mjs @@ -5,6 +5,7 @@ import path from "path"; import { ROOT_FOLDER } from "./constants.mjs"; const PLUGINS_DIR = path.join(ROOT_FOLDER, "plugins"); +const EXTENSIONS_DIR = path.join(ROOT_FOLDER, "extensions"); /** * Recursively copy a directory. @@ -45,6 +46,30 @@ function resolveSource(relPath) { return null; } +function readExtensionReferences(pluginPath, pluginName) { + const referencesPath = path.join(pluginPath, ".github/plugin/extensions.json"); + let references = []; + + if (fs.existsSync(referencesPath)) { + try { + references = JSON.parse(fs.readFileSync(referencesPath, "utf8")); + } catch (err) { + throw new Error(`Failed to parse ${referencesPath}: ${err.message}`); + } + } + + if (!Array.isArray(references) || references.some((name) => typeof name !== "string")) { + throw new Error(`${referencesPath} must contain an array of extension names`); + } + + const names = new Set(references); + if (fs.existsSync(path.join(EXTENSIONS_DIR, pluginName, "extension.mjs"))) { + names.add(pluginName); + } + + return [...names].sort(); +} + function materializePlugins() { console.log("Materializing plugin files...\n"); @@ -124,11 +149,10 @@ function materializePlugins() { } } - // Process extension references from x-awesome-copilot.extensions - const extensionRefs = Array.isArray(metadata?.["x-awesome-copilot"]?.extensions) - ? metadata["x-awesome-copilot"].extensions - : []; - for (const relPath of extensionRefs) { + // Process extension references from the build-only extensions.json file. + const extensionRefs = readExtensionReferences(pluginPath, pluginName); + for (const extensionName of extensionRefs) { + const relPath = `./extensions/${extensionName}`; const src = resolveSource(relPath); if (!src) { console.warn(` โš  ${pluginName}: Unknown extension path format: ${relPath}`); @@ -146,7 +170,7 @@ function materializePlugins() { } // Emit a spec-compliant served manifest for the marketplace branch. - // Source manifests keep non-spec composition fields (agents, skills, x-awesome-copilot) + // Source manifests keep composition fields (agents and skills) // for build tooling. The served manifest retains only Agent Plugins v1.0.0 fields // so the runtime uses conventional directory discovery for all content. const SPEC_FIELDS = new Set(["$schema", "name", "version", "description", "author", diff --git a/eng/validate-plugins.mjs b/eng/validate-plugins.mjs index e4e46308be..816b92f654 100755 --- a/eng/validate-plugins.mjs +++ b/eng/validate-plugins.mjs @@ -165,41 +165,33 @@ function validateSpecPaths(plugin) { return errors; } -function validateCuratedPluginExtensionRefs(plugin) { +function validateExtensionReferences(pluginDir) { const errors = []; - const extensionRefs = plugin?.["x-awesome-copilot"]?.extensions; - if (extensionRefs === undefined) { + const referencesPath = path.join(pluginDir, ".github/plugin/extensions.json"); + if (!fs.existsSync(referencesPath)) { return errors; } - if (!Array.isArray(extensionRefs)) { - errors.push('x-awesome-copilot.extensions must be an array'); + const references = parseJsonFile(referencesPath); + if (references.parseError) { + errors.push(`failed to parse extensions.json: ${references.parseError}`); return errors; } - - if (!arraysEqual(extensionRefs, sortPluginEntries(extensionRefs))) { - errors.push('x-awesome-copilot.extensions must be sorted alphabetically'); + if (!Array.isArray(references)) { + errors.push("extensions.json must contain an array of extension names"); + return errors; + } + if (!arraysEqual(references, sortPluginEntries(references))) { + errors.push("extensions.json entries must be sorted alphabetically"); } - const knownExtensions = new Set(getExtensionFolderNames()); - for (let i = 0; i < extensionRefs.length; i++) { - const ref = extensionRefs[i]; - if (typeof ref !== "string") { - errors.push(`x-awesome-copilot.extensions[${i}] must be a string`); - continue; - } - if (!ref.startsWith("./extensions/")) { - errors.push(`x-awesome-copilot.extensions[${i}] must start with "./extensions/"`); - continue; - } - - const normalized = ref.replace(/^\.\/extensions\//, "").replace(/\/$/, ""); - if (!normalized) { - errors.push(`x-awesome-copilot.extensions[${i}] must include an extension folder name`); + for (const [index, name] of references.entries()) { + if (typeof name !== "string" || !/^[a-z0-9][a-z0-9.-]*[a-z0-9]$|^[a-z0-9]$/.test(name)) { + errors.push(`extensions.json[${index}] must be a valid extension name`); continue; } - if (!knownExtensions.has(normalized)) { - errors.push(`x-awesome-copilot.extensions[${i}] source not found: extensions/${normalized}`); + if (!fs.existsSync(path.join(EXTENSIONS_DIR, name, "extension.mjs"))) { + errors.push(`extensions.json[${index}] source not found: extensions/${name}`); } } @@ -210,6 +202,8 @@ function validatePlugin(folderName) { const pluginDir = path.join(PLUGINS_DIR, folderName); const errors = []; let parsedPlugin = null; + const extensionDir = path.join(EXTENSIONS_DIR, folderName); + const isExtensionPlugin = fs.existsSync(path.join(extensionDir, "extension.mjs")); // Rule 1: Must have .github/plugin/plugin.json const pluginJsonPath = path.join(pluginDir, ".github/plugin", "plugin.json"); @@ -220,7 +214,7 @@ function validatePlugin(folderName) { // Rule 2: Must have README.md const readmePath = path.join(pluginDir, "README.md"); - if (!fs.existsSync(readmePath)) { + if (!fs.existsSync(readmePath) && !isExtensionPlugin) { errors.push("missing required file: README.md"); } @@ -257,9 +251,19 @@ function validatePlugin(folderName) { const specErrors = validateSpecPaths(plugin); errors.push(...specErrors); - const extensionRefErrors = validateCuratedPluginExtensionRefs(plugin); + const extensionRefErrors = validateExtensionReferences(pluginDir); errors.push(...extensionRefErrors); + if (isExtensionPlugin) { + const extension = plugin.extensions; + const namespace = extension?.[COPILOT_NAMESPACE]; + if (!namespace || namespace.logo !== "assets/preview.png") { + errors.push(`extensions["${COPILOT_NAMESPACE}"].logo must be exactly "assets/preview.png" for extension plugins`); + } else { + validateExtensionScreenshotPath(extensionDir, namespace.logo, `extensions["${COPILOT_NAMESPACE}"].logo`, errors); + } + } + return { errors, plugin: parsedPlugin }; } @@ -276,76 +280,6 @@ function validateExtensionScreenshotPath(extensionDir, pathValue, fieldName, err } } -function validateExtensionManifest(folderName) { - const extensionDir = path.join(EXTENSIONS_DIR, folderName); - const errors = []; - let parsedPlugin = null; - - const pluginJsonPath = path.join(extensionDir, ".github/plugin", "plugin.json"); - if (!fs.existsSync(pluginJsonPath)) { - errors.push("missing required file: .github/plugin/plugin.json"); - return { errors, plugin: parsedPlugin }; - } - - const parsed = parseJsonFile(pluginJsonPath); - if (parsed.parseError) { - errors.push(`failed to parse plugin.json: ${parsed.parseError}`); - return { errors, plugin: parsedPlugin }; - } - - parsedPlugin = parsed; - - // $schema required - const schemaError = validateSchema(parsed); - if (schemaError) errors.push(schemaError); - - const nameErrors = validateName(parsed.name, folderName); - errors.push(...nameErrors); - - const descError = validateDescription(parsed.description); - if (descError) errors.push(descError); - - const versionError = validateVersion(parsed.version); - if (versionError) errors.push(versionError); - - const keywordsError = validateKeywords(parsed.keywords ?? parsed.tags); - if (keywordsError) errors.push(keywordsError); - - // Extension convention: top-level logo must NOT be present (moved into namespace) - if (parsed.logo !== undefined) { - errors.push('top-level "logo" must not be present โ€” use extensions["com.github.copilot"].logo instead'); - } - - // Extension convention: x-awesome-copilot must not be present - if (parsed["x-awesome-copilot"] !== undefined) { - errors.push("x-awesome-copilot field must not be present"); - } - - // Extension convention: extensions must be an object with com.github.copilot namespace - const ext = parsed.extensions; - if (ext === undefined || ext === null) { - errors.push(`extensions field is required and must be an object with a "${COPILOT_NAMESPACE}" key`); - } else if (typeof ext !== "object" || Array.isArray(ext) || typeof ext === "string") { - errors.push(`extensions must be an object keyed by reverse-domain namespace (e.g. "${COPILOT_NAMESPACE}")`); - } else { - const ns = ext[COPILOT_NAMESPACE]; - if (ns === undefined) { - errors.push(`extensions["${COPILOT_NAMESPACE}"] is required`); - } else if (typeof ns !== "object" || Array.isArray(ns)) { - errors.push(`extensions["${COPILOT_NAMESPACE}"] must be an object`); - } else { - // Validate logo inside the namespace - if (ns.logo !== "assets/preview.png") { - errors.push(`extensions["${COPILOT_NAMESPACE}"].logo must be exactly "assets/preview.png"`); - } else { - validateExtensionScreenshotPath(extensionDir, ns.logo, `extensions["${COPILOT_NAMESPACE}"].logo`, errors); - } - } - } - - return { errors, plugin: parsedPlugin }; -} - // Main validation function function validatePlugins() { const pluginDirs = fs.existsSync(PLUGINS_DIR) @@ -353,15 +287,12 @@ function validatePlugins() { .filter((d) => d.isDirectory()) .map((d) => d.name) : []; - const extensionDirs = getExtensionFolderNames(); - - if (pluginDirs.length === 0 && extensionDirs.length === 0) { - console.log("No plugins or extension plugin manifests found - validation skipped"); + if (pluginDirs.length === 0) { + console.log("No plugin manifests found - validation skipped"); return true; } console.log(`Validating ${pluginDirs.length} plugins...\n`); - console.log(`Validating ${extensionDirs.length} extensions as plugin sources...\n`); let hasErrors = false; const seenNames = new Set(); @@ -391,30 +322,11 @@ function validatePlugins() { } } - if (extensionDirs.length > 0) { - console.log(""); - } - - for (const dir of extensionDirs) { - console.log(`Validating extension ${dir}...`); - const { errors, plugin } = validateExtensionManifest(dir); - - if (errors.length > 0) { - console.error(`โŒ extension ${dir}:`); - errors.forEach((e) => console.error(` - ${e}`)); + for (const dir of getExtensionFolderNames()) { + const pluginJsonPath = path.join(PLUGINS_DIR, dir, ".github/plugin/plugin.json"); + if (!fs.existsSync(pluginJsonPath)) { + console.error(`โŒ extension ${dir}: missing plugin manifest at plugins/${dir}/.github/plugin/plugin.json`); hasErrors = true; - } else { - console.log(`โœ… extension ${dir} is valid`); - } - - if (plugin?.name) { - if (seenNames.has(plugin.name)) { - console.error(`โŒ Duplicate plugin name "${plugin.name}"`); - hasErrors = true; - } else { - seenNames.add(plugin.name); - localPluginNames.push(plugin.name); - } } } @@ -435,7 +347,7 @@ function validatePlugins() { } if (!hasErrors) { - console.log(`\nโœ… All ${pluginDirs.length} plugins, ${extensionDirs.length} extensions, and the external catalog are valid`); + console.log(`\nโœ… All ${pluginDirs.length} plugins and the external catalog are valid`); } return !hasErrors; diff --git a/extensions/accessibility-kanban/.github/plugin/plugin.json b/plugins/accessibility-kanban/.github/plugin/plugin.json similarity index 100% rename from extensions/accessibility-kanban/.github/plugin/plugin.json rename to plugins/accessibility-kanban/.github/plugin/plugin.json diff --git a/extensions/apng-studio/.github/plugin/plugin.json b/plugins/apng-studio/.github/plugin/plugin.json similarity index 100% rename from extensions/apng-studio/.github/plugin/plugin.json rename to plugins/apng-studio/.github/plugin/plugin.json diff --git a/extensions/arcade-canvas/.github/plugin/plugin.json b/plugins/arcade-canvas/.github/plugin/plugin.json similarity index 100% rename from extensions/arcade-canvas/.github/plugin/plugin.json rename to plugins/arcade-canvas/.github/plugin/plugin.json diff --git a/extensions/backlog-swipe-triage/.github/plugin/plugin.json b/plugins/backlog-swipe-triage/.github/plugin/plugin.json similarity index 100% rename from extensions/backlog-swipe-triage/.github/plugin/plugin.json rename to plugins/backlog-swipe-triage/.github/plugin/plugin.json diff --git a/extensions/chromium-control-canvas/.github/plugin/plugin.json b/plugins/chromium-control-canvas/.github/plugin/plugin.json similarity index 100% rename from extensions/chromium-control-canvas/.github/plugin/plugin.json rename to plugins/chromium-control-canvas/.github/plugin/plugin.json diff --git a/extensions/color-orb/.github/plugin/plugin.json b/plugins/color-orb/.github/plugin/plugin.json similarity index 100% rename from extensions/color-orb/.github/plugin/plugin.json rename to plugins/color-orb/.github/plugin/plugin.json diff --git a/extensions/connector-namespaces/.github/plugin/plugin.json b/plugins/connector-namespaces/.github/plugin/plugin.json similarity index 100% rename from extensions/connector-namespaces/.github/plugin/plugin.json rename to plugins/connector-namespaces/.github/plugin/plugin.json diff --git a/extensions/diagram-viewer/.github/plugin/plugin.json b/plugins/diagram-viewer/.github/plugin/plugin.json similarity index 100% rename from extensions/diagram-viewer/.github/plugin/plugin.json rename to plugins/diagram-viewer/.github/plugin/plugin.json diff --git a/extensions/feedback-themes/.github/plugin/plugin.json b/plugins/feedback-themes/.github/plugin/plugin.json similarity index 100% rename from extensions/feedback-themes/.github/plugin/plugin.json rename to plugins/feedback-themes/.github/plugin/plugin.json diff --git a/extensions/gesture-review/.github/plugin/plugin.json b/plugins/gesture-review/.github/plugin/plugin.json similarity index 100% rename from extensions/gesture-review/.github/plugin/plugin.json rename to plugins/gesture-review/.github/plugin/plugin.json diff --git a/extensions/java-modernization-studio/.github/plugin/plugin.json b/plugins/java-modernization-studio/.github/plugin/plugin.json similarity index 100% rename from extensions/java-modernization-studio/.github/plugin/plugin.json rename to plugins/java-modernization-studio/.github/plugin/plugin.json diff --git a/extensions/release-notes-showcase/.github/plugin/plugin.json b/plugins/release-notes-showcase/.github/plugin/plugin.json similarity index 100% rename from extensions/release-notes-showcase/.github/plugin/plugin.json rename to plugins/release-notes-showcase/.github/plugin/plugin.json diff --git a/extensions/repo-actions-hub/.github/plugin/plugin.json b/plugins/repo-actions-hub/.github/plugin/plugin.json similarity index 100% rename from extensions/repo-actions-hub/.github/plugin/plugin.json rename to plugins/repo-actions-hub/.github/plugin/plugin.json diff --git a/extensions/site-studio/.github/plugin/plugin.json b/plugins/site-studio/.github/plugin/plugin.json similarity index 100% rename from extensions/site-studio/.github/plugin/plugin.json rename to plugins/site-studio/.github/plugin/plugin.json diff --git a/extensions/tiny-tool-town-submitter/.github/plugin/plugin.json b/plugins/tiny-tool-town-submitter/.github/plugin/plugin.json similarity index 100% rename from extensions/tiny-tool-town-submitter/.github/plugin/plugin.json rename to plugins/tiny-tool-town-submitter/.github/plugin/plugin.json diff --git a/extensions/token-pacman/.github/plugin/plugin.json b/plugins/token-pacman/.github/plugin/plugin.json similarity index 100% rename from extensions/token-pacman/.github/plugin/plugin.json rename to plugins/token-pacman/.github/plugin/plugin.json diff --git a/extensions/where-was-i/.github/plugin/plugin.json b/plugins/where-was-i/.github/plugin/plugin.json similarity index 100% rename from extensions/where-was-i/.github/plugin/plugin.json rename to plugins/where-was-i/.github/plugin/plugin.json diff --git a/extensions/work-hub/.github/plugin/plugin.json b/plugins/work-hub/.github/plugin/plugin.json similarity index 100% rename from extensions/work-hub/.github/plugin/plugin.json rename to plugins/work-hub/.github/plugin/plugin.json From d1c9386bcf862be8aebc033cb7b4e12c42652442 Mon Sep 17 00:00:00 2001 From: Aaron Powell Date: Wed, 5 Aug 2026 10:46:33 +1000 Subject: [PATCH 3/8] feat: add canvas extension scaffolding skill - Add repo-local skill for creating canvas extension sources - Generate spec-compliant plugin manifests under plugins/ - Support registering reusable extensions with multiple plugins - Remove guidance for extension-local plugin manifests and custom fields Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8f3a88cb-e01e-4760-8125-460490dc1a76 --- .../skills/create-canvas-extension/SKILL.md | 120 ++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 .github/skills/create-canvas-extension/SKILL.md diff --git a/.github/skills/create-canvas-extension/SKILL.md b/.github/skills/create-canvas-extension/SKILL.md new file mode 100644 index 0000000000..2d94189761 --- /dev/null +++ b/.github/skills/create-canvas-extension/SKILL.md @@ -0,0 +1,120 @@ +--- +name: create-canvas-extension +description: 'Create or register a canvas extension in the awesome-copilot repository. Use when asked to scaffold a new canvas extension, create its plugin.json, add a reusable extension to one or more plugins, or migrate extension metadata. Extensions are reusable source under extensions/; shippable plugin manifests belong under plugins/.' +argument-hint: '[optional extension name or description]' +--- + +# Create a canvas extension + +Use this skill only for the `github/awesome-copilot` repository. Canvas extensions are reusable source components. They do not have a `plugin.json` under `extensions/`. + +## Required decisions + +Before creating files, ask for each missing value: + +1. **Extension ID**: lowercase kebab-case, matching the source folder and plugin name. +2. **Display metadata**: + - description + - version (default `1.0.0`) + - author name and optional URL + - keywords (lowercase, hyphenated, maximum 10) + - repository and license (default to the repository URL and `MIT` when appropriate) +3. **Canvas entrypoint**: confirm whether the extension already has `extension.mjs`. If not, create a minimal entrypoint only when the user provides enough implementation details; otherwise create the directory and leave an explicit TODO. +4. **Preview image**: obtain an existing `assets/preview.png` path or ask the user to add it. Do not invent a binary image or silently use a misleading placeholder. +5. **Plugin registration**: + - For a standalone installable canvas plugin, create `plugins/`. + - For an extension that belongs to an existing plugin, ask for the parent plugin ID and add the extension ID to that plugin's `.github/plugin/extensions.json`. + - If the extension should be shipped by multiple plugins, collect all plugin IDs and add the same extension ID to each mapping file. + +## Files to create + +For a new extension plugin, create this structure: + +```text +extensions// +โ”œโ”€โ”€ extension.mjs +โ””โ”€โ”€ assets/ + โ””โ”€โ”€ preview.png + +plugins// +โ”œโ”€โ”€ .github/ +โ”‚ โ””โ”€โ”€ plugin/ +โ”‚ โ””โ”€โ”€ plugin.json +โ””โ”€โ”€ README.md +``` + +The extension source may contain additional files such as `package.json`, canvas assets, or supporting modules. Keep all reusable implementation files under `extensions//`. + +Create `plugins//.github/plugin/plugin.json` with this shape: + +```json +{ + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", + "name": "", + "description": "", + "version": "1.0.0", + "author": { + "name": "" + }, + "repository": "https://github.com/github/awesome-copilot", + "license": "MIT", + "keywords": [ + "" + ], + "extensions": { + "com.github.copilot": { + "logo": "assets/preview.png" + } + } +} +``` + +The manifest must contain only Agent Plugins spec fields. Do not add `x-awesome-copilot`, `standalone`, or other repository-specific fields. + +For an existing parent plugin, create or update: + +```text +plugins//.github/plugin/extensions.json +``` + +Its contents must be a sorted JSON array of extension IDs: + +```json +[ + "" +] +``` + +Do not copy the extension source into the parent plugin. Materialization resolves the IDs from the root `extensions/` directory, so the same source can be bundled by multiple plugins. + +## Workflow + +1. Inspect the repository before editing: + - confirm `extensions/` and `plugins/` do not already conflict + - inspect the target parent plugin, if any + - check whether a preview image and entrypoint already exist +2. Ask only the missing required questions from the decisions above. +3. Create the source and plugin directories with the required files. +4. If creating a new entrypoint, keep it minimal and clearly mark implementation TODOs rather than fabricating behavior. +5. Add or update `extensions.json` for every parent plugin that should ship the extension. Keep IDs alphabetically sorted and unique. +6. Ensure there is no `extensions//.github/plugin/plugin.json`. +7. Run: + + ```bash + npm run plugin:validate + npm run build + npm run website:data + ``` + +8. Report the created paths, the plugins that ship the extension, and any missing user-provided assets or TODOs. + +## Existing extension migration + +When migrating an existing extension: + +1. Move its `.github/plugin/plugin.json` to `plugins//.github/plugin/plugin.json`. +2. Update the manifest to the namespace-based `extensions.com.github.copilot.logo` shape. +3. Remove the old manifest from `extensions/`. +4. Register the extension in any parent plugin's `.github/plugin/extensions.json`. +5. Run the validation and build commands above. + From 5423fddcd95904166f3aa3f6cc3f88afd2ba3d4b Mon Sep 17 00:00:00 2001 From: Aaron Powell Date: Wed, 5 Aug 2026 11:08:50 +1000 Subject: [PATCH 4/8] fix: align extension namespaces with current guidance - Use each extension ID as its manifest namespace key - Update validation and website generation to resolve extension-specific namespaces - Upsert plugin validation PR comments using the existing repository pattern Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8f3a88cb-e01e-4760-8125-460490dc1a76 --- .github/workflows/validate-plugins.yml | 41 +++++++++++++------ eng/generate-website-data.mjs | 4 +- eng/validate-plugins.mjs | 6 +-- .../.github/plugin/plugin.json | 2 +- .../apng-studio/.github/plugin/plugin.json | 2 +- .../arcade-canvas/.github/plugin/plugin.json | 2 +- .../.github/plugin/plugin.json | 2 +- .../.github/plugin/plugin.json | 2 +- plugins/color-orb/.github/plugin/plugin.json | 2 +- .../.github/plugin/plugin.json | 2 +- .../diagram-viewer/.github/plugin/plugin.json | 2 +- .../.github/plugin/plugin.json | 2 +- .../gesture-review/.github/plugin/plugin.json | 2 +- .../.github/plugin/plugin.json | 2 +- .../.github/plugin/plugin.json | 2 +- .../.github/plugin/plugin.json | 2 +- .../site-studio/.github/plugin/plugin.json | 2 +- .../.github/plugin/plugin.json | 2 +- .../token-pacman/.github/plugin/plugin.json | 2 +- .../where-was-i/.github/plugin/plugin.json | 2 +- plugins/work-hub/.github/plugin/plugin.json | 2 +- 21 files changed, 52 insertions(+), 35 deletions(-) diff --git a/.github/workflows/validate-plugins.yml b/.github/workflows/validate-plugins.yml index 2b5c500ab6..be74fb767b 100644 --- a/.github/workflows/validate-plugins.yml +++ b/.github/workflows/validate-plugins.yml @@ -37,7 +37,9 @@ jobs: uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0 with: script: | + const marker = ''; const body = [ + marker, '๐Ÿ›‘ **Plugin/extension validation failed**', '', 'One or more plugins or extensions in this PR do not pass spec validation.', @@ -45,21 +47,34 @@ jobs: 'All internal plugins and extensions must include:', '- `"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json"` in `plugin.json`', '- A valid `name`, `description`, and `version`', - '- For **extensions**: `extensions["com.github.copilot"].logo` set to `"assets/preview.png"`', + '- For **extensions**: `extensions[""].logo` set to `"assets/preview.png"`', '', 'Run `npm run plugin:validate` locally to see the full list of errors.', ].join('\n'); - const isFork = context.payload.pull_request.head.repo.fork; - if (!isFork) { - try { - await github.rest.issues.createComment({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: context.issue.number, - body, - }); - } catch (error) { - core.warning(`Could not post PR comment: ${error.message}`); - } + const { data: comments } = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + per_page: 100, + }); + + const existing = comments.find((comment) => comment.body.includes(marker)); + + if (existing) { + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: existing.id, + body, + }); + console.log(`Updated existing validation comment ${existing.id}`); + } else { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body, + }); + console.log('Created validation comment'); } diff --git a/eng/generate-website-data.mjs b/eng/generate-website-data.mjs index 000e46fa59..c60f2b0e34 100755 --- a/eng/generate-website-data.mjs +++ b/eng/generate-website-data.mjs @@ -1158,7 +1158,9 @@ function resolveExtensionScreenshots(pluginJson, extensionDir, relPath, ref) { } : null; - const copilotNs = pluginJson?.extensions?.["com.github.copilot"]; + const extensionNamespace = path.basename(extensionDir); + const copilotNs = pluginJson?.extensions?.[extensionNamespace] + ?? pluginJson?.extensions?.["com.github.copilot"]; const logoEntry = normalizeExtensionScreenshotRole( copilotNs?.logo ?? pluginJson?.logo, relPath, ref diff --git a/eng/validate-plugins.mjs b/eng/validate-plugins.mjs index 816b92f654..807f6fe379 100755 --- a/eng/validate-plugins.mjs +++ b/eng/validate-plugins.mjs @@ -256,11 +256,11 @@ function validatePlugin(folderName) { if (isExtensionPlugin) { const extension = plugin.extensions; - const namespace = extension?.[COPILOT_NAMESPACE]; + const namespace = extension?.[folderName]; if (!namespace || namespace.logo !== "assets/preview.png") { - errors.push(`extensions["${COPILOT_NAMESPACE}"].logo must be exactly "assets/preview.png" for extension plugins`); + errors.push(`extensions["${folderName}"].logo must be exactly "assets/preview.png" for extension plugins`); } else { - validateExtensionScreenshotPath(extensionDir, namespace.logo, `extensions["${COPILOT_NAMESPACE}"].logo`, errors); + validateExtensionScreenshotPath(extensionDir, namespace.logo, `extensions["${folderName}"].logo`, errors); } } diff --git a/plugins/accessibility-kanban/.github/plugin/plugin.json b/plugins/accessibility-kanban/.github/plugin/plugin.json index b183ff0dfc..56489086f1 100644 --- a/plugins/accessibility-kanban/.github/plugin/plugin.json +++ b/plugins/accessibility-kanban/.github/plugin/plugin.json @@ -16,7 +16,7 @@ "status-tracking" ], "extensions": { - "com.github.copilot": { + "accessibility-kanban": { "logo": "assets/preview.png" } } diff --git a/plugins/apng-studio/.github/plugin/plugin.json b/plugins/apng-studio/.github/plugin/plugin.json index 60df82c73b..279b43cf82 100644 --- a/plugins/apng-studio/.github/plugin/plugin.json +++ b/plugins/apng-studio/.github/plugin/plugin.json @@ -16,7 +16,7 @@ "interactive-canvas" ], "extensions": { - "com.github.copilot": { + "apng-studio": { "logo": "assets/preview.png" } } diff --git a/plugins/arcade-canvas/.github/plugin/plugin.json b/plugins/arcade-canvas/.github/plugin/plugin.json index d758f0df7e..c55a4db509 100644 --- a/plugins/arcade-canvas/.github/plugin/plugin.json +++ b/plugins/arcade-canvas/.github/plugin/plugin.json @@ -16,7 +16,7 @@ "session-breaks" ], "extensions": { - "com.github.copilot": { + "arcade-canvas": { "logo": "assets/preview.png" } } diff --git a/plugins/backlog-swipe-triage/.github/plugin/plugin.json b/plugins/backlog-swipe-triage/.github/plugin/plugin.json index f8789b1573..9ff07b9c26 100644 --- a/plugins/backlog-swipe-triage/.github/plugin/plugin.json +++ b/plugins/backlog-swipe-triage/.github/plugin/plugin.json @@ -16,7 +16,7 @@ "workflow-automation" ], "extensions": { - "com.github.copilot": { + "backlog-swipe-triage": { "logo": "assets/preview.png" } } diff --git a/plugins/chromium-control-canvas/.github/plugin/plugin.json b/plugins/chromium-control-canvas/.github/plugin/plugin.json index 71240f245e..3effa2f2eb 100644 --- a/plugins/chromium-control-canvas/.github/plugin/plugin.json +++ b/plugins/chromium-control-canvas/.github/plugin/plugin.json @@ -17,7 +17,7 @@ "web-navigation" ], "extensions": { - "com.github.copilot": { + "chromium-control-canvas": { "logo": "assets/preview.png" } } diff --git a/plugins/color-orb/.github/plugin/plugin.json b/plugins/color-orb/.github/plugin/plugin.json index 7c8c9160b8..940a72c075 100644 --- a/plugins/color-orb/.github/plugin/plugin.json +++ b/plugins/color-orb/.github/plugin/plugin.json @@ -16,7 +16,7 @@ "visual-feedback" ], "extensions": { - "com.github.copilot": { + "color-orb": { "logo": "assets/preview.png" } } diff --git a/plugins/connector-namespaces/.github/plugin/plugin.json b/plugins/connector-namespaces/.github/plugin/plugin.json index a2655fdafe..4573948503 100644 --- a/plugins/connector-namespaces/.github/plugin/plugin.json +++ b/plugins/connector-namespaces/.github/plugin/plugin.json @@ -16,7 +16,7 @@ "tool-discovery" ], "extensions": { - "com.github.copilot": { + "connector-namespaces": { "logo": "assets/preview.png" } } diff --git a/plugins/diagram-viewer/.github/plugin/plugin.json b/plugins/diagram-viewer/.github/plugin/plugin.json index 1d2d655de4..c303d5a91f 100644 --- a/plugins/diagram-viewer/.github/plugin/plugin.json +++ b/plugins/diagram-viewer/.github/plugin/plugin.json @@ -16,7 +16,7 @@ "relationship-visualization" ], "extensions": { - "com.github.copilot": { + "diagram-viewer": { "logo": "assets/preview.png" } } diff --git a/plugins/feedback-themes/.github/plugin/plugin.json b/plugins/feedback-themes/.github/plugin/plugin.json index 1af10065e7..3340c62cf9 100644 --- a/plugins/feedback-themes/.github/plugin/plugin.json +++ b/plugins/feedback-themes/.github/plugin/plugin.json @@ -16,7 +16,7 @@ "trend-discovery" ], "extensions": { - "com.github.copilot": { + "feedback-themes": { "logo": "assets/preview.png" } } diff --git a/plugins/gesture-review/.github/plugin/plugin.json b/plugins/gesture-review/.github/plugin/plugin.json index 0690e7992c..fdf69afa76 100644 --- a/plugins/gesture-review/.github/plugin/plugin.json +++ b/plugins/gesture-review/.github/plugin/plugin.json @@ -16,7 +16,7 @@ "pull-request-review" ], "extensions": { - "com.github.copilot": { + "gesture-review": { "logo": "assets/preview.png" } } diff --git a/plugins/java-modernization-studio/.github/plugin/plugin.json b/plugins/java-modernization-studio/.github/plugin/plugin.json index def49b9f3b..b847560f3e 100644 --- a/plugins/java-modernization-studio/.github/plugin/plugin.json +++ b/plugins/java-modernization-studio/.github/plugin/plugin.json @@ -17,7 +17,7 @@ "validation-gates" ], "extensions": { - "com.github.copilot": { + "java-modernization-studio": { "logo": "assets/preview.png" } } diff --git a/plugins/release-notes-showcase/.github/plugin/plugin.json b/plugins/release-notes-showcase/.github/plugin/plugin.json index 82a0d1e278..af4f26a1c6 100644 --- a/plugins/release-notes-showcase/.github/plugin/plugin.json +++ b/plugins/release-notes-showcase/.github/plugin/plugin.json @@ -16,7 +16,7 @@ "release-notes" ], "extensions": { - "com.github.copilot": { + "release-notes-showcase": { "logo": "assets/preview.png" } } diff --git a/plugins/repo-actions-hub/.github/plugin/plugin.json b/plugins/repo-actions-hub/.github/plugin/plugin.json index 4ac6f8bf19..0239a95631 100644 --- a/plugins/repo-actions-hub/.github/plugin/plugin.json +++ b/plugins/repo-actions-hub/.github/plugin/plugin.json @@ -16,7 +16,7 @@ "workflow-dispatch" ], "extensions": { - "com.github.copilot": { + "repo-actions-hub": { "logo": "assets/preview.png" } } diff --git a/plugins/site-studio/.github/plugin/plugin.json b/plugins/site-studio/.github/plugin/plugin.json index eaec31ec69..65fcb92b39 100644 --- a/plugins/site-studio/.github/plugin/plugin.json +++ b/plugins/site-studio/.github/plugin/plugin.json @@ -16,7 +16,7 @@ "site-builder" ], "extensions": { - "com.github.copilot": { + "site-studio": { "logo": "assets/preview.png" } } diff --git a/plugins/tiny-tool-town-submitter/.github/plugin/plugin.json b/plugins/tiny-tool-town-submitter/.github/plugin/plugin.json index 9de9d54708..d5ba0c6127 100644 --- a/plugins/tiny-tool-town-submitter/.github/plugin/plugin.json +++ b/plugins/tiny-tool-town-submitter/.github/plugin/plugin.json @@ -16,7 +16,7 @@ "tiny-tool-town" ], "extensions": { - "com.github.copilot": { + "tiny-tool-town-submitter": { "logo": "assets/preview.png" } } diff --git a/plugins/token-pacman/.github/plugin/plugin.json b/plugins/token-pacman/.github/plugin/plugin.json index 00877988b3..29e8b2e1dc 100644 --- a/plugins/token-pacman/.github/plugin/plugin.json +++ b/plugins/token-pacman/.github/plugin/plugin.json @@ -16,7 +16,7 @@ "session-usage" ], "extensions": { - "com.github.copilot": { + "token-pacman": { "logo": "assets/preview.png" } } diff --git a/plugins/where-was-i/.github/plugin/plugin.json b/plugins/where-was-i/.github/plugin/plugin.json index a28623af13..2c49336c79 100644 --- a/plugins/where-was-i/.github/plugin/plugin.json +++ b/plugins/where-was-i/.github/plugin/plugin.json @@ -16,7 +16,7 @@ "resume-work" ], "extensions": { - "com.github.copilot": { + "where-was-i": { "logo": "assets/preview.png" } } diff --git a/plugins/work-hub/.github/plugin/plugin.json b/plugins/work-hub/.github/plugin/plugin.json index 04af5d030b..b0882440cc 100644 --- a/plugins/work-hub/.github/plugin/plugin.json +++ b/plugins/work-hub/.github/plugin/plugin.json @@ -16,7 +16,7 @@ "workflow-visibility" ], "extensions": { - "com.github.copilot": { + "work-hub": { "logo": "assets/preview.png" } } From d6274b262b8bbf6de270526dd90c254b96d27fd4 Mon Sep 17 00:00:00 2001 From: Aaron Powell Date: Wed, 5 Aug 2026 11:14:36 +1000 Subject: [PATCH 5/8] fix: use Copilot extension namespace - Adopt com.github.copilot for all canvas extension manifests - Require the namespace during validation and website generation - Update extension scaffolding guidance Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8f3a88cb-e01e-4760-8125-460490dc1a76 --- .github/skills/create-canvas-extension/SKILL.md | 1 - eng/generate-website-data.mjs | 4 +--- eng/validate-plugins.mjs | 6 +++--- plugins/accessibility-kanban/.github/plugin/plugin.json | 2 +- plugins/apng-studio/.github/plugin/plugin.json | 2 +- plugins/arcade-canvas/.github/plugin/plugin.json | 2 +- plugins/backlog-swipe-triage/.github/plugin/plugin.json | 2 +- plugins/chromium-control-canvas/.github/plugin/plugin.json | 2 +- plugins/color-orb/.github/plugin/plugin.json | 2 +- plugins/connector-namespaces/.github/plugin/plugin.json | 2 +- plugins/diagram-viewer/.github/plugin/plugin.json | 2 +- plugins/feedback-themes/.github/plugin/plugin.json | 2 +- plugins/gesture-review/.github/plugin/plugin.json | 2 +- .../java-modernization-studio/.github/plugin/plugin.json | 2 +- plugins/release-notes-showcase/.github/plugin/plugin.json | 2 +- plugins/repo-actions-hub/.github/plugin/plugin.json | 2 +- plugins/site-studio/.github/plugin/plugin.json | 2 +- plugins/tiny-tool-town-submitter/.github/plugin/plugin.json | 2 +- plugins/token-pacman/.github/plugin/plugin.json | 2 +- plugins/where-was-i/.github/plugin/plugin.json | 2 +- plugins/work-hub/.github/plugin/plugin.json | 2 +- 21 files changed, 22 insertions(+), 25 deletions(-) diff --git a/.github/skills/create-canvas-extension/SKILL.md b/.github/skills/create-canvas-extension/SKILL.md index 2d94189761..7fb46993a5 100644 --- a/.github/skills/create-canvas-extension/SKILL.md +++ b/.github/skills/create-canvas-extension/SKILL.md @@ -117,4 +117,3 @@ When migrating an existing extension: 3. Remove the old manifest from `extensions/`. 4. Register the extension in any parent plugin's `.github/plugin/extensions.json`. 5. Run the validation and build commands above. - diff --git a/eng/generate-website-data.mjs b/eng/generate-website-data.mjs index c60f2b0e34..000e46fa59 100755 --- a/eng/generate-website-data.mjs +++ b/eng/generate-website-data.mjs @@ -1158,9 +1158,7 @@ function resolveExtensionScreenshots(pluginJson, extensionDir, relPath, ref) { } : null; - const extensionNamespace = path.basename(extensionDir); - const copilotNs = pluginJson?.extensions?.[extensionNamespace] - ?? pluginJson?.extensions?.["com.github.copilot"]; + const copilotNs = pluginJson?.extensions?.["com.github.copilot"]; const logoEntry = normalizeExtensionScreenshotRole( copilotNs?.logo ?? pluginJson?.logo, relPath, ref diff --git a/eng/validate-plugins.mjs b/eng/validate-plugins.mjs index 807f6fe379..816b92f654 100755 --- a/eng/validate-plugins.mjs +++ b/eng/validate-plugins.mjs @@ -256,11 +256,11 @@ function validatePlugin(folderName) { if (isExtensionPlugin) { const extension = plugin.extensions; - const namespace = extension?.[folderName]; + const namespace = extension?.[COPILOT_NAMESPACE]; if (!namespace || namespace.logo !== "assets/preview.png") { - errors.push(`extensions["${folderName}"].logo must be exactly "assets/preview.png" for extension plugins`); + errors.push(`extensions["${COPILOT_NAMESPACE}"].logo must be exactly "assets/preview.png" for extension plugins`); } else { - validateExtensionScreenshotPath(extensionDir, namespace.logo, `extensions["${folderName}"].logo`, errors); + validateExtensionScreenshotPath(extensionDir, namespace.logo, `extensions["${COPILOT_NAMESPACE}"].logo`, errors); } } diff --git a/plugins/accessibility-kanban/.github/plugin/plugin.json b/plugins/accessibility-kanban/.github/plugin/plugin.json index 56489086f1..b183ff0dfc 100644 --- a/plugins/accessibility-kanban/.github/plugin/plugin.json +++ b/plugins/accessibility-kanban/.github/plugin/plugin.json @@ -16,7 +16,7 @@ "status-tracking" ], "extensions": { - "accessibility-kanban": { + "com.github.copilot": { "logo": "assets/preview.png" } } diff --git a/plugins/apng-studio/.github/plugin/plugin.json b/plugins/apng-studio/.github/plugin/plugin.json index 279b43cf82..60df82c73b 100644 --- a/plugins/apng-studio/.github/plugin/plugin.json +++ b/plugins/apng-studio/.github/plugin/plugin.json @@ -16,7 +16,7 @@ "interactive-canvas" ], "extensions": { - "apng-studio": { + "com.github.copilot": { "logo": "assets/preview.png" } } diff --git a/plugins/arcade-canvas/.github/plugin/plugin.json b/plugins/arcade-canvas/.github/plugin/plugin.json index c55a4db509..d758f0df7e 100644 --- a/plugins/arcade-canvas/.github/plugin/plugin.json +++ b/plugins/arcade-canvas/.github/plugin/plugin.json @@ -16,7 +16,7 @@ "session-breaks" ], "extensions": { - "arcade-canvas": { + "com.github.copilot": { "logo": "assets/preview.png" } } diff --git a/plugins/backlog-swipe-triage/.github/plugin/plugin.json b/plugins/backlog-swipe-triage/.github/plugin/plugin.json index 9ff07b9c26..f8789b1573 100644 --- a/plugins/backlog-swipe-triage/.github/plugin/plugin.json +++ b/plugins/backlog-swipe-triage/.github/plugin/plugin.json @@ -16,7 +16,7 @@ "workflow-automation" ], "extensions": { - "backlog-swipe-triage": { + "com.github.copilot": { "logo": "assets/preview.png" } } diff --git a/plugins/chromium-control-canvas/.github/plugin/plugin.json b/plugins/chromium-control-canvas/.github/plugin/plugin.json index 3effa2f2eb..71240f245e 100644 --- a/plugins/chromium-control-canvas/.github/plugin/plugin.json +++ b/plugins/chromium-control-canvas/.github/plugin/plugin.json @@ -17,7 +17,7 @@ "web-navigation" ], "extensions": { - "chromium-control-canvas": { + "com.github.copilot": { "logo": "assets/preview.png" } } diff --git a/plugins/color-orb/.github/plugin/plugin.json b/plugins/color-orb/.github/plugin/plugin.json index 940a72c075..7c8c9160b8 100644 --- a/plugins/color-orb/.github/plugin/plugin.json +++ b/plugins/color-orb/.github/plugin/plugin.json @@ -16,7 +16,7 @@ "visual-feedback" ], "extensions": { - "color-orb": { + "com.github.copilot": { "logo": "assets/preview.png" } } diff --git a/plugins/connector-namespaces/.github/plugin/plugin.json b/plugins/connector-namespaces/.github/plugin/plugin.json index 4573948503..a2655fdafe 100644 --- a/plugins/connector-namespaces/.github/plugin/plugin.json +++ b/plugins/connector-namespaces/.github/plugin/plugin.json @@ -16,7 +16,7 @@ "tool-discovery" ], "extensions": { - "connector-namespaces": { + "com.github.copilot": { "logo": "assets/preview.png" } } diff --git a/plugins/diagram-viewer/.github/plugin/plugin.json b/plugins/diagram-viewer/.github/plugin/plugin.json index c303d5a91f..1d2d655de4 100644 --- a/plugins/diagram-viewer/.github/plugin/plugin.json +++ b/plugins/diagram-viewer/.github/plugin/plugin.json @@ -16,7 +16,7 @@ "relationship-visualization" ], "extensions": { - "diagram-viewer": { + "com.github.copilot": { "logo": "assets/preview.png" } } diff --git a/plugins/feedback-themes/.github/plugin/plugin.json b/plugins/feedback-themes/.github/plugin/plugin.json index 3340c62cf9..1af10065e7 100644 --- a/plugins/feedback-themes/.github/plugin/plugin.json +++ b/plugins/feedback-themes/.github/plugin/plugin.json @@ -16,7 +16,7 @@ "trend-discovery" ], "extensions": { - "feedback-themes": { + "com.github.copilot": { "logo": "assets/preview.png" } } diff --git a/plugins/gesture-review/.github/plugin/plugin.json b/plugins/gesture-review/.github/plugin/plugin.json index fdf69afa76..0690e7992c 100644 --- a/plugins/gesture-review/.github/plugin/plugin.json +++ b/plugins/gesture-review/.github/plugin/plugin.json @@ -16,7 +16,7 @@ "pull-request-review" ], "extensions": { - "gesture-review": { + "com.github.copilot": { "logo": "assets/preview.png" } } diff --git a/plugins/java-modernization-studio/.github/plugin/plugin.json b/plugins/java-modernization-studio/.github/plugin/plugin.json index b847560f3e..def49b9f3b 100644 --- a/plugins/java-modernization-studio/.github/plugin/plugin.json +++ b/plugins/java-modernization-studio/.github/plugin/plugin.json @@ -17,7 +17,7 @@ "validation-gates" ], "extensions": { - "java-modernization-studio": { + "com.github.copilot": { "logo": "assets/preview.png" } } diff --git a/plugins/release-notes-showcase/.github/plugin/plugin.json b/plugins/release-notes-showcase/.github/plugin/plugin.json index af4f26a1c6..82a0d1e278 100644 --- a/plugins/release-notes-showcase/.github/plugin/plugin.json +++ b/plugins/release-notes-showcase/.github/plugin/plugin.json @@ -16,7 +16,7 @@ "release-notes" ], "extensions": { - "release-notes-showcase": { + "com.github.copilot": { "logo": "assets/preview.png" } } diff --git a/plugins/repo-actions-hub/.github/plugin/plugin.json b/plugins/repo-actions-hub/.github/plugin/plugin.json index 0239a95631..4ac6f8bf19 100644 --- a/plugins/repo-actions-hub/.github/plugin/plugin.json +++ b/plugins/repo-actions-hub/.github/plugin/plugin.json @@ -16,7 +16,7 @@ "workflow-dispatch" ], "extensions": { - "repo-actions-hub": { + "com.github.copilot": { "logo": "assets/preview.png" } } diff --git a/plugins/site-studio/.github/plugin/plugin.json b/plugins/site-studio/.github/plugin/plugin.json index 65fcb92b39..eaec31ec69 100644 --- a/plugins/site-studio/.github/plugin/plugin.json +++ b/plugins/site-studio/.github/plugin/plugin.json @@ -16,7 +16,7 @@ "site-builder" ], "extensions": { - "site-studio": { + "com.github.copilot": { "logo": "assets/preview.png" } } diff --git a/plugins/tiny-tool-town-submitter/.github/plugin/plugin.json b/plugins/tiny-tool-town-submitter/.github/plugin/plugin.json index d5ba0c6127..9de9d54708 100644 --- a/plugins/tiny-tool-town-submitter/.github/plugin/plugin.json +++ b/plugins/tiny-tool-town-submitter/.github/plugin/plugin.json @@ -16,7 +16,7 @@ "tiny-tool-town" ], "extensions": { - "tiny-tool-town-submitter": { + "com.github.copilot": { "logo": "assets/preview.png" } } diff --git a/plugins/token-pacman/.github/plugin/plugin.json b/plugins/token-pacman/.github/plugin/plugin.json index 29e8b2e1dc..00877988b3 100644 --- a/plugins/token-pacman/.github/plugin/plugin.json +++ b/plugins/token-pacman/.github/plugin/plugin.json @@ -16,7 +16,7 @@ "session-usage" ], "extensions": { - "token-pacman": { + "com.github.copilot": { "logo": "assets/preview.png" } } diff --git a/plugins/where-was-i/.github/plugin/plugin.json b/plugins/where-was-i/.github/plugin/plugin.json index 2c49336c79..a28623af13 100644 --- a/plugins/where-was-i/.github/plugin/plugin.json +++ b/plugins/where-was-i/.github/plugin/plugin.json @@ -16,7 +16,7 @@ "resume-work" ], "extensions": { - "where-was-i": { + "com.github.copilot": { "logo": "assets/preview.png" } } diff --git a/plugins/work-hub/.github/plugin/plugin.json b/plugins/work-hub/.github/plugin/plugin.json index b0882440cc..04af5d030b 100644 --- a/plugins/work-hub/.github/plugin/plugin.json +++ b/plugins/work-hub/.github/plugin/plugin.json @@ -16,7 +16,7 @@ "workflow-visibility" ], "extensions": { - "work-hub": { + "com.github.copilot": { "logo": "assets/preview.png" } } From 43734826a7383644243e836464d9c5b4b0cc3f64 Mon Sep 17 00:00:00 2001 From: Aaron Powell Date: Wed, 5 Aug 2026 11:21:41 +1000 Subject: [PATCH 6/8] docs: regenerate plugin catalog after merge Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8f3a88cb-e01e-4760-8125-460490dc1a76 --- docs/README.plugins.md | 122 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 121 insertions(+), 1 deletion(-) diff --git a/docs/README.plugins.md b/docs/README.plugins.md index 729a2c4359..1f701e30e0 100644 --- a/docs/README.plugins.md +++ b/docs/README.plugins.md @@ -1 +1,121 @@ -# ๐Ÿ”Œ PluginsCurated plugins of related agents and skills organized around specific themes, workflows, or use cases. Plugins can be installed directly via GitHub Copilot CLI or VS Code.> **Awesome Copilot is a default plugin marketplace** โ€” no setup required in either Copilot CLI or VS Code.### How to ContributeSee [CONTRIBUTING.md](../CONTRIBUTING.md#adding-plugins) for guidelines on how to contribute new plugins, improve existing ones, and share your use cases.### How to Use Plugins**Browse Plugins:**- โญ Featured plugins are highlighted and appear at the top of the list- Explore themed plugins that group related customizations- Each plugin includes agents and skills for specific workflows- Plugins make it easy to adopt comprehensive toolkits for particular scenarios**Find & Install in Copilot CLI:**- Browse the marketplace from within an interactive Copilot session: \`/plugin marketplace browse awesome-copilot\`- Install a plugin: \`copilot plugin install @awesome-copilot\`**Find & Install in VS Code:**- Open the Extensions search view and type \`@agentPlugins\` to browse available plugins- Or open the Command Palette and run \`Chat: Plugins\`- Published marketplace manifest (tool-facing): `https://raw.githubusercontent.com/github/awesome-copilot/marketplace/.github/plugin/marketplace.json`- Source plugin content (human-authored): `https://github.com/github/awesome-copilot/tree/main/plugins`| Name | Description | Items | Tags || ---- | ----------- | ----- | ---- || [accessibility-kanban](../plugins/accessibility-kanban/README.md) | Kanban board to manage accessibility issues, allow you to plan, track, and complete remediation work. | 0 items | accessibility, github-issues, issue-triage, kanban-board, planning-workflow, status-tracking || [acreadiness-cockpit](../plugins/acreadiness-cockpit/README.md) | Drive Microsoft AgentRC from Copilot chat: assess AI readiness, generate Copilot instructions (flat or nested with applyTo globs for monorepos), and manage policies. Produces a self-contained static HTML dashboard at reports/index.html. | 4 items | agentrc, ai-readiness, copilot-instructions, readiness-report, monorepo, policy, dashboard || [ai-team-orchestration](../plugins/ai-team-orchestration/README.md) | Bootstrap and run a multi-agent AI development team with named roles (Producer, Dev Team, QA). Sprint planning, brainstorm prompts with distinct agent voices, cross-chat context survival, and parallel team workflows. Based on a proven template that shipped a 30-game app in 5 days with zero human-written code. | 4 items | ai-team, multi-agent, sprint-planning, brainstorm, project-management, orchestration, developer-workflow || [apng-studio](../plugins/apng-studio/README.md) | Interactive GitHub Copilot app canvas extension for building Animated PNG (APNG) files from frames. Draw or upload frames, tune per-frame timing and compositing, preview live, send the result to your phone by QR, and export an animated .png. | 0 items | animated-png, apng, copilot-canvas, frame-animation, image-export, interactive-canvas || [arcade-canvas](../plugins/arcade-canvas/README.md) | Play five retro Phaser mini-games in a Copilot canvas while agents work. | 0 items | arcade-games, copilot-canvas, interactive-canvas, phaser, retro-games, session-breaks || [arch](../plugins/arch/README.md) | Architecture and modernization toolkit: produce a cited architecture document for a locally-cloned repo, and generate a phased modernization plan that auto-runs Documentation mode when needed. | 1 items | architecture, modernization, documentation, migration, onboarding || [arize-ax](../plugins/arize-ax/README.md) | Arize AX platform skills for LLM observability, evaluation, and optimization. Includes trace export, instrumentation, datasets, experiments, evaluators, AI provider integrations, annotations, prompt optimization, and deep linking to the Arize UI. | 9 items | arize, llm, observability, tracing, evaluation, instrumentation, datasets, experiments, prompt-optimization || [automate-this](../plugins/automate-this/README.md) | Record your screen doing a manual process, drop the video on your Desktop, and let Copilot CLI analyze it frame-by-frame to build working automation scripts. Supports narrated recordings with audio transcription. | 1 items | automation, screen-recording, workflow, video-analysis, process-automation, scripting, productivity, copilot-cli || [awesome-copilot](../plugins/awesome-copilot/README.md) | Meta prompts that help you discover and generate curated GitHub Copilot agents, instructions, prompts, and skills. | 4 items | github-copilot, discovery, meta, prompt-engineering, agents || [aws-cloud-development](../plugins/aws-cloud-development/README.md) | Comprehensive AWS cloud development tools including Infrastructure as Code, serverless functions, architecture patterns, and cost optimization for building scalable cloud applications. | 8 items | aws, cloud, infrastructure, cloudformation, terraform, serverless, architecture, devops, cdk || [azure-cloud-development](../plugins/azure-cloud-development/README.md) | Comprehensive Azure cloud development tools including Infrastructure as Code, serverless functions, architecture patterns, and cost optimization for building scalable cloud applications. | 11 items | azure, cloud, infrastructure, bicep, terraform, serverless, architecture, devops || [backlog-swipe-triage](../plugins/backlog-swipe-triage/README.md) | Quickly swipe through backlog issues to triage decisions like assign, needs-info, defer, close, or ignore. | 0 items | agent-assignment, backlog-triage, github-issues, issue-prioritization, swipe-interface, workflow-automation || [cast-imaging](../plugins/cast-imaging/README.md) | A comprehensive collection of specialized agents for software analysis, impact assessment, structural quality advisories, and architectural review using CAST Imaging. | 3 items | cast-imaging, software-analysis, architecture, quality, impact-analysis, devops || [chromium-control-canvas](../plugins/chromium-control-canvas/README.md) | Opens a real Chromium window you can navigate and interact with from a Copilot canvas control panel and agent actions. | 0 items | browser-control, chromium-browser, interactive-canvas, playwright-automation, screenshots, ui-testing, web-navigation || [clojure-interactive-programming](../plugins/clojure-interactive-programming/README.md) | Tools for REPL-first Clojure workflows featuring Clojure instructions, the interactive programming chat mode and supporting guidance. | 2 items | clojure, repl, interactive-programming || [cms-development](../plugins/cms-development/README.md) | Skills for CMS development across themes, plugins, admin tooling, media workflows, markdown rendering, and static export pipelines. | 3 items | cms, content-management-system, wordpress, shopify, drupal, theme, plugin, media, static-site || [color-orb](../plugins/color-orb/README.md) | A visual orb that users can ask the agent to recolor while showing a live activity log in the canvas. | 0 items | agent-actions, color-picker, interactive-demo, realtime-updates, sse-events, visual-feedback || [connector-namespaces](../plugins/connector-namespaces/README.md) | Browse, connect, and open MCP connectors from an Azure Connector Namespace. | 0 items | azure, connector-namespace, mcp, mcp-connectors, model-context-protocol, tool-discovery || [context-engineering](../plugins/context-engineering/README.md) | Tools and techniques for maximizing GitHub Copilot effectiveness through better context management. Includes guidelines for structuring code, an agent for planning multi-file changes, and prompts for context-aware development. | 4 items | context, productivity, refactoring, best-practices, architecture || [context-matic](../plugins/context-matic/README.md) | Coding agents hallucinate APIs. ContextMatic gives them curated, versioned API and SDK docs. Ask your agent to "integrate the payments API" and it guesses โ€” falling back on outdated training data and generic patterns that don't match your actual SDK. ContextMatic solves this by giving the agent deterministic, version-aware, SDK-native context at the exact moment it's needed. | 2 items | api-context, api-integration, mcp, sdk, apimatic, third-party-apis, sdks || [convert-to-md](../plugins/convert-to-md/README.md) | A collection of Copilot skills that convert common document formats into Markdown so their contents can be accurately analyzed, summarized, searched, or extracted from. Just tell Copilot what you need โ€” the right skill is invoked automatically and the conversion happens behind the scenes. | 3 items | skills, configuration, copilot, convert-word-to-md, convert-excel-to-md, convert-pdf-to-md || [copilot-sdk](../plugins/copilot-sdk/README.md) | Build applications with the GitHub Copilot SDK across multiple programming languages. Includes comprehensive instructions for C#, Go, Node.js/TypeScript, and Python to help you create AI-powered applications. | 1 items | copilot-sdk, sdk, csharp, go, nodejs, typescript, python, ai, github-copilot || [csharp-dotnet-development](../plugins/csharp-dotnet-development/README.md) | Essential prompts, instructions, and chat modes for C# and .NET development including testing, documentation, and best practices. | 9 items | csharp, dotnet, aspnet, testing || [database-data-management](../plugins/database-data-management/README.md) | Database administration, SQL optimization, and data management tools for PostgreSQL, SQL Server, and general database development best practices. | 6 items | database, sql, postgresql, sql-server, dba, optimization, queries, data-management || [dataverse-sdk-for-python](../plugins/dataverse-sdk-for-python/README.md) | Comprehensive collection for building production-ready Python integrations with Microsoft Dataverse. Includes official documentation, best practices, advanced features, file operations, and code generation prompts. | 4 items | dataverse, python, integration, sdk || [devops-oncall](../plugins/devops-oncall/README.md) | A focused set of prompts, instructions, and a chat mode to help triage incidents and respond quickly with DevOps tools and Azure resources. | 3 items | devops, incident-response, oncall, azure || [diagram-viewer](../plugins/diagram-viewer/README.md) | Render diagrams, click nodes to drill down, and view agent-generated explanations directly in the canvas. | 0 items | architecture-mapping, canvas-navigation, exploratory-analysis, interactive-diagrams, node-drilldown, relationship-visualization || [doublecheck](../plugins/doublecheck/README.md) | Three-layer verification pipeline for AI output. Extracts claims, finds sources, and flags hallucination risks so humans can verify before acting. | 2 items | verification, hallucination, fact-check, source-citation, trust, safety || [edge-ai-tasks](../plugins/edge-ai-tasks/README.md) | Task Researcher and Task Planner for intermediate to expert users and large codebases - Brought to you by microsoft/edge-ai | 2 items | architecture, planning, research, tasks, implementation || [ember](../plugins/ember/README.md) | An AI partner, not a tool. Ember carries fire from person to person โ€” helping humans discover that AI partnership isn't something you learn, it's something you find. | 5 items | ai-partnership, coaching, onboarding, collaboration, storytelling, developer-experience || [eyeball](../plugins/eyeball/README.md) | Document analysis with inline source screenshots. When you ask Copilot to analyze a document, Eyeball generates a Word doc where every factual claim includes a highlighted screenshot from the source material so you can verify it with your own eyes. | 1 items | document-analysis, citation-verification, screenshot, contracts, legal, trust, visual-verification || [fastah-ip-geo-tools](../plugins/fastah-ip-geo-tools/README.md) | This plugin is for network operations engineers who wish to tune and publish IP geolocation feeds in RFC 8805 format. It consists of an AI Skill and an associated MCP server that geocodes geolocation place names to real cities for accuracy. | 1 items | geofeed, ip-geolocation, rfc-8805, rfc-9632, network-operations, isp, cloud, hosting, ixp || [feedback-themes](../plugins/feedback-themes/README.md) | Explore grouped customer feedback signals by impact and drill into a theme to guide product next steps. | 0 items | customer-feedback, impact-prioritization, product-insights, signal-grouping, theme-analysis, trend-discovery || [flowstudio-power-automate](../plugins/flowstudio-power-automate/README.md) | Give your AI agent full visibility into Power Automate cloud flows via the FlowStudio MCP server. Connect, debug, build, monitor health, and govern flows at scale โ€” action-level inputs and outputs, not just status codes. | 5 items | power-automate, power-platform, flowstudio, mcp, model-context-protocol, cloud-flows, workflow-automation, monitoring, governance || [frontend-web-dev](../plugins/frontend-web-dev/README.md) | Essential prompts, instructions, and chat modes for modern frontend web development including React, Angular, Vue, TypeScript, and CSS frameworks. | 4 items | frontend, web, react, typescript, javascript, css, html, angular, vue || [gem-team](../plugins/gem-team/README.md) | Self-Learning Multi-agent orchestration framework for spec-driven development and automated verification. With smarter tool calling and leaner context. | 0 items | multi-agent, orchestration, tdd, testing, e2e, devops, security-audit, code-review, prd, mobile || [gesture-review](../plugins/gesture-review/README.md) | Review pull requests with a live camera feed and approve or reject using thumbs-up/thumbs-down gestures. | 0 items | camera-input, gesture-control, github-prs, hands-free, mediapipe, pull-request-review || [go-mcp-development](../plugins/go-mcp-development/README.md) | Complete toolkit for building Model Context Protocol (MCP) servers in Go using the official github.com/modelcontextprotocol/go-sdk. Includes instructions for best practices, a prompt for generating servers, and an expert chat mode for guidance. | 2 items | go, golang, mcp, model-context-protocol, server-development, sdk || [java-development](../plugins/java-development/README.md) | Comprehensive collection of prompts and instructions for Java development including Spring Boot, Quarkus, testing, documentation, and best practices. | 4 items | java, springboot, quarkus, jpa, junit, javadoc || [java-mcp-development](../plugins/java-mcp-development/README.md) | Complete toolkit for building Model Context Protocol servers in Java using the official MCP Java SDK with reactive streams and Spring Boot integration. | 2 items | java, mcp, model-context-protocol, server-development, sdk, reactive-streams, spring-boot, reactor || [java-modernization-studio](../plugins/java-modernization-studio/README.md) | Drive the GitHub Copilot App Modernization for Java workflow from an interactive canvas: environment readiness, repo assessment, prioritized plan and progress, validation gates, and one-click predefined-task runs grounded in the repo's real artifacts. | 0 items | app-modernization, assessment-dashboard, azure-migration, java-modernization, legacy-java, modernization-cockpit, validation-gates || [kotlin-mcp-development](../plugins/kotlin-mcp-development/README.md) | Complete toolkit for building Model Context Protocol (MCP) servers in Kotlin using the official io.modelcontextprotocol:kotlin-sdk library. Includes instructions for best practices, a prompt for generating servers, and an expert chat mode for guidance. | 2 items | kotlin, mcp, model-context-protocol, kotlin-multiplatform, server-development, ktor || [mcp-m365-copilot](../plugins/mcp-m365-copilot/README.md) | Comprehensive collection for building declarative agents with Model Context Protocol integration for Microsoft 365 Copilot | 4 items | mcp, m365-copilot, declarative-agents, api-plugins, model-context-protocol, adaptive-cards || [napkin](../plugins/napkin/README.md) | Visual whiteboard collaboration for Copilot CLI. Opens an interactive whiteboard in your browser where you can draw, sketch, and add sticky notes โ€” then share everything back with Copilot. Copilot sees your drawings and responds with analysis, suggestions, and ideas. | 1 items | whiteboard, visual, collaboration, brainstorming, non-technical, drawing, sticky-notes, accessibility, copilot-cli, ux || [noob-mode](../plugins/noob-mode/README.md) | Plain-English translation layer for non-technical Copilot CLI users. Translates every approval prompt, error message, and technical output into clear, jargon-free English with color-coded risk indicators. | 1 items | accessibility, plain-english, non-technical, beginner, translation, copilot-cli, ux || [openapi-to-application-csharp-dotnet](../plugins/openapi-to-application-csharp-dotnet/README.md) | Generate production-ready .NET applications from OpenAPI specifications. Includes ASP.NET Core project scaffolding, controller generation, entity framework integration, and C# best practices. | 2 items | openapi, code-generation, api, csharp, dotnet, aspnet || [openapi-to-application-go](../plugins/openapi-to-application-go/README.md) | Generate production-ready Go applications from OpenAPI specifications. Includes project scaffolding, handler generation, middleware setup, and Go best practices for REST APIs. | 2 items | openapi, code-generation, api, go, golang || [openapi-to-application-java-spring-boot](../plugins/openapi-to-application-java-spring-boot/README.md) | Generate production-ready Spring Boot applications from OpenAPI specifications. Includes project scaffolding, REST controller generation, service layer organization, and Spring Boot best practices. | 2 items | openapi, code-generation, api, java, spring-boot || [openapi-to-application-nodejs-nestjs](../plugins/openapi-to-application-nodejs-nestjs/README.md) | Generate production-ready NestJS applications from OpenAPI specifications. Includes project scaffolding, controller and service generation, TypeScript best practices, and enterprise patterns. | 2 items | openapi, code-generation, api, nodejs, typescript, nestjs || [openapi-to-application-python-fastapi](../plugins/openapi-to-application-python-fastapi/README.md) | Generate production-ready FastAPI applications from OpenAPI specifications. Includes project scaffolding, route generation, dependency injection, and Python best practices for async APIs. | 2 items | openapi, code-generation, api, python, fastapi || [oracle-to-postgres-migration-expert](../plugins/oracle-to-postgres-migration-expert/README.md) | Expert agent for Oracle-to-PostgreSQL application migrations in .NET solutions. Performs code edits, runs commands, and invokes extension tools to migrate .NET/Oracle data access patterns to PostgreSQL. | 8 items | oracle, postgresql, database-migration, dotnet, sql, migration, integration-testing, stored-procedures || [ospo-sponsorship](../plugins/ospo-sponsorship/README.md) | Tools and resources for Open Source Program Offices (OSPOs) to identify, evaluate, and manage sponsorship of open source dependencies through GitHub Sponsors, Open Collective, and other funding platforms. | 1 items | || [partners](../plugins/partners/README.md) | Custom agents that have been created by GitHub partners | 20 items | devops, security, database, cloud, infrastructure, observability, feature-flags, cicd, migration, performance || [pcf-development](../plugins/pcf-development/README.md) | Complete toolkit for developing custom code components using Power Apps Component Framework for model-driven and canvas apps | 0 items | power-apps, pcf, component-framework, typescript, power-platform || [phoenix](../plugins/phoenix/README.md) | Phoenix AI observability skills for LLM application debugging, evaluation, and tracing. Includes CLI debugging tools, LLM evaluation workflows, and OpenInference tracing instrumentation. | 3 items | phoenix, arize, llm, observability, tracing, evaluation, openinference, instrumentation || [php-mcp-development](../plugins/php-mcp-development/README.md) | Comprehensive resources for building Model Context Protocol servers using the official PHP SDK with attribute-based discovery, including best practices, project generation, and expert assistance | 2 items | php, mcp, model-context-protocol, server-development, sdk, attributes, composer || [power-apps-code-apps](../plugins/power-apps-code-apps/README.md) | Complete toolkit for Power Apps Code Apps development including project scaffolding, development standards, and expert guidance for building code-first applications with Power Platform integration. | 2 items | power-apps, power-platform, typescript, react, code-apps, dataverse, connectors || [power-bi-development](../plugins/power-bi-development/README.md) | Comprehensive Power BI development resources including data modeling, DAX optimization, performance tuning, visualization design, security best practices, and DevOps/ALM guidance for building enterprise-grade Power BI solutions. | 8 items | power-bi, dax, data-modeling, performance, visualization, security, devops, business-intelligence || [power-platform-architect](../plugins/power-platform-architect/README.md) | Solution Architect for the Microsoft Power Platform, turning business requirements into functioning Power Platform solution architectures. | 1 items | power-platform, power-platform-architect, power-apps, dataverse, power-automate, power-pages, power-bi || [power-platform-mcp-connector-development](../plugins/power-platform-mcp-connector-development/README.md) | Complete toolkit for developing Power Platform custom connectors with Model Context Protocol integration for Microsoft Copilot Studio | 3 items | power-platform, mcp, copilot-studio, custom-connector, json-rpc || [project-documenter](../plugins/project-documenter/README.md) | Generate professional project documentation with draw.io architecture diagrams and Word (.docx) output with embedded images. Automatically discovers any project's technology stack and produces Markdown, diagrams, PNG exports, and a formatted Word document. | 3 items | documentation, architecture-diagrams, drawio, word-document, docx, png-images, c4-model, project-summary, auto-discovery || [project-planning](../plugins/project-planning/README.md) | Tools and guidance for software project planning, feature breakdown, epic management, implementation planning, and task organization for development teams. | 15 items | planning, project-management, epic, feature, implementation, task, architecture, technical-spike || [python-mcp-development](../plugins/python-mcp-development/README.md) | Complete toolkit for building Model Context Protocol (MCP) servers in Python using the official SDK with FastMCP. Includes instructions for best practices, a prompt for generating servers, and an expert chat mode for guidance. | 2 items | python, mcp, model-context-protocol, fastmcp, server-development || [react18-upgrade](../plugins/react18-upgrade/README.md) | Enterprise React 18 migration toolkit with specialized agents and skills for upgrading React 16/17 class-component codebases to React 18.3.1. Includes auditor, dependency surgeon, class component migration specialist, automatic batching fixer, and test guardian. | 13 items | react18, react, migration, upgrade, class-components, lifecycle, batching || [react19-upgrade](../plugins/react19-upgrade/README.md) | Enterprise React 19 migration toolkit with specialized agents and skills for upgrading React 18 codebases to React 19. Includes auditor, dependency surgeon, source code migrator, and test guardian. Handles removal of deprecated APIs including ReactDOM.render, forwardRef, defaultProps, legacy context, string refs, and more. | 8 items | react19, react, migration, upgrade, hooks, modern-react || [release-notes-showcase](../plugins/release-notes-showcase/README.md) | Compose and refine launch-ready release notes with contributor callouts and export-friendly output. | 0 items | changelog, contributor-callouts, email-export, launch-summary, product-updates, release-notes || [repo-actions-hub](../plugins/repo-actions-hub/README.md) | Browse repository GitHub Actions workflows, inspect recent runs, and trigger manual workflow_dispatch runs from a Copilot canvas. | 0 items | actions, canvas, copilot-extension, github-actions, recent-runs, workflow-dispatch || [roundup](../plugins/roundup/README.md) | Self-configuring status briefing generator. Learns your communication style from examples, discovers your data sources, and produces draft updates for any audience on demand. | 2 items | status-updates, briefings, management, productivity, communication, synthesis, roundup, copilot-cli || [ruby-mcp-development](../plugins/ruby-mcp-development/README.md) | Complete toolkit for building Model Context Protocol servers in Ruby using the official MCP Ruby SDK gem with Rails integration support. | 2 items | ruby, mcp, model-context-protocol, server-development, sdk, rails, gem || [rug-agentic-workflow](../plugins/rug-agentic-workflow/README.md) | Three-agent workflow for orchestrated software delivery with an orchestrator plus implementation and QA subagents. | 3 items | agentic-workflow, orchestration, subagents, software-engineering, qa || [rust-mcp-development](../plugins/rust-mcp-development/README.md) | Build high-performance Model Context Protocol servers in Rust using the official rmcp SDK with async/await, procedural macros, and type-safe implementations. | 2 items | rust, mcp, model-context-protocol, server-development, sdk, tokio, async, macros, rmcp || [salesforce-development](../plugins/salesforce-development/README.md) | Complete Salesforce agentic development environment covering Apex & Triggers, Flow automation, Lightning Web Components, Aura components, and Visualforce pages. | 7 items | salesforce, apex, triggers, lwc, aura, flow, visualforce, crm, salesforce-dx || [security-best-practices](../plugins/security-best-practices/README.md) | Security frameworks, accessibility guidelines, performance optimization, and code quality best practices for building secure, maintainable, and high-performance applications. | 1 items | security, accessibility, performance, code-quality, owasp, a11y, optimization, best-practices || [site-studio](../plugins/site-studio/README.md) | Plan, draft, and track a personal website section by section โ€” a shared canvas where you and your agent author content, watch progress, and review every change. | 0 items | agent-collaboration, content-authoring, personal-website, progress-tracking, section-planning, site-builder || [skill-image-gen](../plugins/skill-image-gen/README.md) | Generate images using AI directly from your coding workflow. Supports OpenAI (gpt-image-2) and Google Gemini. BYO API key โ€” the skill guides you through setup on first use. | 1 items | image-generation, openai, gemini, ai, art, sprites, textures, icons || [software-engineering-team](../plugins/software-engineering-team/README.md) | 7 specialized agents covering the full software development lifecycle from UX design and architecture to security and DevOps. | 7 items | team, enterprise, security, devops, ux, architecture, product, ai-ethics || [structured-autonomy](../plugins/structured-autonomy/README.md) | Premium planning, thrifty implementation | 3 items | || [swift-mcp-development](../plugins/swift-mcp-development/README.md) | Comprehensive collection for building Model Context Protocol servers in Swift using the official MCP Swift SDK with modern concurrency features. | 2 items | swift, mcp, model-context-protocol, server-development, sdk, ios, macos, concurrency, actor, async-await || [technical-spike](../plugins/technical-spike/README.md) | Tools for creation, management and research of technical spikes to reduce unknowns and assumptions before proceeding to specification and implementation of solutions. | 2 items | technical-spike, assumption-testing, validation, research || [testing-automation](../plugins/testing-automation/README.md) | Comprehensive collection for writing tests, test automation, and test-driven development including unit tests, integration tests, and end-to-end testing strategies. | 9 items | testing, tdd, automation, unit-tests, integration, playwright, jest, nunit || [tiny-tool-town-submitter](../plugins/tiny-tool-town-submitter/README.md) | Inspect a repository, improve Tiny Tool Town readiness, submit its listing issue, and launch remediation work. | 0 items | github-issues, open-source, project-readiness, repository-analysis, submission-workflow, tiny-tool-town || [token-pacman](../plugins/token-pacman/README.md) | Visualizes live session AI-credit usage as a Pac-Man board with pellets, ghosts, fruit milestones, and game-over limits. | 0 items | ai-credits, copilot-canvas, interactive-canvas, pac-man, quota-tracking, session-usage || [typescript-mcp-development](../plugins/typescript-mcp-development/README.md) | Complete toolkit for building Model Context Protocol (MCP) servers in TypeScript/Node.js using the official SDK. Includes instructions for best practices, a prompt for generating servers, and an expert chat mode for guidance. | 2 items | typescript, mcp, model-context-protocol, nodejs, server-development || [typespec-m365-copilot](../plugins/typespec-m365-copilot/README.md) | Comprehensive collection of prompts, instructions, and resources for building declarative agents and API plugins using TypeSpec for Microsoft 365 Copilot extensibility. | 3 items | typespec, m365-copilot, declarative-agents, api-plugins, agent-development, microsoft-365 || [visual-pr](../plugins/visual-pr/README.md) | Capture, annotate, and embed screenshots and animated GIF demos in pull request descriptions. Includes Playwright-based UI capture, PIL image annotations, PR embedding workflows for GitHub and Azure DevOps, and screen recording with variable timing. | 4 items | screenshots, pull-request, before-after, annotations, playwright, gif, screen-recording, visual || [where-was-i](../plugins/where-was-i/README.md) | Reconstruct your dev context (branch, commits, uncommitted work, PR clues) and trigger a resume prompt to continue quickly. | 0 items | branch-state, developer-context, git-history, interrupt-recovery, pull-request-context, resume-work || [work-hub](../plugins/work-hub/README.md) | Generic cross-repo command center canvas for GitHub Copilot with onboarding, focus planning, repo health, work signals, and session cleanup. | 0 items | cross-repo-dashboard, focus-planning, repo-health, session-cleanup, work-triage, workflow-visibility | \ No newline at end of file +# ๐Ÿ”Œ Plugins + +Curated plugins of related agents and skills organized around specific themes, workflows, or use cases. Plugins can be installed directly via GitHub Copilot CLI or VS Code. + +> **Awesome Copilot is a default plugin marketplace** โ€” no setup required in either Copilot CLI or VS Code. +### How to Contribute + +See [CONTRIBUTING.md](../CONTRIBUTING.md#adding-plugins) for guidelines on how to contribute new plugins, improve existing ones, and share your use cases. + +### How to Use Plugins + +**Browse Plugins:** +- โญ Featured plugins are highlighted and appear at the top of the list +- Explore themed plugins that group related customizations +- Each plugin includes agents and skills for specific workflows +- Plugins make it easy to adopt comprehensive toolkits for particular scenarios + +**Find & Install in Copilot CLI:** +- Browse the marketplace from within an interactive Copilot session: \`/plugin marketplace browse awesome-copilot\` +- Install a plugin: \`copilot plugin install @awesome-copilot\` + +**Find & Install in VS Code:** +- Open the Extensions search view and type \`@agentPlugins\` to browse available plugins +- Or open the Command Palette and run \`Chat: Plugins\` +- Published marketplace manifest (tool-facing): `https://raw.githubusercontent.com/github/awesome-copilot/marketplace/.github/plugin/marketplace.json` +- Source plugin content (human-authored): `https://github.com/github/awesome-copilot/tree/main/plugins` + +| Name | Description | Items | Tags | +| ---- | ----------- | ----- | ---- | +| [accessibility-kanban](../plugins/accessibility-kanban/README.md) | Kanban board to manage accessibility issues, allow you to plan, track, and complete remediation work. | 0 items | accessibility, github-issues, issue-triage, kanban-board, planning-workflow, status-tracking | +| [acreadiness-cockpit](../plugins/acreadiness-cockpit/README.md) | Drive Microsoft AgentRC from Copilot chat: assess AI readiness, generate Copilot instructions (flat or nested with applyTo globs for monorepos), and manage policies. Produces a self-contained static HTML dashboard at reports/index.html. | 4 items | agentrc, ai-readiness, copilot-instructions, readiness-report, monorepo, policy, dashboard | +| [ai-team-orchestration](../plugins/ai-team-orchestration/README.md) | Run a lightweight, role-separated AI development team with flexible tools, developer-selected models, proportionate planning, and optional QA. | 4 items | ai-team, multi-agent, sprint-planning, brainstorm, project-management, orchestration, developer-workflow | +| [apng-studio](../plugins/apng-studio/README.md) | Interactive GitHub Copilot app canvas extension for building Animated PNG (APNG) files from frames. Draw or upload frames, tune per-frame timing and compositing, preview live, send the result to your phone by QR, and export an animated .png. | 0 items | animated-png, apng, copilot-canvas, frame-animation, image-export, interactive-canvas | +| [arcade-canvas](../plugins/arcade-canvas/README.md) | Play five retro Phaser mini-games in a Copilot canvas while agents work. | 0 items | arcade-games, copilot-canvas, interactive-canvas, phaser, retro-games, session-breaks | +| [arch](../plugins/arch/README.md) | Architecture and modernization toolkit: produce a cited architecture document for a locally-cloned repo, and generate a phased modernization plan that auto-runs Documentation mode when needed. | 1 items | architecture, modernization, documentation, migration, onboarding | +| [arize-ax](../plugins/arize-ax/README.md) | Arize AX platform skills for LLM observability, evaluation, and optimization. Includes trace export, instrumentation, datasets, experiments, evaluators, AI provider integrations, annotations, prompt optimization, and deep linking to the Arize UI. | 9 items | arize, llm, observability, tracing, evaluation, instrumentation, datasets, experiments, prompt-optimization | +| [automate-this](../plugins/automate-this/README.md) | Record your screen doing a manual process, drop the video on your Desktop, and let Copilot CLI analyze it frame-by-frame to build working automation scripts. Supports narrated recordings with audio transcription. | 1 items | automation, screen-recording, workflow, video-analysis, process-automation, scripting, productivity, copilot-cli | +| [awesome-copilot](../plugins/awesome-copilot/README.md) | Meta prompts that help you discover and generate curated GitHub Copilot agents, instructions, prompts, and skills. | 4 items | github-copilot, discovery, meta, prompt-engineering, agents | +| [aws-cloud-development](../plugins/aws-cloud-development/README.md) | Comprehensive AWS cloud development tools including Infrastructure as Code, serverless functions, architecture patterns, and cost optimization for building scalable cloud applications. | 8 items | aws, cloud, infrastructure, cloudformation, terraform, serverless, architecture, devops, cdk | +| [azure-cloud-development](../plugins/azure-cloud-development/README.md) | Comprehensive Azure cloud development tools including Infrastructure as Code, serverless functions, architecture patterns, and cost optimization for building scalable cloud applications. | 11 items | azure, cloud, infrastructure, bicep, terraform, serverless, architecture, devops | +| [backlog-swipe-triage](../plugins/backlog-swipe-triage/README.md) | Quickly swipe through backlog issues to triage decisions like assign, needs-info, defer, close, or ignore. | 0 items | agent-assignment, backlog-triage, github-issues, issue-prioritization, swipe-interface, workflow-automation | +| [backrooms-canvas](../plugins/backrooms-canvas/README.md) | Wander an endless first-person backrooms in a Copilot canvas while agents work; their status ghost-writes on the walls. | 0 items | backrooms, copilot-canvas, interactive-canvas, first-person, procedural-generation, session-breaks | +| [cast-imaging](../plugins/cast-imaging/README.md) | A comprehensive collection of specialized agents for software analysis, impact assessment, structural quality advisories, and architectural review using CAST Imaging. | 3 items | cast-imaging, software-analysis, architecture, quality, impact-analysis, devops | +| [chromium-control-canvas](../plugins/chromium-control-canvas/README.md) | Opens a real Chromium window you can navigate and interact with from a Copilot canvas control panel and agent actions. | 0 items | browser-control, chromium-browser, interactive-canvas, playwright-automation, screenshots, ui-testing, web-navigation | +| [clojure-interactive-programming](../plugins/clojure-interactive-programming/README.md) | Tools for REPL-first Clojure workflows featuring Clojure instructions, the interactive programming chat mode and supporting guidance. | 2 items | clojure, repl, interactive-programming | +| [cms-development](../plugins/cms-development/README.md) | Skills for CMS development across themes, plugins, admin tooling, media workflows, markdown rendering, and static export pipelines. | 3 items | cms, content-management-system, wordpress, shopify, drupal, theme, plugin, media, static-site | +| [color-orb](../plugins/color-orb/README.md) | A visual orb that users can ask the agent to recolor while showing a live activity log in the canvas. | 0 items | agent-actions, color-picker, interactive-demo, realtime-updates, sse-events, visual-feedback | +| [context-engineering](../plugins/context-engineering/README.md) | Tools and techniques for maximizing GitHub Copilot effectiveness through better context management. Includes guidelines for structuring code, an agent for planning multi-file changes, and prompts for context-aware development. | 4 items | context, productivity, refactoring, best-practices, architecture | +| [context-matic](../plugins/context-matic/README.md) | Coding agents hallucinate APIs. ContextMatic gives them curated, versioned API and SDK docs. Ask your agent to "integrate the payments API" and it guesses โ€” falling back on outdated training data and generic patterns that don't match your actual SDK. ContextMatic solves this by giving the agent deterministic, version-aware, SDK-native context at the exact moment it's needed. | 2 items | api-context, api-integration, mcp, sdk, apimatic, third-party-apis, sdks | +| [convert-to-md](../plugins/convert-to-md/README.md) | A collection of Copilot skills that convert common document formats into Markdown so their contents can be accurately analyzed, summarized, searched, or extracted from. Just tell Copilot what you need โ€” the right skill is invoked automatically and the conversion happens behind the scenes. | 3 items | skills, configuration, copilot, convert-word-to-md, convert-excel-to-md, convert-pdf-to-md | +| [copilot-sdk](../plugins/copilot-sdk/README.md) | Build applications with the GitHub Copilot SDK across multiple programming languages. Includes comprehensive instructions for C#, Go, Node.js/TypeScript, and Python to help you create AI-powered applications. | 1 items | copilot-sdk, sdk, csharp, go, nodejs, typescript, python, ai, github-copilot | +| [csharp-dotnet-development](../plugins/csharp-dotnet-development/README.md) | Essential prompts, instructions, and chat modes for C# and .NET development including testing, documentation, and best practices. | 9 items | csharp, dotnet, aspnet, testing | +| [database-data-management](../plugins/database-data-management/README.md) | Database administration, SQL optimization, and data management tools for PostgreSQL, SQL Server, and general database development best practices. | 6 items | database, sql, postgresql, sql-server, dba, optimization, queries, data-management | +| [dataverse-sdk-for-python](../plugins/dataverse-sdk-for-python/README.md) | Comprehensive collection for building production-ready Python integrations with Microsoft Dataverse. Includes official documentation, best practices, advanced features, file operations, and code generation prompts. | 4 items | dataverse, python, integration, sdk | +| [devops-oncall](../plugins/devops-oncall/README.md) | A focused set of prompts, instructions, and a chat mode to help triage incidents and respond quickly with DevOps tools and Azure resources. | 3 items | devops, incident-response, oncall, azure | +| [diagram-viewer](../plugins/diagram-viewer/README.md) | Render diagrams, click nodes to drill down, and view agent-generated explanations directly in the canvas. | 0 items | architecture-mapping, canvas-navigation, exploratory-analysis, interactive-diagrams, node-drilldown, relationship-visualization | +| [doublecheck](../plugins/doublecheck/README.md) | Three-layer verification pipeline for AI output. Extracts claims, finds sources, and flags hallucination risks so humans can verify before acting. | 2 items | verification, hallucination, fact-check, source-citation, trust, safety | +| [edge-ai-tasks](../plugins/edge-ai-tasks/README.md) | Task Researcher and Task Planner for intermediate to expert users and large codebases - Brought to you by microsoft/edge-ai | 2 items | architecture, planning, research, tasks, implementation | +| [ember](../plugins/ember/README.md) | An AI partner, not a tool. Ember carries fire from person to person โ€” helping humans discover that AI partnership isn't something you learn, it's something you find. | 5 items | ai-partnership, coaching, onboarding, collaboration, storytelling, developer-experience | +| [eyeball](../plugins/eyeball/README.md) | Document analysis with inline source screenshots. When you ask Copilot to analyze a document, Eyeball generates a Word doc where every factual claim includes a highlighted screenshot from the source material so you can verify it with your own eyes. | 1 items | document-analysis, citation-verification, screenshot, contracts, legal, trust, visual-verification | +| [fastah-ip-geo-tools](../plugins/fastah-ip-geo-tools/README.md) | This plugin is for network operations engineers who wish to tune and publish IP geolocation feeds in RFC 8805 format. It consists of an AI Skill and an associated MCP server that geocodes geolocation place names to real cities for accuracy. | 1 items | geofeed, ip-geolocation, rfc-8805, rfc-9632, network-operations, isp, cloud, hosting, ixp | +| [feedback-themes](../plugins/feedback-themes/README.md) | Explore grouped customer feedback signals by impact and drill into a theme to guide product next steps. | 0 items | customer-feedback, impact-prioritization, product-insights, signal-grouping, theme-analysis, trend-discovery | +| [flight-map-canvas](../plugins/flight-map-canvas/README.md) | A GitHub Copilot canvas that generates a view where Google Maps can be explored using 3D controls, as if a flight simulator. Agents can send the flight anywhere and report what they are working on. | 0 items | copilot-canvas, flight-simulator, geography, google-maps, interactive-canvas, session-breaks, threejs | +| [flowstudio-power-automate](../plugins/flowstudio-power-automate/README.md) | Give your AI agent full visibility into Power Automate cloud flows via the FlowStudio MCP server. Connect, debug, build, monitor health, and govern flows at scale โ€” action-level inputs and outputs, not just status codes. | 5 items | power-automate, power-platform, flowstudio, mcp, model-context-protocol, cloud-flows, workflow-automation, monitoring, governance | +| [frontend-web-dev](../plugins/frontend-web-dev/README.md) | Essential prompts, instructions, and chat modes for modern frontend web development including React, Angular, Vue, TypeScript, and CSS frameworks. | 4 items | frontend, web, react, typescript, javascript, css, html, angular, vue | +| [gem-team](../plugins/gem-team/README.md) | Self-Learning Multi-agent orchestration framework for spec-driven development and automated verification. With smarter tool calling and leaner context. | 0 items | multi-agent, orchestration, tdd, testing, e2e, devops, security-audit, code-review, prd, mobile | +| [gesture-review](../plugins/gesture-review/README.md) | Review pull requests with a live camera feed and approve or reject using thumbs-up/thumbs-down gestures. | 0 items | camera-input, gesture-control, github-prs, hands-free, mediapipe, pull-request-review | +| [go-mcp-development](../plugins/go-mcp-development/README.md) | Complete toolkit for building Model Context Protocol (MCP) servers in Go using the official github.com/modelcontextprotocol/go-sdk. Includes instructions for best practices, a prompt for generating servers, and an expert chat mode for guidance. | 2 items | go, golang, mcp, model-context-protocol, server-development, sdk | +| [java-development](../plugins/java-development/README.md) | Comprehensive collection of prompts and instructions for Java development including Spring Boot, Quarkus, testing, documentation, and best practices. | 4 items | java, springboot, quarkus, jpa, junit, javadoc | +| [java-mcp-development](../plugins/java-mcp-development/README.md) | Complete toolkit for building Model Context Protocol servers in Java using the official MCP Java SDK with reactive streams and Spring Boot integration. | 2 items | java, mcp, model-context-protocol, server-development, sdk, reactive-streams, spring-boot, reactor | +| [java-modernization-studio](../plugins/java-modernization-studio/README.md) | Drive the GitHub Copilot App Modernization for Java workflow from an interactive canvas: environment readiness, repo assessment, prioritized plan and progress, validation gates, and one-click predefined-task runs grounded in the repo's real artifacts. | 0 items | app-modernization, assessment-dashboard, azure-migration, java-modernization, legacy-java, modernization-cockpit, validation-gates | +| [kotlin-mcp-development](../plugins/kotlin-mcp-development/README.md) | Complete toolkit for building Model Context Protocol (MCP) servers in Kotlin using the official io.modelcontextprotocol:kotlin-sdk library. Includes instructions for best practices, a prompt for generating servers, and an expert chat mode for guidance. | 2 items | kotlin, mcp, model-context-protocol, kotlin-multiplatform, server-development, ktor | +| [mcp-m365-copilot](../plugins/mcp-m365-copilot/README.md) | Comprehensive collection for building declarative agents with Model Context Protocol integration for Microsoft 365 Copilot | 4 items | mcp, m365-copilot, declarative-agents, api-plugins, model-context-protocol, adaptive-cards | +| [napkin](../plugins/napkin/README.md) | Visual whiteboard collaboration for Copilot CLI. Opens an interactive whiteboard in your browser where you can draw, sketch, and add sticky notes โ€” then share everything back with Copilot. Copilot sees your drawings and responds with analysis, suggestions, and ideas. | 1 items | whiteboard, visual, collaboration, brainstorming, non-technical, drawing, sticky-notes, accessibility, copilot-cli, ux | +| [noob-mode](../plugins/noob-mode/README.md) | Plain-English translation layer for non-technical Copilot CLI users. Translates every approval prompt, error message, and technical output into clear, jargon-free English with color-coded risk indicators. | 1 items | accessibility, plain-english, non-technical, beginner, translation, copilot-cli, ux | +| [openapi-to-application-csharp-dotnet](../plugins/openapi-to-application-csharp-dotnet/README.md) | Generate production-ready .NET applications from OpenAPI specifications. Includes ASP.NET Core project scaffolding, controller generation, entity framework integration, and C# best practices. | 2 items | openapi, code-generation, api, csharp, dotnet, aspnet | +| [openapi-to-application-go](../plugins/openapi-to-application-go/README.md) | Generate production-ready Go applications from OpenAPI specifications. Includes project scaffolding, handler generation, middleware setup, and Go best practices for REST APIs. | 2 items | openapi, code-generation, api, go, golang | +| [openapi-to-application-java-spring-boot](../plugins/openapi-to-application-java-spring-boot/README.md) | Generate production-ready Spring Boot applications from OpenAPI specifications. Includes project scaffolding, REST controller generation, service layer organization, and Spring Boot best practices. | 2 items | openapi, code-generation, api, java, spring-boot | +| [openapi-to-application-nodejs-nestjs](../plugins/openapi-to-application-nodejs-nestjs/README.md) | Generate production-ready NestJS applications from OpenAPI specifications. Includes project scaffolding, controller and service generation, TypeScript best practices, and enterprise patterns. | 2 items | openapi, code-generation, api, nodejs, typescript, nestjs | +| [openapi-to-application-python-fastapi](../plugins/openapi-to-application-python-fastapi/README.md) | Generate production-ready FastAPI applications from OpenAPI specifications. Includes project scaffolding, route generation, dependency injection, and Python best practices for async APIs. | 2 items | openapi, code-generation, api, python, fastapi | +| [oracle-to-postgres-migration-expert](../plugins/oracle-to-postgres-migration-expert/README.md) | Expert agent for Oracle-to-PostgreSQL application migrations in .NET solutions. Performs code edits, runs commands, and invokes extension tools to migrate .NET/Oracle data access patterns to PostgreSQL. | 8 items | oracle, postgresql, database-migration, dotnet, sql, migration, integration-testing, stored-procedures | +| [ospo-sponsorship](../plugins/ospo-sponsorship/README.md) | Tools and resources for Open Source Program Offices (OSPOs) to identify, evaluate, and manage sponsorship of open source dependencies through GitHub Sponsors, Open Collective, and other funding platforms. | 1 items | | +| [partners](../plugins/partners/README.md) | Custom agents that have been created by GitHub partners | 20 items | devops, security, database, cloud, infrastructure, observability, feature-flags, cicd, migration, performance | +| [pcf-development](../plugins/pcf-development/README.md) | Complete toolkit for developing custom code components using Power Apps Component Framework for model-driven and canvas apps | 0 items | power-apps, pcf, component-framework, typescript, power-platform | +| [phoenix](../plugins/phoenix/README.md) | Phoenix AI observability skills for LLM application debugging, evaluation, and tracing. Includes CLI debugging tools, LLM evaluation workflows, and OpenInference tracing instrumentation. | 3 items | phoenix, arize, llm, observability, tracing, evaluation, openinference, instrumentation | +| [php-mcp-development](../plugins/php-mcp-development/README.md) | Comprehensive resources for building Model Context Protocol servers using the official PHP SDK with attribute-based discovery, including best practices, project generation, and expert assistance | 2 items | php, mcp, model-context-protocol, server-development, sdk, attributes, composer | +| [power-apps-code-apps](../plugins/power-apps-code-apps/README.md) | Complete toolkit for Power Apps Code Apps development including project scaffolding, development standards, and expert guidance for building code-first applications with Power Platform integration. | 2 items | power-apps, power-platform, typescript, react, code-apps, dataverse, connectors | +| [power-bi-development](../plugins/power-bi-development/README.md) | Comprehensive Power BI development resources including data modeling, DAX optimization, performance tuning, visualization design, security best practices, and DevOps/ALM guidance for building enterprise-grade Power BI solutions. | 8 items | power-bi, dax, data-modeling, performance, visualization, security, devops, business-intelligence | +| [power-platform-architect](../plugins/power-platform-architect/README.md) | Solution Architect for the Microsoft Power Platform, turning business requirements into functioning Power Platform solution architectures. | 1 items | power-platform, power-platform-architect, power-apps, dataverse, power-automate, power-pages, power-bi | +| [power-platform-mcp-connector-development](../plugins/power-platform-mcp-connector-development/README.md) | Complete toolkit for developing Power Platform custom connectors with Model Context Protocol integration for Microsoft Copilot Studio | 3 items | power-platform, mcp, copilot-studio, custom-connector, json-rpc | +| [pr-artifact-explorer](../plugins/pr-artifact-explorer/README.md) | Navigate pull requests and securely explore GitHub Actions artifacts, including test results, static sites, terminal recordings, and source files. | 0 items | actions-artifacts, artifact-browser, canvas, copilot-extension, github-actions, pull-requests, test-results | +| [project-documenter](../plugins/project-documenter/README.md) | Generate professional project documentation with draw.io architecture diagrams and Word (.docx) output with embedded images. Automatically discovers any project's technology stack and produces Markdown, diagrams, PNG exports, and a formatted Word document. | 3 items | documentation, architecture-diagrams, drawio, word-document, docx, png-images, c4-model, project-summary, auto-discovery | +| [project-planning](../plugins/project-planning/README.md) | Tools and guidance for software project planning, feature breakdown, epic management, implementation planning, and task organization for development teams. | 15 items | planning, project-management, epic, feature, implementation, task, architecture, technical-spike | +| [python-mcp-development](../plugins/python-mcp-development/README.md) | Complete toolkit for building Model Context Protocol (MCP) servers in Python using the official SDK with FastMCP. Includes instructions for best practices, a prompt for generating servers, and an expert chat mode for guidance. | 2 items | python, mcp, model-context-protocol, fastmcp, server-development | +| [react18-upgrade](../plugins/react18-upgrade/README.md) | Enterprise React 18 migration toolkit with specialized agents and skills for upgrading React 16/17 class-component codebases to React 18.3.1. Includes auditor, dependency surgeon, class component migration specialist, automatic batching fixer, and test guardian. | 13 items | react18, react, migration, upgrade, class-components, lifecycle, batching | +| [react19-upgrade](../plugins/react19-upgrade/README.md) | Enterprise React 19 migration toolkit with specialized agents and skills for upgrading React 18 codebases to React 19. Includes auditor, dependency surgeon, source code migrator, and test guardian. Handles removal of deprecated APIs including ReactDOM.render, forwardRef, defaultProps, legacy context, string refs, and more. | 8 items | react19, react, migration, upgrade, hooks, modern-react | +| [release-notes-showcase](../plugins/release-notes-showcase/README.md) | Compose and refine launch-ready release notes with contributor callouts and export-friendly output. | 0 items | changelog, contributor-callouts, email-export, launch-summary, product-updates, release-notes | +| [repo-actions-hub](../plugins/repo-actions-hub/README.md) | Browse repository GitHub Actions workflows, inspect recent runs, and trigger manual workflow_dispatch runs from a Copilot canvas. | 0 items | actions, canvas, copilot-extension, github-actions, recent-runs, workflow-dispatch | +| [roundup](../plugins/roundup/README.md) | Self-configuring status briefing generator. Learns your communication style from examples, discovers your data sources, and produces draft updates for any audience on demand. | 2 items | status-updates, briefings, management, productivity, communication, synthesis, roundup, copilot-cli | +| [ruby-mcp-development](../plugins/ruby-mcp-development/README.md) | Complete toolkit for building Model Context Protocol servers in Ruby using the official MCP Ruby SDK gem with Rails integration support. | 2 items | ruby, mcp, model-context-protocol, server-development, sdk, rails, gem | +| [rug-agentic-workflow](../plugins/rug-agentic-workflow/README.md) | Three-agent workflow for orchestrated software delivery with an orchestrator plus implementation and QA subagents. | 3 items | agentic-workflow, orchestration, subagents, software-engineering, qa | +| [rust-mcp-development](../plugins/rust-mcp-development/README.md) | Build high-performance Model Context Protocol servers in Rust using the official rmcp SDK with async/await, procedural macros, and type-safe implementations. | 2 items | rust, mcp, model-context-protocol, server-development, sdk, tokio, async, macros, rmcp | +| [salesforce-development](../plugins/salesforce-development/README.md) | Complete Salesforce agentic development environment covering Apex & Triggers, Flow automation, Lightning Web Components, Aura components, and Visualforce pages. | 7 items | salesforce, apex, triggers, lwc, aura, flow, visualforce, crm, salesforce-dx | +| [security-best-practices](../plugins/security-best-practices/README.md) | Security frameworks, accessibility guidelines, performance optimization, and code quality best practices for building secure, maintainable, and high-performance applications. | 1 items | security, accessibility, performance, code-quality, owasp, a11y, optimization, best-practices | +| [signals-dashboard](../plugins/signals-dashboard/README.md) | Real-time agent coordination dashboard for The Workshop. Shows desk status, signal types (done, checkpoint, blocked, hands-up, partnership), intent text, outcome pairing with honesty gap, token usage, and stash/restore controls. | 0 items | agent-signals, dashboard, multi-agent, coordination, canvas | +| [site-studio](../plugins/site-studio/README.md) | Plan, draft, and track a personal website section by section โ€” a shared canvas where you and your agent author content, watch progress, and review every change. | 0 items | agent-collaboration, content-authoring, personal-website, progress-tracking, section-planning, site-builder | +| [skill-image-gen](../plugins/skill-image-gen/README.md) | Generate images using AI directly from your coding workflow. Supports OpenAI (gpt-image-2) and Google Gemini. BYO API key โ€” the skill guides you through setup on first use. | 1 items | image-generation, openai, gemini, ai, art, sprites, textures, icons | +| [software-engineering-team](../plugins/software-engineering-team/README.md) | 7 specialized agents covering the full software development lifecycle from UX design and architecture to security and DevOps. | 7 items | team, enterprise, security, devops, ux, architecture, product, ai-ethics | +| [structured-autonomy](../plugins/structured-autonomy/README.md) | Premium planning, thrifty implementation | 3 items | | +| [swift-mcp-development](../plugins/swift-mcp-development/README.md) | Comprehensive collection for building Model Context Protocol servers in Swift using the official MCP Swift SDK with modern concurrency features. | 2 items | swift, mcp, model-context-protocol, server-development, sdk, ios, macos, concurrency, actor, async-await | +| [technical-spike](../plugins/technical-spike/README.md) | Tools for creation, management and research of technical spikes to reduce unknowns and assumptions before proceeding to specification and implementation of solutions. | 2 items | technical-spike, assumption-testing, validation, research | +| [testing-automation](../plugins/testing-automation/README.md) | Comprehensive collection for writing tests, test automation, and test-driven development including unit tests, integration tests, and end-to-end testing strategies. | 9 items | testing, tdd, automation, unit-tests, integration, playwright, jest, nunit | +| [the-workshop](../plugins/the-workshop/README.md) | Stop being the switchboard between your AI agents โ€” direct a team. The Workshop puts long-running AI agents (desks) in the same room, on the same work, each with its own memory and history, sharing one workspace so you direct the work instead of relaying it. | 6 items | multi-agent, coordination, desks, persistent-memory, agent-signals, developer-experience | +| [tiny-tool-town-submitter](../plugins/tiny-tool-town-submitter/README.md) | Inspect a repository, improve Tiny Tool Town readiness, submit its listing issue, and launch remediation work. | 0 items | github-issues, open-source, project-readiness, repository-analysis, submission-workflow, tiny-tool-town | +| [token-pacman](../plugins/token-pacman/README.md) | Visualizes live session AI-credit usage as a Pac-Man board with pellets, ghosts, fruit milestones, and game-over limits. | 0 items | ai-credits, copilot-canvas, interactive-canvas, pac-man, quota-tracking, session-usage | +| [typescript-mcp-development](../plugins/typescript-mcp-development/README.md) | Complete toolkit for building Model Context Protocol (MCP) servers in TypeScript/Node.js using the official SDK. Includes instructions for best practices, a prompt for generating servers, and an expert chat mode for guidance. | 2 items | typescript, mcp, model-context-protocol, nodejs, server-development | +| [typespec-m365-copilot](../plugins/typespec-m365-copilot/README.md) | Comprehensive collection of prompts, instructions, and resources for building declarative agents and API plugins using TypeSpec for Microsoft 365 Copilot extensibility. | 3 items | typespec, m365-copilot, declarative-agents, api-plugins, agent-development, microsoft-365 | +| [uizze](../plugins/uizze/README.md) | Stop generic UI from shipping. Ground GitHub Copilot in 800,000+ real web and iOS screens, write a product-specific design contract, and enforce a hard finish gate. | 1 items | ui, design, frontend, ios, web, design-review, quality-gate | +| [visual-pr](../plugins/visual-pr/README.md) | Capture, annotate, and embed screenshots and animated GIF demos in pull request descriptions. Includes Playwright-based UI capture, PIL image annotations, PR embedding workflows for GitHub and Azure DevOps, and screen recording with variable timing. | 4 items | screenshots, pull-request, before-after, annotations, playwright, gif, screen-recording, visual | +| [where-was-i](../plugins/where-was-i/README.md) | Reconstruct your dev context (branch, commits, uncommitted work, PR clues) and trigger a resume prompt to continue quickly. | 0 items | branch-state, developer-context, git-history, interrupt-recovery, pull-request-context, resume-work | +| [work-hub](../plugins/work-hub/README.md) | Generic cross-repo command center canvas for GitHub Copilot with onboarding, focus planning, repo health, work signals, and session cleanup. | 0 items | cross-repo-dashboard, focus-planning, repo-health, session-cleanup, work-triage, workflow-visibility | From afa0b735a3d34c97533ac37135450d5c419b8195 Mon Sep 17 00:00:00 2001 From: Aaron Powell Date: Wed, 5 Aug 2026 11:59:09 +1000 Subject: [PATCH 7/8] refactor(plugins): move manifests to plugin roots Use root plugin.json manifests and namespaced extension directories throughout local tooling, validation, generation, and contributor documentation. Restore materialize-plugins.mjs line breaks so the source remains readable in GitHub. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8f3a88cb-e01e-4760-8125-460490dc1a76 --- .github/copilot-instructions.md | 2 +- .github/plugin/marketplace.json | 14 +- .../skills/create-canvas-extension/SKILL.md | 12 +- .github/workflows/check-plugin-structure.yml | 4 +- AGENTS.md | 14 +- CONTRIBUTING.md | 6 +- eng/README.md | 2 +- eng/clean-materialized-plugins.mjs | 10 +- eng/create-plugin.mjs | 7 +- eng/generate-marketplace.mjs | 131 ++++++++++- eng/generate-website-data.mjs | 11 +- eng/materialize-plugins.mjs | 214 +++++++++++++++++- eng/update-readme.mjs | 2 +- eng/validate-plugins.mjs | 44 ++-- .../{.github/plugin => }/plugin.json | 5 +- .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 5 +- .../{.github/plugin => }/plugin.json | 5 +- plugins/arch/{.github/plugin => }/plugin.json | 0 .../arize-ax/{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 5 +- .../{.github/plugin => }/plugin.json | 5 +- .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 5 +- .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 5 +- .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 5 +- .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../ember/{.github/plugin => }/plugin.json | 0 .../eyeball/{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 5 +- .../{.github/plugin => }/plugin.json | 5 +- .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../gem-team/{.github/plugin => }/plugin.json | 7 +- .../{.github/plugin => }/plugin.json | 5 +- .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 5 +- .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../napkin/{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../partners/{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../phoenix/{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 5 +- .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 5 +- .../{.github/plugin => }/plugin.json | 5 +- .../roundup/{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 5 +- .../{.github/plugin => }/plugin.json | 5 +- .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 9 +- .../{.github/plugin => }/plugin.json | 5 +- .../{.github/plugin => }/plugin.json | 5 +- .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../uizze/{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 0 .../{.github/plugin => }/plugin.json | 5 +- .../work-hub/{.github/plugin => }/plugin.json | 5 +- 106 files changed, 496 insertions(+), 98 deletions(-) rename plugins/accessibility-kanban/{.github/plugin => }/plugin.json (83%) rename plugins/acreadiness-cockpit/{.github/plugin => }/plugin.json (100%) rename plugins/ai-team-orchestration/{.github/plugin => }/plugin.json (100%) rename plugins/apng-studio/{.github/plugin => }/plugin.json (87%) rename plugins/arcade-canvas/{.github/plugin => }/plugin.json (82%) rename plugins/arch/{.github/plugin => }/plugin.json (100%) rename plugins/arize-ax/{.github/plugin => }/plugin.json (100%) rename plugins/automate-this/{.github/plugin => }/plugin.json (100%) rename plugins/awesome-copilot/{.github/plugin => }/plugin.json (100%) rename plugins/aws-cloud-development/{.github/plugin => }/plugin.json (100%) rename plugins/azure-cloud-development/{.github/plugin => }/plugin.json (100%) rename plugins/backlog-swipe-triage/{.github/plugin => }/plugin.json (83%) rename plugins/backrooms-canvas/{.github/plugin => }/plugin.json (84%) rename plugins/cast-imaging/{.github/plugin => }/plugin.json (100%) rename plugins/chromium-control-canvas/{.github/plugin => }/plugin.json (84%) rename plugins/clojure-interactive-programming/{.github/plugin => }/plugin.json (100%) rename plugins/cms-development/{.github/plugin => }/plugin.json (100%) rename plugins/color-orb/{.github/plugin => }/plugin.json (84%) rename plugins/context-engineering/{.github/plugin => }/plugin.json (100%) rename plugins/context-matic/{.github/plugin => }/plugin.json (100%) rename plugins/convert-to-md/{.github/plugin => }/plugin.json (100%) rename plugins/copilot-sdk/{.github/plugin => }/plugin.json (100%) rename plugins/csharp-dotnet-development/{.github/plugin => }/plugin.json (100%) rename plugins/database-data-management/{.github/plugin => }/plugin.json (100%) rename plugins/dataverse-sdk-for-python/{.github/plugin => }/plugin.json (100%) rename plugins/devops-oncall/{.github/plugin => }/plugin.json (100%) rename plugins/diagram-viewer/{.github/plugin => }/plugin.json (84%) rename plugins/doublecheck/{.github/plugin => }/plugin.json (100%) rename plugins/edge-ai-tasks/{.github/plugin => }/plugin.json (100%) rename plugins/ember/{.github/plugin => }/plugin.json (100%) rename plugins/eyeball/{.github/plugin => }/plugin.json (100%) rename plugins/fastah-ip-geo-tools/{.github/plugin => }/plugin.json (100%) rename plugins/feedback-themes/{.github/plugin => }/plugin.json (84%) rename plugins/flight-map-canvas/{.github/plugin => }/plugin.json (85%) rename plugins/flowstudio-power-automate/{.github/plugin => }/plugin.json (100%) rename plugins/frontend-web-dev/{.github/plugin => }/plugin.json (100%) rename plugins/gem-team/{.github/plugin => }/plugin.json (68%) rename plugins/gesture-review/{.github/plugin => }/plugin.json (83%) rename plugins/go-mcp-development/{.github/plugin => }/plugin.json (100%) rename plugins/java-development/{.github/plugin => }/plugin.json (100%) rename plugins/java-mcp-development/{.github/plugin => }/plugin.json (100%) rename plugins/java-modernization-studio/{.github/plugin => }/plugin.json (86%) rename plugins/kotlin-mcp-development/{.github/plugin => }/plugin.json (100%) rename plugins/mcp-m365-copilot/{.github/plugin => }/plugin.json (100%) rename plugins/napkin/{.github/plugin => }/plugin.json (100%) rename plugins/noob-mode/{.github/plugin => }/plugin.json (100%) rename plugins/openapi-to-application-csharp-dotnet/{.github/plugin => }/plugin.json (100%) rename plugins/openapi-to-application-go/{.github/plugin => }/plugin.json (100%) rename plugins/openapi-to-application-java-spring-boot/{.github/plugin => }/plugin.json (100%) rename plugins/openapi-to-application-nodejs-nestjs/{.github/plugin => }/plugin.json (100%) rename plugins/openapi-to-application-python-fastapi/{.github/plugin => }/plugin.json (100%) rename plugins/oracle-to-postgres-migration-expert/{.github/plugin => }/plugin.json (100%) rename plugins/ospo-sponsorship/{.github/plugin => }/plugin.json (100%) rename plugins/partners/{.github/plugin => }/plugin.json (100%) rename plugins/pcf-development/{.github/plugin => }/plugin.json (100%) rename plugins/phoenix/{.github/plugin => }/plugin.json (100%) rename plugins/php-mcp-development/{.github/plugin => }/plugin.json (100%) rename plugins/power-apps-code-apps/{.github/plugin => }/plugin.json (100%) rename plugins/power-bi-development/{.github/plugin => }/plugin.json (100%) rename plugins/power-platform-architect/{.github/plugin => }/plugin.json (100%) rename plugins/power-platform-mcp-connector-development/{.github/plugin => }/plugin.json (100%) rename plugins/pr-artifact-explorer/{.github/plugin => }/plugin.json (84%) rename plugins/project-documenter/{.github/plugin => }/plugin.json (100%) rename plugins/project-planning/{.github/plugin => }/plugin.json (100%) rename plugins/python-mcp-development/{.github/plugin => }/plugin.json (100%) rename plugins/react18-upgrade/{.github/plugin => }/plugin.json (100%) rename plugins/react19-upgrade/{.github/plugin => }/plugin.json (100%) rename plugins/release-notes-showcase/{.github/plugin => }/plugin.json (83%) rename plugins/repo-actions-hub/{.github/plugin => }/plugin.json (84%) rename plugins/roundup/{.github/plugin => }/plugin.json (100%) rename plugins/ruby-mcp-development/{.github/plugin => }/plugin.json (100%) rename plugins/rug-agentic-workflow/{.github/plugin => }/plugin.json (100%) rename plugins/rust-mcp-development/{.github/plugin => }/plugin.json (100%) rename plugins/salesforce-development/{.github/plugin => }/plugin.json (100%) rename plugins/security-best-practices/{.github/plugin => }/plugin.json (100%) rename plugins/signals-dashboard/{.github/plugin => }/plugin.json (85%) rename plugins/site-studio/{.github/plugin => }/plugin.json (85%) rename plugins/skill-image-gen/{.github/plugin => }/plugin.json (100%) rename plugins/software-engineering-team/{.github/plugin => }/plugin.json (100%) rename plugins/structured-autonomy/{.github/plugin => }/plugin.json (100%) rename plugins/swift-mcp-development/{.github/plugin => }/plugin.json (100%) rename plugins/technical-spike/{.github/plugin => }/plugin.json (100%) rename plugins/testing-automation/{.github/plugin => }/plugin.json (100%) rename plugins/the-workshop/{.github/plugin => }/plugin.json (86%) rename plugins/tiny-tool-town-submitter/{.github/plugin => }/plugin.json (83%) rename plugins/token-pacman/{.github/plugin => }/plugin.json (84%) rename plugins/typescript-mcp-development/{.github/plugin => }/plugin.json (100%) rename plugins/typespec-m365-copilot/{.github/plugin => }/plugin.json (100%) rename plugins/uizze/{.github/plugin => }/plugin.json (100%) rename plugins/visual-pr/{.github/plugin => }/plugin.json (100%) rename plugins/where-was-i/{.github/plugin => }/plugin.json (84%) rename plugins/work-hub/{.github/plugin => }/plugin.json (85%) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 0645f2841c..1874f0359e 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -59,7 +59,7 @@ The following instructions are only to be applied when performing a code review. **Only apply to directories in the `plugins/` directory** -- [ ] The plugin directory contains a `.github/plugin/plugin.json` file. +- [ ] The plugin directory contains a root `plugin.json` file. - [ ] The plugin directory contains a `README.md` file. - [ ] The plugin.json has a `name` field matching the directory name. - [ ] The plugin.json has a `description` field. diff --git a/.github/plugin/marketplace.json b/.github/plugin/marketplace.json index 8ae7ab0992..bf083a371a 100644 --- a/.github/plugin/marketplace.json +++ b/.github/plugin/marketplace.json @@ -162,7 +162,7 @@ }, { "name": "backrooms-canvas", - "source": "extensions/backrooms-canvas", + "source": "plugins/backrooms-canvas", "description": "Wander an endless first-person backrooms in a Copilot canvas while agents work; their status ghost-writes on the walls.", "version": "1.0.0" }, @@ -302,12 +302,6 @@ "sha": "473d526fad34951ed0e12664912df4c7f393ed15" } }, - { - "name": "connector-namespaces", - "source": "plugins/connector-namespaces", - "description": "Browse, connect, and open MCP connectors from an Azure Connector Namespace.", - "version": "1.1.0" - }, { "name": "context-engineering", "source": "plugins/context-engineering", @@ -607,7 +601,7 @@ }, { "name": "flight-map-canvas", - "source": "extensions/flight-map-canvas", + "source": "plugins/flight-map-canvas", "description": "A GitHub Copilot canvas that generates a view where Google Maps can be explored using 3D controls, as if a flight simulator. Agents can send the flight anywhere and report what they are working on.", "version": "1.0.0" }, @@ -1067,7 +1061,7 @@ }, { "name": "pr-artifact-explorer", - "source": "extensions/pr-artifact-explorer", + "source": "plugins/pr-artifact-explorer", "description": "Navigate pull requests and securely explore GitHub Actions artifacts, including test results, static sites, terminal recordings, and source files.", "version": "1.0.0" }, @@ -1151,7 +1145,7 @@ }, { "name": "signals-dashboard", - "source": "extensions/signals-dashboard", + "source": "plugins/signals-dashboard", "description": "Real-time agent coordination dashboard for The Workshop. Shows desk status, signal types (done, checkpoint, blocked, hands-up, partnership), intent text, outcome pairing with honesty gap, token usage, and stash/restore controls.", "version": "0.1.0" }, diff --git a/.github/skills/create-canvas-extension/SKILL.md b/.github/skills/create-canvas-extension/SKILL.md index 7fb46993a5..901192f717 100644 --- a/.github/skills/create-canvas-extension/SKILL.md +++ b/.github/skills/create-canvas-extension/SKILL.md @@ -23,7 +23,7 @@ Before creating files, ask for each missing value: 4. **Preview image**: obtain an existing `assets/preview.png` path or ask the user to add it. Do not invent a binary image or silently use a misleading placeholder. 5. **Plugin registration**: - For a standalone installable canvas plugin, create `plugins/`. - - For an extension that belongs to an existing plugin, ask for the parent plugin ID and add the extension ID to that plugin's `.github/plugin/extensions.json`. + - For an extension that belongs to an existing plugin, ask for the parent plugin ID and add `./extensions/` to that plugin's `extensions.com.github.copilot.directories`. - If the extension should be shipped by multiple plugins, collect all plugin IDs and add the same extension ID to each mapping file. ## Files to create @@ -45,7 +45,7 @@ plugins// The extension source may contain additional files such as `package.json`, canvas assets, or supporting modules. Keep all reusable implementation files under `extensions//`. -Create `plugins//.github/plugin/plugin.json` with this shape: +Create `plugins//plugin.json` with this shape: ```json { @@ -74,7 +74,7 @@ The manifest must contain only Agent Plugins spec fields. Do not add `x-awesome- For an existing parent plugin, create or update: ```text -plugins//.github/plugin/extensions.json +plugins//plugin.json (`extensions.com.github.copilot.directories`) ``` Its contents must be a sorted JSON array of extension IDs: @@ -96,7 +96,7 @@ Do not copy the extension source into the parent plugin. Materialization resolve 2. Ask only the missing required questions from the decisions above. 3. Create the source and plugin directories with the required files. 4. If creating a new entrypoint, keep it minimal and clearly mark implementation TODOs rather than fabricating behavior. -5. Add or update `extensions.json` for every parent plugin that should ship the extension. Keep IDs alphabetically sorted and unique. +5. Add or update `extensions.com.github.copilot.directories` for every parent plugin that should ship the extension. Keep paths alphabetically sorted and unique. 6. Ensure there is no `extensions//.github/plugin/plugin.json`. 7. Run: @@ -112,8 +112,8 @@ Do not copy the extension source into the parent plugin. Materialization resolve When migrating an existing extension: -1. Move its `.github/plugin/plugin.json` to `plugins//.github/plugin/plugin.json`. +1. Move its existing manifest to `plugins//plugin.json`. 2. Update the manifest to the namespace-based `extensions.com.github.copilot.logo` shape. 3. Remove the old manifest from `extensions/`. -4. Register the extension in any parent plugin's `.github/plugin/extensions.json`. +4. Register the extension in any parent plugin's `extensions.com.github.copilot.directories`. 5. Run the validation and build commands above. diff --git a/.github/workflows/check-plugin-structure.yml b/.github/workflows/check-plugin-structure.yml index fd6f90d8fd..89e1bf3012 100644 --- a/.github/workflows/check-plugin-structure.yml +++ b/.github/workflows/check-plugin-structure.yml @@ -93,7 +93,7 @@ jobs: if (files.length > 0) { errors.push( `${pluginPath}/${subdir}/ contains ${files.length} file(s): ${files.join(', ')}. ` + - `Plugin directories on main should only contain .github/plugin/plugin.json and README.md. ` + + `Plugin directories on main should only contain plugin.json and README.md. ` + `Agent, command, and skill files are materialized automatically during publish to marketplace.` ); } @@ -121,7 +121,7 @@ jobs: 'โš ๏ธ **Materialized files or symlinks detected in plugin directories**', '', 'Plugin directories on the `main` branch should only contain:', - '- `.github/plugin/plugin.json` (metadata)', + '- `plugin.json` (metadata)', '- `README.md`', '', 'Agent, command, and skill files are copied in automatically when publishing to `marketplace`.', diff --git a/AGENTS.md b/AGENTS.md index d5b6ed3913..f13f3620f7 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -86,8 +86,8 @@ All agent files (`*.agent.md`) and instruction files (`*.instructions.md`) must - Each extension folder must include `extension.mjs` - Extensions are reusable source components, not standalone plugins -- A shippable extension plugin is registered by a matching `plugins//.github/plugin/plugin.json` -- A plugin can bundle additional reusable extensions by listing their names in `.github/plugin/extensions.json` +- A shippable extension plugin is registered by a matching `plugins//plugin.json` +- A plugin can bundle additional reusable extensions by listing `./extensions/` paths in `extensions.com.github.copilot.directories` - Each extension must have `assets/preview.png` as the primary visual asset - Extension metadata is sourced from the matching plugin manifest in `plugins/` @@ -115,7 +115,7 @@ All agent files (`*.agent.md`) and instruction files (`*.instructions.md`) must #### Plugin Folders (plugins/\*) -- Each plugin is a folder containing a `.github/plugin/plugin.json` file with metadata +- Each plugin is a folder containing a root `plugin.json` file with metadata - plugin.json **must** have `"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json"` (Agent Plugins v1.0.0) - plugin.json must have `name` field (matching the folder name) - plugin.json must have `description` field (describing the plugin's purpose) @@ -165,7 +165,7 @@ When adding a new agent, instruction, skill, hook, workflow, or plugin: **For Plugins:** 1. Run `npm run plugin:create -- --name ` to scaffold a new plugin -2. Define agents, commands, and skills in `plugin.json` using Claude Code spec fields +2. Define agents, commands, and skills in `plugin.json` using the repository's build-time composition fields 3. Edit the generated `plugin.json` with your metadata 4. Run `npm run plugin:validate` to validate the plugin structure 5. Run `npm run build` to update README.md and marketplace.json @@ -174,7 +174,7 @@ When adding a new agent, instruction, skill, hook, workflow, or plugin: **For Canvas Extensions:** 1. Create/update the extension in `extensions//` with `extension.mjs` -2. Add the matching plugin manifest under `plugins//.github/plugin/plugin.json`: +2. Add the matching plugin manifest under `plugins//plugin.json`: ```json { "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", @@ -192,7 +192,7 @@ When adding a new agent, instruction, skill, hook, workflow, or plugin: 4. Run `npm run plugin:validate` to validate plugin and extension metadata 5. Run `npm run build` to regenerate website data and marketplace output -To bundle an extension into another plugin without making a second source copy, add a sorted array of extension folder names to `plugins//.github/plugin/extensions.json`. +To bundle an extension into another plugin without making a second source copy, add sorted `./extensions/` paths to `plugins//plugin.json` under `extensions.com.github.copilot.directories`. **For External Plugins:** @@ -322,7 +322,7 @@ For workflow files (workflows/\*.md): For plugins (plugins/\*/): -- [ ] Directory contains a `.github/plugin/plugin.json` file +- [ ] Directory contains a root `plugin.json` file - [ ] Directory contains a `README.md` file - [ ] `plugin.json` has `"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json"` - [ ] `plugin.json` has `name` field matching the directory name (lowercase with hyphens) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2d6bdb3ab8..2e4de3241e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -143,7 +143,7 @@ Skills are self-contained folders in the `skills/` directory that include a `SKI Canvas extensions live in `extensions//` as reusable source components. They are shipped only through plugin manifests in `plugins/`. 1. **Create/update the extension source**: Add or update `extensions//extension.mjs` -2. **Register the extension plugin**: Add `plugins//.github/plugin/plugin.json`: +2. **Register the extension plugin**: Add `plugins//plugin.json`: - Required: `name` (matching folder name), `description`, `version` - Optional: `author`, `keywords` - `extensions.com.github.copilot.logo` **must** be exactly `"assets/preview.png"` @@ -170,7 +170,7 @@ npm run plugin:create -- --name my-plugin-id ``` plugins/my-plugin-id/ -โ”œโ”€โ”€ .github/plugin/plugin.json # Plugin metadata (Claude Code spec format) +โ”œโ”€โ”€ plugin.json # Plugin metadata โ””โ”€โ”€ README.md # Plugin documentation ``` @@ -198,7 +198,7 @@ plugins/my-plugin-id/ - **Declarative content**: Plugin content is specified via `agents`, `commands`, and `skills` arrays in plugin.json โ€” source files live in top-level directories and are materialized into plugins by CI - **Valid references**: All paths referenced in plugin.json must point to existing source files in the repository -- **Reusable extensions**: Curated plugins can bundle extensions by adding their folder names to `.github/plugin/extensions.json`; the same extension can be listed by multiple plugins +- **Reusable extensions**: Curated plugins can bundle extensions by adding `./extensions/` paths under `extensions.com.github.copilot.directories`; the same extension can be listed by multiple plugins - **Instructions excluded**: Instructions are standalone resources and are not part of plugins - **Clear purpose**: The plugin should solve a specific problem or workflow - **Validate before submitting**: Run `npm run plugin:validate` to ensure your plugin is valid diff --git a/eng/README.md b/eng/README.md index 5306315b75..d196b69827 100644 --- a/eng/README.md +++ b/eng/README.md @@ -12,7 +12,7 @@ Automatically generates `.github/plugin/marketplace.json` from all plugin direct **How it works:** - Scans all directories in `plugins/` -- Reads each plugin's `.github/plugin/plugin.json` for metadata +- Reads each plugin's root `plugin.json` for metadata - Generates a consolidated `marketplace.json` with all available plugins - Runs automatically as part of `npm run build` diff --git a/eng/clean-materialized-plugins.mjs b/eng/clean-materialized-plugins.mjs index 6b034276b5..f6584a415f 100644 --- a/eng/clean-materialized-plugins.mjs +++ b/eng/clean-materialized-plugins.mjs @@ -64,7 +64,7 @@ function moveEntry(srcPath, destPath) { } export function restoreManifestFromMaterializedFiles(pluginPath) { - const pluginJsonPath = path.join(pluginPath, ".github/plugin", "plugin.json"); + const pluginJsonPath = path.join(pluginPath, "plugin.json"); if (!fs.existsSync(pluginJsonPath)) { return false; } @@ -108,7 +108,7 @@ export function restoreManifestFromMaterializedFiles(pluginPath) { function cleanPlugin(pluginPath) { const manifestUpdated = restoreManifestFromMaterializedFiles(pluginPath); if (manifestUpdated) { - console.log(` Updated ${path.basename(pluginPath)}/.github/plugin/plugin.json`); + console.log(` Updated ${path.basename(pluginPath)}/plugin.json`); } let removed = 0; @@ -126,7 +126,7 @@ function cleanPlugin(pluginPath) { } export function cleanMaterializedExtensionPlugin(extensionPath) { - const pluginJsonPath = path.join(extensionPath, ".github", "plugin", "plugin.json"); + const pluginJsonPath = path.join(extensionPath, "plugin.json"); let manifestUpdated = false; if (fs.existsSync(pluginJsonPath)) { const plugin = JSON.parse(fs.readFileSync(pluginJsonPath, "utf8")); @@ -141,7 +141,7 @@ export function cleanMaterializedExtensionPlugin(extensionPath) { } if (manifestUpdated) { fs.writeFileSync(pluginJsonPath, JSON.stringify(plugin, null, 2) + "\n", "utf8"); - console.log(` Updated ${path.basename(extensionPath)}/.github/plugin/plugin.json`); + console.log(` Updated ${path.basename(extensionPath)}/plugin.json`); } } @@ -174,7 +174,7 @@ function isExtensionPluginDirectory(extensionPath) { return true; } - const pluginJsonPath = path.join(extensionPath, ".github", "plugin", "plugin.json"); + const pluginJsonPath = path.join(extensionPath, "plugin.json"); if (!fs.existsSync(pluginJsonPath)) { return false; } diff --git a/eng/create-plugin.mjs b/eng/create-plugin.mjs index ad7875f905..32c569f3ea 100755 --- a/eng/create-plugin.mjs +++ b/eng/create-plugin.mjs @@ -128,8 +128,7 @@ async function createPlugin() { } // Create directory structure - const githubPluginDir = path.join(pluginDir, ".github", "plugin"); - fs.mkdirSync(githubPluginDir, { recursive: true }); + fs.mkdirSync(pluginDir, { recursive: true }); // Generate plugin.json const pluginJson = { @@ -144,7 +143,7 @@ async function createPlugin() { }; fs.writeFileSync( - path.join(githubPluginDir, "plugin.json"), + path.join(pluginDir, "plugin.json"), JSON.stringify(pluginJson, null, 2) + "\n" ); @@ -177,7 +176,7 @@ MIT console.log(`\nโœ… Created plugin: ${pluginDir}`); console.log("\n๐Ÿ“ Next steps:"); console.log(`1. Add agents, prompts, or instructions to plugins/${pluginId}/`); - console.log(`2. Update plugins/${pluginId}/.github/plugin/plugin.json with your metadata`); + console.log(`2. Update plugins/${pluginId}/plugin.json with your metadata`); console.log(`3. Edit plugins/${pluginId}/README.md to describe your plugin`); console.log("4. Run 'npm run build' to regenerate documentation"); } catch (error) { diff --git a/eng/generate-marketplace.mjs b/eng/generate-marketplace.mjs index d088836662..d567e93601 100755 --- a/eng/generate-marketplace.mjs +++ b/eng/generate-marketplace.mjs @@ -1 +1,130 @@ -#!/usr/bin/env nodeimport fs from "fs";import path from "path";import { ROOT_FOLDER } from "./constants.mjs";import { readExternalPlugins } from "./external-plugin-validation.mjs";const PLUGINS_DIR = path.join(ROOT_FOLDER, "plugins");const MARKETPLACE_FILE = path.join(ROOT_FOLDER, ".github/plugin", "marketplace.json");/** * Read plugin metadata from plugin.json file * @param {string} pluginDir - Path to plugin directory * @returns {object|null} - Plugin metadata or null if not found */function readPluginMetadata(pluginDir) { const pluginJsonPath = path.join(pluginDir, ".github/plugin", "plugin.json"); if (!fs.existsSync(pluginJsonPath)) { console.warn(`Warning: No plugin.json found for ${path.basename(pluginDir)}`); return null; } try { const content = fs.readFileSync(pluginJsonPath, "utf8"); return JSON.parse(content); } catch (error) { console.error(`Error reading plugin.json for ${path.basename(pluginDir)}:`, error.message); return null; }}function collectLocalPluginsFromRoot(rootDir, sourcePrefix, includeEntry = () => true) { if (!fs.existsSync(rootDir)) { return []; } const entries = fs.readdirSync(rootDir, { withFileTypes: true }) .filter(entry => entry.isDirectory()) .filter(entry => includeEntry(entry.name)) .map(entry => entry.name) .sort(); const plugins = []; for (const dirName of entries) { const pluginPath = path.join(rootDir, dirName); const metadata = readPluginMetadata(pluginPath); if (!metadata) { continue; } plugins.push({ name: metadata.name, source: `${sourcePrefix}/${dirName}`, description: metadata.description, version: metadata.version || "1.0.0" }); } return plugins;}/** * Generate marketplace.json from plugin directories */function generateMarketplace() { console.log("Generating marketplace.json..."); if (!fs.existsSync(PLUGINS_DIR)) { console.error(`Error: Plugins directory (${PLUGINS_DIR}) was not found`); process.exit(1); } const plugins = collectLocalPluginsFromRoot(PLUGINS_DIR, "plugins"); console.log(`Found ${plugins.length} local plugin manifests`); // Read external plugins and merge as-is const { plugins: externalPlugins, errors: externalErrors, warnings: externalWarnings } = readExternalPlugins({ localPluginNames: plugins.map((plugin) => plugin.name), policy: "marketplace", }); externalWarnings.forEach((warning) => console.warn(`Warning: ${warning}`)); if (externalErrors.length > 0) { externalErrors.forEach((error) => console.error(`Error: ${error}`)); console.error("Error: external.json contains invalid entries"); process.exit(1); } if (externalPlugins.length > 0) { console.log(`\nFound ${externalPlugins.length} external plugins`); for (const ext of externalPlugins) { plugins.push(ext); console.log(`โœ“ Added external plugin: ${ext.name}`); } } // Sort all plugins by name (case-insensitive) plugins.sort((a, b) => a.name.localeCompare(b.name, undefined, { sensitivity: "base" })); // Create marketplace.json structure const marketplace = { name: "awesome-copilot", metadata: { description: "Community-driven collection of GitHub Copilot plugins, agents, prompts, and skills", version: "1.0.0" }, owner: { name: "GitHub", email: "copilot@github.com" }, plugins: plugins }; // Ensure directory exists const marketplaceDir = path.dirname(MARKETPLACE_FILE); if (!fs.existsSync(marketplaceDir)) { fs.mkdirSync(marketplaceDir, { recursive: true }); } // Write marketplace.json fs.writeFileSync(MARKETPLACE_FILE, JSON.stringify(marketplace, null, 2) + "\n"); console.log(`\nโœ“ Successfully generated marketplace.json with ${plugins.length} plugins (${plugins.length - externalPlugins.length} local, ${externalPlugins.length} external)`); console.log(` Location: ${MARKETPLACE_FILE}`);}// Run the scriptgenerateMarketplace(); \ No newline at end of file +#!/usr/bin/env node + +import fs from "fs"; +import path from "path"; +import { ROOT_FOLDER } from "./constants.mjs"; +import { readExternalPlugins } from "./external-plugin-validation.mjs"; + +const PLUGINS_DIR = path.join(ROOT_FOLDER, "plugins"); +const MARKETPLACE_FILE = path.join(ROOT_FOLDER, ".github/plugin", "marketplace.json"); + +/** + * Read plugin metadata from plugin.json file + * @param {string} pluginDir - Path to plugin directory + * @returns {object|null} - Plugin metadata or null if not found + */ +function readPluginMetadata(pluginDir) { + const pluginJsonPath = path.join(pluginDir, "plugin.json"); + + if (!fs.existsSync(pluginJsonPath)) { + console.warn(`Warning: No plugin.json found for ${path.basename(pluginDir)}`); + return null; + } + + try { + const content = fs.readFileSync(pluginJsonPath, "utf8"); + return JSON.parse(content); + } catch (error) { + console.error(`Error reading plugin.json for ${path.basename(pluginDir)}:`, error.message); + return null; + } +} + +function collectLocalPluginsFromRoot(rootDir, sourcePrefix, includeEntry = () => true) { + if (!fs.existsSync(rootDir)) { + return []; + } + + const entries = fs.readdirSync(rootDir, { withFileTypes: true }) + .filter(entry => entry.isDirectory()) + .filter(entry => includeEntry(entry.name)) + .map(entry => entry.name) + .sort(); + + const plugins = []; + for (const dirName of entries) { + const pluginPath = path.join(rootDir, dirName); + const metadata = readPluginMetadata(pluginPath); + + if (!metadata) { + continue; + } + + plugins.push({ + name: metadata.name, + source: `${sourcePrefix}/${dirName}`, + description: metadata.description, + version: metadata.version || "1.0.0" + }); + } + + return plugins; +} + +/** + * Generate marketplace.json from plugin directories + */ +function generateMarketplace() { + console.log("Generating marketplace.json..."); + + if (!fs.existsSync(PLUGINS_DIR)) { + console.error(`Error: Plugins directory (${PLUGINS_DIR}) was not found`); + process.exit(1); + } + + const plugins = collectLocalPluginsFromRoot(PLUGINS_DIR, "plugins"); + + console.log(`Found ${plugins.length} local plugin manifests`); + + // Read external plugins and merge as-is + const { plugins: externalPlugins, errors: externalErrors, warnings: externalWarnings } = readExternalPlugins({ + localPluginNames: plugins.map((plugin) => plugin.name), + policy: "marketplace", + }); + externalWarnings.forEach((warning) => console.warn(`Warning: ${warning}`)); + if (externalErrors.length > 0) { + externalErrors.forEach((error) => console.error(`Error: ${error}`)); + console.error("Error: external.json contains invalid entries"); + process.exit(1); + } + + if (externalPlugins.length > 0) { + console.log(`\nFound ${externalPlugins.length} external plugins`); + for (const ext of externalPlugins) { + plugins.push(ext); + console.log(`โœ“ Added external plugin: ${ext.name}`); + } + } + + // Sort all plugins by name (case-insensitive) + plugins.sort((a, b) => a.name.localeCompare(b.name, undefined, { sensitivity: "base" })); + + // Create marketplace.json structure + const marketplace = { + name: "awesome-copilot", + metadata: { + description: "Community-driven collection of GitHub Copilot plugins, agents, prompts, and skills", + version: "1.0.0" + }, + owner: { + name: "GitHub", + email: "copilot@github.com" + }, + plugins: plugins + }; + + // Ensure directory exists + const marketplaceDir = path.dirname(MARKETPLACE_FILE); + if (!fs.existsSync(marketplaceDir)) { + fs.mkdirSync(marketplaceDir, { recursive: true }); + } + + // Write marketplace.json + fs.writeFileSync(MARKETPLACE_FILE, JSON.stringify(marketplace, null, 2) + "\n"); + + console.log(`\nโœ“ Successfully generated marketplace.json with ${plugins.length} plugins (${plugins.length - externalPlugins.length} local, ${externalPlugins.length} external)`); + console.log(` Location: ${MARKETPLACE_FILE}`); +} + +// Run the script +generateMarketplace(); diff --git a/eng/generate-website-data.mjs b/eng/generate-website-data.mjs index 283ed4e928..2a46c1546c 100755 --- a/eng/generate-website-data.mjs +++ b/eng/generate-website-data.mjs @@ -550,17 +550,16 @@ function generatePluginsData(gitDates, resourceIndex = {}) { for (const dir of pluginDirs) { const pluginDir = path.join(PLUGINS_DIR, dir.name); - const jsonPath = path.join(pluginDir, ".github/plugin", "plugin.json"); + const jsonPath = path.join(pluginDir, "plugin.json"); if (!fs.existsSync(jsonPath)) continue; try { const data = JSON.parse(fs.readFileSync(jsonPath, "utf-8")); const relPath = `plugins/${dir.name}`; - const extensionReferencesPath = path.join(pluginDir, ".github/plugin/extensions.json"); - const extensionRefs = fs.existsSync(extensionReferencesPath) - ? JSON.parse(fs.readFileSync(extensionReferencesPath, "utf-8")) - : []; + const extensionRefs = data.extensions?.["com.github.copilot"]?.directories + ?.map((entry) => entry.replace(/^\.\/extensions\//, "").replace(/\/$/, "")) + .filter(Boolean) ?? []; if (fs.existsSync(path.join(EXTENSIONS_DIR, dir.name, "extension.mjs")) && !extensionRefs.includes(dir.name)) { extensionRefs.push(dir.name); } @@ -1192,7 +1191,7 @@ function generateCanvasManifest(gitDates, commitSha) { const packageJson = fs.existsSync(packageJsonPath) ? JSON.parse(fs.readFileSync(packageJsonPath, "utf-8")) : {}; - const pluginJsonPath = path.join(PLUGINS_DIR, dir.name, ".github", "plugin", "plugin.json"); + const pluginJsonPath = path.join(PLUGINS_DIR, dir.name, "plugin.json"); const pluginJson = fs.existsSync(pluginJsonPath) ? JSON.parse(fs.readFileSync(pluginJsonPath, "utf-8")) : {}; diff --git a/eng/materialize-plugins.mjs b/eng/materialize-plugins.mjs index 85b8742504..8b42ed1481 100644 --- a/eng/materialize-plugins.mjs +++ b/eng/materialize-plugins.mjs @@ -1 +1,213 @@ -#!/usr/bin/env nodeimport fs from "fs";import path from "path";import { ROOT_FOLDER } from "./constants.mjs";const PLUGINS_DIR = path.join(ROOT_FOLDER, "plugins");const EXTENSIONS_DIR = path.join(ROOT_FOLDER, "extensions");/** * Recursively copy a directory. */function copyDirRecursive(src, dest) { fs.mkdirSync(dest, { recursive: true }); for (const entry of fs.readdirSync(src, { withFileTypes: true })) { const srcPath = path.join(src, entry.name); const destPath = path.join(dest, entry.name); if (entry.isDirectory()) { copyDirRecursive(srcPath, destPath); } else { fs.copyFileSync(srcPath, destPath); } }}/** * Resolve a plugin-relative path to the repo-root source file. * * ./agents/foo.md โ†’ ROOT/agents/foo.agent.md * ./skills/baz/ โ†’ ROOT/skills/baz/ */function resolveSource(relPath) { const basename = path.basename(relPath, ".md"); if (relPath.startsWith("./agents/")) { return path.join(ROOT_FOLDER, "agents", `${basename}.agent.md`); } if (relPath.startsWith("./skills/")) { // Strip trailing slash and get the skill folder name const skillName = relPath.replace(/^\.\/skills\//, "").replace(/\/$/, ""); return path.join(ROOT_FOLDER, "skills", skillName); } if (relPath.startsWith("./extensions/")) { const extensionName = relPath.replace(/^\.\/extensions\//, "").replace(/\/$/, ""); return path.join(ROOT_FOLDER, "extensions", extensionName); } return null;}function readExtensionReferences(pluginPath, pluginName) { const referencesPath = path.join(pluginPath, ".github/plugin/extensions.json"); let references = []; if (fs.existsSync(referencesPath)) { try { references = JSON.parse(fs.readFileSync(referencesPath, "utf8")); } catch (err) { throw new Error(`Failed to parse ${referencesPath}: ${err.message}`); } } if (!Array.isArray(references) || references.some((name) => typeof name !== "string")) { throw new Error(`${referencesPath} must contain an array of extension names`); } const names = new Set(references); if (fs.existsSync(path.join(EXTENSIONS_DIR, pluginName, "extension.mjs"))) { names.add(pluginName); } return [...names].sort();}function materializePlugins() { console.log("Materializing plugin files...\n"); if (!fs.existsSync(PLUGINS_DIR)) { console.error(`Error: Plugins directory not found at ${PLUGINS_DIR}`); process.exit(1); } const pluginDirs = fs.readdirSync(PLUGINS_DIR, { withFileTypes: true }) .filter(entry => entry.isDirectory()) .map(entry => entry.name) .sort(); let totalAgents = 0; let totalSkills = 0; let totalExtensions = 0; let warnings = 0; let errors = 0; for (const dirName of pluginDirs) { const pluginPath = path.join(PLUGINS_DIR, dirName); const pluginJsonPath = path.join(pluginPath, ".github/plugin", "plugin.json"); if (!fs.existsSync(pluginJsonPath)) { continue; } let metadata; try { metadata = JSON.parse(fs.readFileSync(pluginJsonPath, "utf8")); } catch (err) { console.error(`Error: Failed to parse ${pluginJsonPath}: ${err.message}`); errors++; continue; } const pluginName = metadata.name || dirName; // Process agents if (Array.isArray(metadata.agents)) { for (const relPath of metadata.agents) { const src = resolveSource(relPath); if (!src) { console.warn(` โš  ${pluginName}: Unknown path format: ${relPath}`); warnings++; continue; } if (!fs.existsSync(src)) { console.warn(` โš  ${pluginName}: Source not found: ${src}`); warnings++; continue; } const dest = path.join(pluginPath, relPath.replace(/^\.\//, "")); fs.mkdirSync(path.dirname(dest), { recursive: true }); fs.copyFileSync(src, dest); totalAgents++; } } // Process skills if (Array.isArray(metadata.skills)) { for (const relPath of metadata.skills) { const src = resolveSource(relPath); if (!src) { console.warn(` โš  ${pluginName}: Unknown path format: ${relPath}`); warnings++; continue; } if (!fs.existsSync(src) || !fs.statSync(src).isDirectory()) { console.warn(` โš  ${pluginName}: Source directory not found: ${src}`); warnings++; continue; } const dest = path.join(pluginPath, relPath.replace(/^\.\//, "").replace(/\/$/, "")); copyDirRecursive(src, dest); totalSkills++; } } // Process extension references from the build-only extensions.json file. const extensionRefs = readExtensionReferences(pluginPath, pluginName); for (const extensionName of extensionRefs) { const relPath = `./extensions/${extensionName}`; const src = resolveSource(relPath); if (!src) { console.warn(` โš  ${pluginName}: Unknown extension path format: ${relPath}`); warnings++; continue; } if (!fs.existsSync(src) || !fs.statSync(src).isDirectory()) { console.warn(` โš  ${pluginName}: Extension source directory not found: ${src}`); warnings++; continue; } const dest = path.join(pluginPath, relPath.replace(/^\.\//, "").replace(/\/$/, "")); copyDirRecursive(src, dest); totalExtensions++; } // Emit a spec-compliant served manifest for the marketplace branch. // Source manifests keep composition fields (agents and skills) // for build tooling. The served manifest retains only Agent Plugins v1.0.0 fields // so the runtime uses conventional directory discovery for all content. const SPEC_FIELDS = new Set(["$schema", "name", "version", "description", "author", "homepage", "repository", "license", "keywords", "extensions"]); const AGENT_PLUGINS_SCHEMA = "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json"; const served = { "$schema": AGENT_PLUGINS_SCHEMA }; for (const [key, val] of Object.entries(metadata)) { if (SPEC_FIELDS.has(key) && key !== "$schema") { served[key] = val; } } fs.writeFileSync(pluginJsonPath, JSON.stringify(served, null, 2) + "\n", "utf8"); const counts = []; if (metadata.agents?.length) counts.push(`${metadata.agents.length} agents`); if (metadata.skills?.length) counts.push(`${metadata.skills.length} skills`); if (extensionRefs.length) counts.push(`${extensionRefs.length} extensions`); if (counts.length) { console.log(`โœ“ ${pluginName}: ${counts.join(", ")}`); } } console.log(`\nDone. Copied ${totalAgents} agents, ${totalSkills} skills, ${totalExtensions} extensions.`); if (warnings > 0) { console.log(`${warnings} warning(s).`); } if (errors > 0) { console.error(`${errors} error(s).`); process.exit(1); }}materializePlugins(); \ No newline at end of file +#!/usr/bin/env node + +import fs from "fs"; +import path from "path"; +import { ROOT_FOLDER } from "./constants.mjs"; + +const PLUGINS_DIR = path.join(ROOT_FOLDER, "plugins"); +const EXTENSIONS_DIR = path.join(ROOT_FOLDER, "extensions"); +const COPILOT_NAMESPACE = "com.github.copilot"; + +/** + * Recursively copy a directory. + */ +function copyDirRecursive(src, dest) { + fs.mkdirSync(dest, { recursive: true }); + for (const entry of fs.readdirSync(src, { withFileTypes: true })) { + const srcPath = path.join(src, entry.name); + const destPath = path.join(dest, entry.name); + if (entry.isDirectory()) { + copyDirRecursive(srcPath, destPath); + } else { + fs.copyFileSync(srcPath, destPath); + } + } +} + +/** + * Resolve a plugin-relative path to the repo-root source file. + * + * ./agents/foo.md โ†’ ROOT/agents/foo.agent.md + * ./skills/baz/ โ†’ ROOT/skills/baz/ + */ +function resolveSource(relPath) { + const basename = path.basename(relPath, ".md"); + if (relPath.startsWith("./agents/")) { + return path.join(ROOT_FOLDER, "agents", `${basename}.agent.md`); + } + if (relPath.startsWith("./skills/")) { + // Strip trailing slash and get the skill folder name + const skillName = relPath.replace(/^\.\/skills\//, "").replace(/\/$/, ""); + return path.join(ROOT_FOLDER, "skills", skillName); + } + if (relPath.startsWith("./extensions/")) { + const extensionName = relPath.replace(/^\.\/extensions\//, "").replace(/\/$/, ""); + return path.join(ROOT_FOLDER, "extensions", extensionName); + } + return null; +} + +function readExtensionReferences(metadata, pluginName) { + const extensionData = metadata.extensions?.[COPILOT_NAMESPACE]; + const directories = extensionData?.directories ?? []; + if (!Array.isArray(directories) || directories.some((entry) => typeof entry !== "string")) { + throw new Error(`extensions["${COPILOT_NAMESPACE}"].directories must contain plugin-relative paths`); + } + + const names = new Set(directories.map((entry) => + entry.replace(/^\.\/extensions\//, "").replace(/\/$/, "") + )); + if (fs.existsSync(path.join(EXTENSIONS_DIR, pluginName, "extension.mjs"))) { + names.add(pluginName); + } + + return [...names].sort(); +} + +function materializePlugins() { + console.log("Materializing plugin files...\n"); + + if (!fs.existsSync(PLUGINS_DIR)) { + console.error(`Error: Plugins directory not found at ${PLUGINS_DIR}`); + process.exit(1); + } + + const pluginDirs = fs.readdirSync(PLUGINS_DIR, { withFileTypes: true }) + .filter(entry => entry.isDirectory()) + .map(entry => entry.name) + .sort(); + + let totalAgents = 0; + let totalSkills = 0; + let totalExtensions = 0; + let warnings = 0; + let errors = 0; + + for (const dirName of pluginDirs) { + const pluginPath = path.join(PLUGINS_DIR, dirName); + const pluginJsonPath = path.join(pluginPath, "plugin.json"); + + if (!fs.existsSync(pluginJsonPath)) { + continue; + } + + let metadata; + try { + metadata = JSON.parse(fs.readFileSync(pluginJsonPath, "utf8")); + } catch (err) { + console.error(`Error: Failed to parse ${pluginJsonPath}: ${err.message}`); + errors++; + continue; + } + + const pluginName = metadata.name || dirName; + + // Process agents + if (Array.isArray(metadata.agents)) { + for (const relPath of metadata.agents) { + const src = resolveSource(relPath); + if (!src) { + console.warn(` โš  ${pluginName}: Unknown path format: ${relPath}`); + warnings++; + continue; + } + if (!fs.existsSync(src)) { + console.warn(` โš  ${pluginName}: Source not found: ${src}`); + warnings++; + continue; + } + const dest = path.join(pluginPath, relPath.replace(/^\.\//, "")); + fs.mkdirSync(path.dirname(dest), { recursive: true }); + fs.copyFileSync(src, dest); + totalAgents++; + } + } + + // Process skills + if (Array.isArray(metadata.skills)) { + for (const relPath of metadata.skills) { + const src = resolveSource(relPath); + if (!src) { + console.warn(` โš  ${pluginName}: Unknown path format: ${relPath}`); + warnings++; + continue; + } + if (!fs.existsSync(src) || !fs.statSync(src).isDirectory()) { + console.warn(` โš  ${pluginName}: Source directory not found: ${src}`); + warnings++; + continue; + } + const dest = path.join(pluginPath, relPath.replace(/^\.\//, "").replace(/\/$/, "")); + copyDirRecursive(src, dest); + totalSkills++; + } + } + + // Process extension directories declared in the Copilot namespace. + const extensionRefs = readExtensionReferences(metadata, pluginName); + for (const extensionName of extensionRefs) { + const relPath = `./extensions/${extensionName}`; + const src = resolveSource(relPath); + if (!src) { + console.warn(` โš  ${pluginName}: Unknown extension path format: ${relPath}`); + warnings++; + continue; + } + if (!fs.existsSync(src) || !fs.statSync(src).isDirectory()) { + console.warn(` โš  ${pluginName}: Extension source directory not found: ${src}`); + warnings++; + continue; + } + const dest = path.join(pluginPath, COPILOT_NAMESPACE, extensionName); + copyDirRecursive(src, dest); + totalExtensions++; + } + + // Emit a spec-compliant served manifest for the marketplace branch. + // Source manifests keep composition fields (agents and skills) + // for build tooling. The served manifest retains only Agent Plugins v1.0.0 fields + // so the runtime uses conventional directory discovery for all content. + const SPEC_FIELDS = new Set(["$schema", "name", "version", "description", "author", + "homepage", "repository", "license", "keywords", "extensions"]); + const AGENT_PLUGINS_SCHEMA = "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json"; + + const served = { "$schema": AGENT_PLUGINS_SCHEMA }; + for (const [key, val] of Object.entries(metadata)) { + if (SPEC_FIELDS.has(key) && key !== "$schema") { + if (key === "extensions" && val?.[COPILOT_NAMESPACE]?.directories) { + served[key] = { + ...val, + [COPILOT_NAMESPACE]: { + ...val[COPILOT_NAMESPACE], + directories: undefined, + }, + }; + delete served[key][COPILOT_NAMESPACE].directories; + } else { + served[key] = val; + } + } + } + + fs.writeFileSync(pluginJsonPath, JSON.stringify(served, null, 2) + "\n", "utf8"); + + const counts = []; + if (metadata.agents?.length) counts.push(`${metadata.agents.length} agents`); + if (metadata.skills?.length) counts.push(`${metadata.skills.length} skills`); + if (extensionRefs.length) counts.push(`${extensionRefs.length} extensions`); + if (counts.length) { + console.log(`โœ“ ${pluginName}: ${counts.join(", ")}`); + } + } + + console.log(`\nDone. Copied ${totalAgents} agents, ${totalSkills} skills, ${totalExtensions} extensions.`); + if (warnings > 0) { + console.log(`${warnings} warning(s).`); + } + if (errors > 0) { + console.error(`${errors} error(s).`); + process.exit(1); + } +} + +materializePlugins(); diff --git a/eng/update-readme.mjs b/eng/update-readme.mjs index db671b8abe..c75e8f2d16 100644 --- a/eng/update-readme.mjs +++ b/eng/update-readme.mjs @@ -715,7 +715,7 @@ function generateUnifiedModeSection(cfg) { * Read and parse a plugin.json file from a plugin directory. */ function readPluginJson(pluginDir) { - const jsonPath = path.join(pluginDir, ".github/plugin", "plugin.json"); + const jsonPath = path.join(pluginDir, "plugin.json"); if (!fs.existsSync(jsonPath)) return null; try { return JSON.parse(fs.readFileSync(jsonPath, "utf-8")); diff --git a/eng/validate-plugins.mjs b/eng/validate-plugins.mjs index b2ab95825c..6f5c2ce3c4 100755 --- a/eng/validate-plugins.mjs +++ b/eng/validate-plugins.mjs @@ -166,33 +166,31 @@ function validateSpecPaths(plugin) { return errors; } -function validateExtensionReferences(pluginDir) { +function validateExtensionReferences(plugin, pluginDir) { const errors = []; - const referencesPath = path.join(pluginDir, ".github/plugin/extensions.json"); - if (!fs.existsSync(referencesPath)) { + const directories = plugin.extensions?.[COPILOT_NAMESPACE]?.directories; + if (directories === undefined) { return errors; } - - const references = parseJsonFile(referencesPath); - if (references.parseError) { - errors.push(`failed to parse extensions.json: ${references.parseError}`); - return errors; - } - if (!Array.isArray(references)) { - errors.push("extensions.json must contain an array of extension names"); + if (!Array.isArray(directories)) { + errors.push(`extensions["${COPILOT_NAMESPACE}"].directories must be an array`); return errors; } - if (!arraysEqual(references, sortPluginEntries(references))) { - errors.push("extensions.json entries must be sorted alphabetically"); + if (!arraysEqual(directories, sortPluginEntries(directories))) { + errors.push(`extensions["${COPILOT_NAMESPACE}"].directories entries must be sorted alphabetically`); } - for (const [index, name] of references.entries()) { - if (typeof name !== "string" || !/^[a-z0-9][a-z0-9.-]*[a-z0-9]$|^[a-z0-9]$/.test(name)) { - errors.push(`extensions.json[${index}] must be a valid extension name`); + for (const [index, directory] of directories.entries()) { + const name = typeof directory === "string" + ? directory.replace(/^\.\/extensions\//, "").replace(/\/$/, "") + : ""; + if (typeof directory !== "string" || !directory.startsWith("./extensions/") || + !/^[a-z0-9][a-z0-9.-]*[a-z0-9]$|^[a-z0-9]$/.test(name)) { + errors.push(`extensions["${COPILOT_NAMESPACE}"].directories[${index}] must be a valid ./extensions/ path`); continue; } if (!fs.existsSync(path.join(EXTENSIONS_DIR, name, "extension.mjs"))) { - errors.push(`extensions.json[${index}] source not found: extensions/${name}`); + errors.push(`extensions["${COPILOT_NAMESPACE}"].directories[${index}] source not found: extensions/${name}`); } } @@ -206,10 +204,10 @@ function validatePlugin(folderName) { const extensionDir = path.join(EXTENSIONS_DIR, folderName); const isExtensionPlugin = fs.existsSync(path.join(extensionDir, "extension.mjs")); - // Rule 1: Must have .github/plugin/plugin.json - const pluginJsonPath = path.join(pluginDir, ".github/plugin", "plugin.json"); + // Rule 1: Must have plugin.json at the plugin root + const pluginJsonPath = path.join(pluginDir, "plugin.json"); if (!fs.existsSync(pluginJsonPath)) { - errors.push("missing required file: .github/plugin/plugin.json"); + errors.push("missing required file: plugin.json"); return errors; } @@ -258,7 +256,7 @@ function validatePlugin(folderName) { const specErrors = validateSpecPaths(plugin); errors.push(...specErrors); - const extensionRefErrors = validateExtensionReferences(pluginDir); + const extensionRefErrors = validateExtensionReferences(plugin, pluginDir); errors.push(...extensionRefErrors); if (isExtensionPlugin) { @@ -334,9 +332,9 @@ function validatePlugins() { } for (const dir of getExtensionFolderNames()) { - const pluginJsonPath = path.join(PLUGINS_DIR, dir, ".github/plugin/plugin.json"); + const pluginJsonPath = path.join(PLUGINS_DIR, dir, "plugin.json"); if (!fs.existsSync(pluginJsonPath)) { - console.error(`โŒ extension ${dir}: missing plugin manifest at plugins/${dir}/.github/plugin/plugin.json`); + console.error(`โŒ extension ${dir}: missing plugin manifest at plugins/${dir}/plugin.json`); hasErrors = true; } } diff --git a/plugins/accessibility-kanban/.github/plugin/plugin.json b/plugins/accessibility-kanban/plugin.json similarity index 83% rename from plugins/accessibility-kanban/.github/plugin/plugin.json rename to plugins/accessibility-kanban/plugin.json index 44675fc640..b9e1b3dd9e 100644 --- a/plugins/accessibility-kanban/.github/plugin/plugin.json +++ b/plugins/accessibility-kanban/plugin.json @@ -17,7 +17,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png" + "logo": "assets/preview.png", + "directories": [ + "./extensions/accessibility-kanban" + ] } } } diff --git a/plugins/acreadiness-cockpit/.github/plugin/plugin.json b/plugins/acreadiness-cockpit/plugin.json similarity index 100% rename from plugins/acreadiness-cockpit/.github/plugin/plugin.json rename to plugins/acreadiness-cockpit/plugin.json diff --git a/plugins/ai-team-orchestration/.github/plugin/plugin.json b/plugins/ai-team-orchestration/plugin.json similarity index 100% rename from plugins/ai-team-orchestration/.github/plugin/plugin.json rename to plugins/ai-team-orchestration/plugin.json diff --git a/plugins/apng-studio/.github/plugin/plugin.json b/plugins/apng-studio/plugin.json similarity index 87% rename from plugins/apng-studio/.github/plugin/plugin.json rename to plugins/apng-studio/plugin.json index 4fa9da34c8..51827d28df 100644 --- a/plugins/apng-studio/.github/plugin/plugin.json +++ b/plugins/apng-studio/plugin.json @@ -17,7 +17,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png" + "logo": "assets/preview.png", + "directories": [ + "./extensions/apng-studio" + ] } } } diff --git a/plugins/arcade-canvas/.github/plugin/plugin.json b/plugins/arcade-canvas/plugin.json similarity index 82% rename from plugins/arcade-canvas/.github/plugin/plugin.json rename to plugins/arcade-canvas/plugin.json index 7f2b7abea4..6d48e2d527 100644 --- a/plugins/arcade-canvas/.github/plugin/plugin.json +++ b/plugins/arcade-canvas/plugin.json @@ -17,7 +17,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png" + "logo": "assets/preview.png", + "directories": [ + "./extensions/arcade-canvas" + ] } } } diff --git a/plugins/arch/.github/plugin/plugin.json b/plugins/arch/plugin.json similarity index 100% rename from plugins/arch/.github/plugin/plugin.json rename to plugins/arch/plugin.json diff --git a/plugins/arize-ax/.github/plugin/plugin.json b/plugins/arize-ax/plugin.json similarity index 100% rename from plugins/arize-ax/.github/plugin/plugin.json rename to plugins/arize-ax/plugin.json diff --git a/plugins/automate-this/.github/plugin/plugin.json b/plugins/automate-this/plugin.json similarity index 100% rename from plugins/automate-this/.github/plugin/plugin.json rename to plugins/automate-this/plugin.json diff --git a/plugins/awesome-copilot/.github/plugin/plugin.json b/plugins/awesome-copilot/plugin.json similarity index 100% rename from plugins/awesome-copilot/.github/plugin/plugin.json rename to plugins/awesome-copilot/plugin.json diff --git a/plugins/aws-cloud-development/.github/plugin/plugin.json b/plugins/aws-cloud-development/plugin.json similarity index 100% rename from plugins/aws-cloud-development/.github/plugin/plugin.json rename to plugins/aws-cloud-development/plugin.json diff --git a/plugins/azure-cloud-development/.github/plugin/plugin.json b/plugins/azure-cloud-development/plugin.json similarity index 100% rename from plugins/azure-cloud-development/.github/plugin/plugin.json rename to plugins/azure-cloud-development/plugin.json diff --git a/plugins/backlog-swipe-triage/.github/plugin/plugin.json b/plugins/backlog-swipe-triage/plugin.json similarity index 83% rename from plugins/backlog-swipe-triage/.github/plugin/plugin.json rename to plugins/backlog-swipe-triage/plugin.json index 8bd19eebf8..5aa5ffa52a 100644 --- a/plugins/backlog-swipe-triage/.github/plugin/plugin.json +++ b/plugins/backlog-swipe-triage/plugin.json @@ -17,7 +17,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png" + "logo": "assets/preview.png", + "directories": [ + "./extensions/backlog-swipe-triage" + ] } } } diff --git a/plugins/backrooms-canvas/.github/plugin/plugin.json b/plugins/backrooms-canvas/plugin.json similarity index 84% rename from plugins/backrooms-canvas/.github/plugin/plugin.json rename to plugins/backrooms-canvas/plugin.json index be4b090169..19827b171c 100644 --- a/plugins/backrooms-canvas/.github/plugin/plugin.json +++ b/plugins/backrooms-canvas/plugin.json @@ -16,7 +16,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png" + "logo": "assets/preview.png", + "directories": [ + "./extensions/backrooms-canvas" + ] } }, "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json" diff --git a/plugins/cast-imaging/.github/plugin/plugin.json b/plugins/cast-imaging/plugin.json similarity index 100% rename from plugins/cast-imaging/.github/plugin/plugin.json rename to plugins/cast-imaging/plugin.json diff --git a/plugins/chromium-control-canvas/.github/plugin/plugin.json b/plugins/chromium-control-canvas/plugin.json similarity index 84% rename from plugins/chromium-control-canvas/.github/plugin/plugin.json rename to plugins/chromium-control-canvas/plugin.json index ef04d64897..32b933cb01 100644 --- a/plugins/chromium-control-canvas/.github/plugin/plugin.json +++ b/plugins/chromium-control-canvas/plugin.json @@ -18,7 +18,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png" + "logo": "assets/preview.png", + "directories": [ + "./extensions/chromium-control-canvas" + ] } } } diff --git a/plugins/clojure-interactive-programming/.github/plugin/plugin.json b/plugins/clojure-interactive-programming/plugin.json similarity index 100% rename from plugins/clojure-interactive-programming/.github/plugin/plugin.json rename to plugins/clojure-interactive-programming/plugin.json diff --git a/plugins/cms-development/.github/plugin/plugin.json b/plugins/cms-development/plugin.json similarity index 100% rename from plugins/cms-development/.github/plugin/plugin.json rename to plugins/cms-development/plugin.json diff --git a/plugins/color-orb/.github/plugin/plugin.json b/plugins/color-orb/plugin.json similarity index 84% rename from plugins/color-orb/.github/plugin/plugin.json rename to plugins/color-orb/plugin.json index 295ea957fa..c5d9ff790c 100644 --- a/plugins/color-orb/.github/plugin/plugin.json +++ b/plugins/color-orb/plugin.json @@ -17,7 +17,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png" + "logo": "assets/preview.png", + "directories": [ + "./extensions/color-orb" + ] } } } diff --git a/plugins/context-engineering/.github/plugin/plugin.json b/plugins/context-engineering/plugin.json similarity index 100% rename from plugins/context-engineering/.github/plugin/plugin.json rename to plugins/context-engineering/plugin.json diff --git a/plugins/context-matic/.github/plugin/plugin.json b/plugins/context-matic/plugin.json similarity index 100% rename from plugins/context-matic/.github/plugin/plugin.json rename to plugins/context-matic/plugin.json diff --git a/plugins/convert-to-md/.github/plugin/plugin.json b/plugins/convert-to-md/plugin.json similarity index 100% rename from plugins/convert-to-md/.github/plugin/plugin.json rename to plugins/convert-to-md/plugin.json diff --git a/plugins/copilot-sdk/.github/plugin/plugin.json b/plugins/copilot-sdk/plugin.json similarity index 100% rename from plugins/copilot-sdk/.github/plugin/plugin.json rename to plugins/copilot-sdk/plugin.json diff --git a/plugins/csharp-dotnet-development/.github/plugin/plugin.json b/plugins/csharp-dotnet-development/plugin.json similarity index 100% rename from plugins/csharp-dotnet-development/.github/plugin/plugin.json rename to plugins/csharp-dotnet-development/plugin.json diff --git a/plugins/database-data-management/.github/plugin/plugin.json b/plugins/database-data-management/plugin.json similarity index 100% rename from plugins/database-data-management/.github/plugin/plugin.json rename to plugins/database-data-management/plugin.json diff --git a/plugins/dataverse-sdk-for-python/.github/plugin/plugin.json b/plugins/dataverse-sdk-for-python/plugin.json similarity index 100% rename from plugins/dataverse-sdk-for-python/.github/plugin/plugin.json rename to plugins/dataverse-sdk-for-python/plugin.json diff --git a/plugins/devops-oncall/.github/plugin/plugin.json b/plugins/devops-oncall/plugin.json similarity index 100% rename from plugins/devops-oncall/.github/plugin/plugin.json rename to plugins/devops-oncall/plugin.json diff --git a/plugins/diagram-viewer/.github/plugin/plugin.json b/plugins/diagram-viewer/plugin.json similarity index 84% rename from plugins/diagram-viewer/.github/plugin/plugin.json rename to plugins/diagram-viewer/plugin.json index 2117a86f36..d9be58b1e8 100644 --- a/plugins/diagram-viewer/.github/plugin/plugin.json +++ b/plugins/diagram-viewer/plugin.json @@ -17,7 +17,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png" + "logo": "assets/preview.png", + "directories": [ + "./extensions/diagram-viewer" + ] } } } diff --git a/plugins/doublecheck/.github/plugin/plugin.json b/plugins/doublecheck/plugin.json similarity index 100% rename from plugins/doublecheck/.github/plugin/plugin.json rename to plugins/doublecheck/plugin.json diff --git a/plugins/edge-ai-tasks/.github/plugin/plugin.json b/plugins/edge-ai-tasks/plugin.json similarity index 100% rename from plugins/edge-ai-tasks/.github/plugin/plugin.json rename to plugins/edge-ai-tasks/plugin.json diff --git a/plugins/ember/.github/plugin/plugin.json b/plugins/ember/plugin.json similarity index 100% rename from plugins/ember/.github/plugin/plugin.json rename to plugins/ember/plugin.json diff --git a/plugins/eyeball/.github/plugin/plugin.json b/plugins/eyeball/plugin.json similarity index 100% rename from plugins/eyeball/.github/plugin/plugin.json rename to plugins/eyeball/plugin.json diff --git a/plugins/fastah-ip-geo-tools/.github/plugin/plugin.json b/plugins/fastah-ip-geo-tools/plugin.json similarity index 100% rename from plugins/fastah-ip-geo-tools/.github/plugin/plugin.json rename to plugins/fastah-ip-geo-tools/plugin.json diff --git a/plugins/feedback-themes/.github/plugin/plugin.json b/plugins/feedback-themes/plugin.json similarity index 84% rename from plugins/feedback-themes/.github/plugin/plugin.json rename to plugins/feedback-themes/plugin.json index fd4ea6aaa9..c1f0ca1715 100644 --- a/plugins/feedback-themes/.github/plugin/plugin.json +++ b/plugins/feedback-themes/plugin.json @@ -17,7 +17,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png" + "logo": "assets/preview.png", + "directories": [ + "./extensions/feedback-themes" + ] } } } diff --git a/plugins/flight-map-canvas/.github/plugin/plugin.json b/plugins/flight-map-canvas/plugin.json similarity index 85% rename from plugins/flight-map-canvas/.github/plugin/plugin.json rename to plugins/flight-map-canvas/plugin.json index eaa6fe14dc..d1d3fc7e68 100644 --- a/plugins/flight-map-canvas/.github/plugin/plugin.json +++ b/plugins/flight-map-canvas/plugin.json @@ -17,7 +17,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png" + "logo": "assets/preview.png", + "directories": [ + "./extensions/flight-map-canvas" + ] } }, "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json" diff --git a/plugins/flowstudio-power-automate/.github/plugin/plugin.json b/plugins/flowstudio-power-automate/plugin.json similarity index 100% rename from plugins/flowstudio-power-automate/.github/plugin/plugin.json rename to plugins/flowstudio-power-automate/plugin.json diff --git a/plugins/frontend-web-dev/.github/plugin/plugin.json b/plugins/frontend-web-dev/plugin.json similarity index 100% rename from plugins/frontend-web-dev/.github/plugin/plugin.json rename to plugins/frontend-web-dev/plugin.json diff --git a/plugins/gem-team/.github/plugin/plugin.json b/plugins/gem-team/plugin.json similarity index 68% rename from plugins/gem-team/.github/plugin/plugin.json rename to plugins/gem-team/plugin.json index c784b39a8c..f30fa8b3c5 100644 --- a/plugins/gem-team/.github/plugin/plugin.json +++ b/plugins/gem-team/plugin.json @@ -1,14 +1,13 @@ { "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "gem-team", - "version": "1.80.0", + "version": "1.87.0", "description": "Self-Learning Multi-agent orchestration framework for spec-driven development and automated verification. With smarter tool calling and leaner context.", "author": { "email": "mubaidr@gmail.com", "name": "mubaidr", "url": "https://github.com/mubaidr" }, - "description": "Self-Learning Multi-agent orchestration framework for spec-driven development and automated verification. With smarter tool calling and leaner context.", "homepage": "https://github.com/mubaidr/gem-team", "keywords": [ "multi-agent", @@ -23,7 +22,5 @@ "mobile" ], "license": "Apache-2.0", - "name": "gem-team", - "repository": "https://github.com/mubaidr/gem-team", - "version": "1.87.0" + "repository": "https://github.com/mubaidr/gem-team" } diff --git a/plugins/gesture-review/.github/plugin/plugin.json b/plugins/gesture-review/plugin.json similarity index 83% rename from plugins/gesture-review/.github/plugin/plugin.json rename to plugins/gesture-review/plugin.json index c7bd4c32fd..5c26cb8d28 100644 --- a/plugins/gesture-review/.github/plugin/plugin.json +++ b/plugins/gesture-review/plugin.json @@ -17,7 +17,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png" + "logo": "assets/preview.png", + "directories": [ + "./extensions/gesture-review" + ] } } } diff --git a/plugins/go-mcp-development/.github/plugin/plugin.json b/plugins/go-mcp-development/plugin.json similarity index 100% rename from plugins/go-mcp-development/.github/plugin/plugin.json rename to plugins/go-mcp-development/plugin.json diff --git a/plugins/java-development/.github/plugin/plugin.json b/plugins/java-development/plugin.json similarity index 100% rename from plugins/java-development/.github/plugin/plugin.json rename to plugins/java-development/plugin.json diff --git a/plugins/java-mcp-development/.github/plugin/plugin.json b/plugins/java-mcp-development/plugin.json similarity index 100% rename from plugins/java-mcp-development/.github/plugin/plugin.json rename to plugins/java-mcp-development/plugin.json diff --git a/plugins/java-modernization-studio/.github/plugin/plugin.json b/plugins/java-modernization-studio/plugin.json similarity index 86% rename from plugins/java-modernization-studio/.github/plugin/plugin.json rename to plugins/java-modernization-studio/plugin.json index 7085eb7ce2..a28e3643e9 100644 --- a/plugins/java-modernization-studio/.github/plugin/plugin.json +++ b/plugins/java-modernization-studio/plugin.json @@ -18,7 +18,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png" + "logo": "assets/preview.png", + "directories": [ + "./extensions/java-modernization-studio" + ] } } } diff --git a/plugins/kotlin-mcp-development/.github/plugin/plugin.json b/plugins/kotlin-mcp-development/plugin.json similarity index 100% rename from plugins/kotlin-mcp-development/.github/plugin/plugin.json rename to plugins/kotlin-mcp-development/plugin.json diff --git a/plugins/mcp-m365-copilot/.github/plugin/plugin.json b/plugins/mcp-m365-copilot/plugin.json similarity index 100% rename from plugins/mcp-m365-copilot/.github/plugin/plugin.json rename to plugins/mcp-m365-copilot/plugin.json diff --git a/plugins/napkin/.github/plugin/plugin.json b/plugins/napkin/plugin.json similarity index 100% rename from plugins/napkin/.github/plugin/plugin.json rename to plugins/napkin/plugin.json diff --git a/plugins/noob-mode/.github/plugin/plugin.json b/plugins/noob-mode/plugin.json similarity index 100% rename from plugins/noob-mode/.github/plugin/plugin.json rename to plugins/noob-mode/plugin.json diff --git a/plugins/openapi-to-application-csharp-dotnet/.github/plugin/plugin.json b/plugins/openapi-to-application-csharp-dotnet/plugin.json similarity index 100% rename from plugins/openapi-to-application-csharp-dotnet/.github/plugin/plugin.json rename to plugins/openapi-to-application-csharp-dotnet/plugin.json diff --git a/plugins/openapi-to-application-go/.github/plugin/plugin.json b/plugins/openapi-to-application-go/plugin.json similarity index 100% rename from plugins/openapi-to-application-go/.github/plugin/plugin.json rename to plugins/openapi-to-application-go/plugin.json diff --git a/plugins/openapi-to-application-java-spring-boot/.github/plugin/plugin.json b/plugins/openapi-to-application-java-spring-boot/plugin.json similarity index 100% rename from plugins/openapi-to-application-java-spring-boot/.github/plugin/plugin.json rename to plugins/openapi-to-application-java-spring-boot/plugin.json diff --git a/plugins/openapi-to-application-nodejs-nestjs/.github/plugin/plugin.json b/plugins/openapi-to-application-nodejs-nestjs/plugin.json similarity index 100% rename from plugins/openapi-to-application-nodejs-nestjs/.github/plugin/plugin.json rename to plugins/openapi-to-application-nodejs-nestjs/plugin.json diff --git a/plugins/openapi-to-application-python-fastapi/.github/plugin/plugin.json b/plugins/openapi-to-application-python-fastapi/plugin.json similarity index 100% rename from plugins/openapi-to-application-python-fastapi/.github/plugin/plugin.json rename to plugins/openapi-to-application-python-fastapi/plugin.json diff --git a/plugins/oracle-to-postgres-migration-expert/.github/plugin/plugin.json b/plugins/oracle-to-postgres-migration-expert/plugin.json similarity index 100% rename from plugins/oracle-to-postgres-migration-expert/.github/plugin/plugin.json rename to plugins/oracle-to-postgres-migration-expert/plugin.json diff --git a/plugins/ospo-sponsorship/.github/plugin/plugin.json b/plugins/ospo-sponsorship/plugin.json similarity index 100% rename from plugins/ospo-sponsorship/.github/plugin/plugin.json rename to plugins/ospo-sponsorship/plugin.json diff --git a/plugins/partners/.github/plugin/plugin.json b/plugins/partners/plugin.json similarity index 100% rename from plugins/partners/.github/plugin/plugin.json rename to plugins/partners/plugin.json diff --git a/plugins/pcf-development/.github/plugin/plugin.json b/plugins/pcf-development/plugin.json similarity index 100% rename from plugins/pcf-development/.github/plugin/plugin.json rename to plugins/pcf-development/plugin.json diff --git a/plugins/phoenix/.github/plugin/plugin.json b/plugins/phoenix/plugin.json similarity index 100% rename from plugins/phoenix/.github/plugin/plugin.json rename to plugins/phoenix/plugin.json diff --git a/plugins/php-mcp-development/.github/plugin/plugin.json b/plugins/php-mcp-development/plugin.json similarity index 100% rename from plugins/php-mcp-development/.github/plugin/plugin.json rename to plugins/php-mcp-development/plugin.json diff --git a/plugins/power-apps-code-apps/.github/plugin/plugin.json b/plugins/power-apps-code-apps/plugin.json similarity index 100% rename from plugins/power-apps-code-apps/.github/plugin/plugin.json rename to plugins/power-apps-code-apps/plugin.json diff --git a/plugins/power-bi-development/.github/plugin/plugin.json b/plugins/power-bi-development/plugin.json similarity index 100% rename from plugins/power-bi-development/.github/plugin/plugin.json rename to plugins/power-bi-development/plugin.json diff --git a/plugins/power-platform-architect/.github/plugin/plugin.json b/plugins/power-platform-architect/plugin.json similarity index 100% rename from plugins/power-platform-architect/.github/plugin/plugin.json rename to plugins/power-platform-architect/plugin.json diff --git a/plugins/power-platform-mcp-connector-development/.github/plugin/plugin.json b/plugins/power-platform-mcp-connector-development/plugin.json similarity index 100% rename from plugins/power-platform-mcp-connector-development/.github/plugin/plugin.json rename to plugins/power-platform-mcp-connector-development/plugin.json diff --git a/plugins/pr-artifact-explorer/.github/plugin/plugin.json b/plugins/pr-artifact-explorer/plugin.json similarity index 84% rename from plugins/pr-artifact-explorer/.github/plugin/plugin.json rename to plugins/pr-artifact-explorer/plugin.json index b94608f051..c15f3919be 100644 --- a/plugins/pr-artifact-explorer/.github/plugin/plugin.json +++ b/plugins/pr-artifact-explorer/plugin.json @@ -17,7 +17,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png" + "logo": "assets/preview.png", + "directories": [ + "./extensions/pr-artifact-explorer" + ] } }, "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json" diff --git a/plugins/project-documenter/.github/plugin/plugin.json b/plugins/project-documenter/plugin.json similarity index 100% rename from plugins/project-documenter/.github/plugin/plugin.json rename to plugins/project-documenter/plugin.json diff --git a/plugins/project-planning/.github/plugin/plugin.json b/plugins/project-planning/plugin.json similarity index 100% rename from plugins/project-planning/.github/plugin/plugin.json rename to plugins/project-planning/plugin.json diff --git a/plugins/python-mcp-development/.github/plugin/plugin.json b/plugins/python-mcp-development/plugin.json similarity index 100% rename from plugins/python-mcp-development/.github/plugin/plugin.json rename to plugins/python-mcp-development/plugin.json diff --git a/plugins/react18-upgrade/.github/plugin/plugin.json b/plugins/react18-upgrade/plugin.json similarity index 100% rename from plugins/react18-upgrade/.github/plugin/plugin.json rename to plugins/react18-upgrade/plugin.json diff --git a/plugins/react19-upgrade/.github/plugin/plugin.json b/plugins/react19-upgrade/plugin.json similarity index 100% rename from plugins/react19-upgrade/.github/plugin/plugin.json rename to plugins/react19-upgrade/plugin.json diff --git a/plugins/release-notes-showcase/.github/plugin/plugin.json b/plugins/release-notes-showcase/plugin.json similarity index 83% rename from plugins/release-notes-showcase/.github/plugin/plugin.json rename to plugins/release-notes-showcase/plugin.json index 1b27af5523..034950661e 100644 --- a/plugins/release-notes-showcase/.github/plugin/plugin.json +++ b/plugins/release-notes-showcase/plugin.json @@ -17,7 +17,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png" + "logo": "assets/preview.png", + "directories": [ + "./extensions/release-notes-showcase" + ] } } } diff --git a/plugins/repo-actions-hub/.github/plugin/plugin.json b/plugins/repo-actions-hub/plugin.json similarity index 84% rename from plugins/repo-actions-hub/.github/plugin/plugin.json rename to plugins/repo-actions-hub/plugin.json index 35f733c63c..de30aaf02b 100644 --- a/plugins/repo-actions-hub/.github/plugin/plugin.json +++ b/plugins/repo-actions-hub/plugin.json @@ -17,7 +17,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png" + "logo": "assets/preview.png", + "directories": [ + "./extensions/repo-actions-hub" + ] } } } diff --git a/plugins/roundup/.github/plugin/plugin.json b/plugins/roundup/plugin.json similarity index 100% rename from plugins/roundup/.github/plugin/plugin.json rename to plugins/roundup/plugin.json diff --git a/plugins/ruby-mcp-development/.github/plugin/plugin.json b/plugins/ruby-mcp-development/plugin.json similarity index 100% rename from plugins/ruby-mcp-development/.github/plugin/plugin.json rename to plugins/ruby-mcp-development/plugin.json diff --git a/plugins/rug-agentic-workflow/.github/plugin/plugin.json b/plugins/rug-agentic-workflow/plugin.json similarity index 100% rename from plugins/rug-agentic-workflow/.github/plugin/plugin.json rename to plugins/rug-agentic-workflow/plugin.json diff --git a/plugins/rust-mcp-development/.github/plugin/plugin.json b/plugins/rust-mcp-development/plugin.json similarity index 100% rename from plugins/rust-mcp-development/.github/plugin/plugin.json rename to plugins/rust-mcp-development/plugin.json diff --git a/plugins/salesforce-development/.github/plugin/plugin.json b/plugins/salesforce-development/plugin.json similarity index 100% rename from plugins/salesforce-development/.github/plugin/plugin.json rename to plugins/salesforce-development/plugin.json diff --git a/plugins/security-best-practices/.github/plugin/plugin.json b/plugins/security-best-practices/plugin.json similarity index 100% rename from plugins/security-best-practices/.github/plugin/plugin.json rename to plugins/security-best-practices/plugin.json diff --git a/plugins/signals-dashboard/.github/plugin/plugin.json b/plugins/signals-dashboard/plugin.json similarity index 85% rename from plugins/signals-dashboard/.github/plugin/plugin.json rename to plugins/signals-dashboard/plugin.json index 8254896ad9..6efe14fd32 100644 --- a/plugins/signals-dashboard/.github/plugin/plugin.json +++ b/plugins/signals-dashboard/plugin.json @@ -15,7 +15,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png" + "logo": "assets/preview.png", + "directories": [ + "./extensions/signals-dashboard" + ] } }, "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json" diff --git a/plugins/site-studio/.github/plugin/plugin.json b/plugins/site-studio/plugin.json similarity index 85% rename from plugins/site-studio/.github/plugin/plugin.json rename to plugins/site-studio/plugin.json index 44abf07fd6..0762279880 100644 --- a/plugins/site-studio/.github/plugin/plugin.json +++ b/plugins/site-studio/plugin.json @@ -17,7 +17,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png" + "logo": "assets/preview.png", + "directories": [ + "./extensions/site-studio" + ] } } } diff --git a/plugins/skill-image-gen/.github/plugin/plugin.json b/plugins/skill-image-gen/plugin.json similarity index 100% rename from plugins/skill-image-gen/.github/plugin/plugin.json rename to plugins/skill-image-gen/plugin.json diff --git a/plugins/software-engineering-team/.github/plugin/plugin.json b/plugins/software-engineering-team/plugin.json similarity index 100% rename from plugins/software-engineering-team/.github/plugin/plugin.json rename to plugins/software-engineering-team/plugin.json diff --git a/plugins/structured-autonomy/.github/plugin/plugin.json b/plugins/structured-autonomy/plugin.json similarity index 100% rename from plugins/structured-autonomy/.github/plugin/plugin.json rename to plugins/structured-autonomy/plugin.json diff --git a/plugins/swift-mcp-development/.github/plugin/plugin.json b/plugins/swift-mcp-development/plugin.json similarity index 100% rename from plugins/swift-mcp-development/.github/plugin/plugin.json rename to plugins/swift-mcp-development/plugin.json diff --git a/plugins/technical-spike/.github/plugin/plugin.json b/plugins/technical-spike/plugin.json similarity index 100% rename from plugins/technical-spike/.github/plugin/plugin.json rename to plugins/technical-spike/plugin.json diff --git a/plugins/testing-automation/.github/plugin/plugin.json b/plugins/testing-automation/plugin.json similarity index 100% rename from plugins/testing-automation/.github/plugin/plugin.json rename to plugins/testing-automation/plugin.json diff --git a/plugins/the-workshop/.github/plugin/plugin.json b/plugins/the-workshop/plugin.json similarity index 86% rename from plugins/the-workshop/.github/plugin/plugin.json rename to plugins/the-workshop/plugin.json index 36ffb574cc..705cf8e0ca 100644 --- a/plugins/the-workshop/.github/plugin/plugin.json +++ b/plugins/the-workshop/plugin.json @@ -25,5 +25,12 @@ "./skills/desk-open/", "./skills/signal-write/", "./skills/workshop-create/" - ] + ], + "extensions": { + "com.github.copilot": { + "directories": [ + "./extensions/signals-dashboard" + ] + } + } } diff --git a/plugins/tiny-tool-town-submitter/.github/plugin/plugin.json b/plugins/tiny-tool-town-submitter/plugin.json similarity index 83% rename from plugins/tiny-tool-town-submitter/.github/plugin/plugin.json rename to plugins/tiny-tool-town-submitter/plugin.json index 1609e6b33d..04f639ffb2 100644 --- a/plugins/tiny-tool-town-submitter/.github/plugin/plugin.json +++ b/plugins/tiny-tool-town-submitter/plugin.json @@ -17,7 +17,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png" + "logo": "assets/preview.png", + "directories": [ + "./extensions/tiny-tool-town-submitter" + ] } } } diff --git a/plugins/token-pacman/.github/plugin/plugin.json b/plugins/token-pacman/plugin.json similarity index 84% rename from plugins/token-pacman/.github/plugin/plugin.json rename to plugins/token-pacman/plugin.json index 6ac2a6c743..eee9a94a0c 100644 --- a/plugins/token-pacman/.github/plugin/plugin.json +++ b/plugins/token-pacman/plugin.json @@ -17,7 +17,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png" + "logo": "assets/preview.png", + "directories": [ + "./extensions/token-pacman" + ] } } } diff --git a/plugins/typescript-mcp-development/.github/plugin/plugin.json b/plugins/typescript-mcp-development/plugin.json similarity index 100% rename from plugins/typescript-mcp-development/.github/plugin/plugin.json rename to plugins/typescript-mcp-development/plugin.json diff --git a/plugins/typespec-m365-copilot/.github/plugin/plugin.json b/plugins/typespec-m365-copilot/plugin.json similarity index 100% rename from plugins/typespec-m365-copilot/.github/plugin/plugin.json rename to plugins/typespec-m365-copilot/plugin.json diff --git a/plugins/uizze/.github/plugin/plugin.json b/plugins/uizze/plugin.json similarity index 100% rename from plugins/uizze/.github/plugin/plugin.json rename to plugins/uizze/plugin.json diff --git a/plugins/visual-pr/.github/plugin/plugin.json b/plugins/visual-pr/plugin.json similarity index 100% rename from plugins/visual-pr/.github/plugin/plugin.json rename to plugins/visual-pr/plugin.json diff --git a/plugins/where-was-i/.github/plugin/plugin.json b/plugins/where-was-i/plugin.json similarity index 84% rename from plugins/where-was-i/.github/plugin/plugin.json rename to plugins/where-was-i/plugin.json index a3ecdf4c09..d501f2b105 100644 --- a/plugins/where-was-i/.github/plugin/plugin.json +++ b/plugins/where-was-i/plugin.json @@ -17,7 +17,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png" + "logo": "assets/preview.png", + "directories": [ + "./extensions/where-was-i" + ] } } } diff --git a/plugins/work-hub/.github/plugin/plugin.json b/plugins/work-hub/plugin.json similarity index 85% rename from plugins/work-hub/.github/plugin/plugin.json rename to plugins/work-hub/plugin.json index b744b39fdf..cff115fbf0 100644 --- a/plugins/work-hub/.github/plugin/plugin.json +++ b/plugins/work-hub/plugin.json @@ -17,7 +17,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png" + "logo": "assets/preview.png", + "directories": [ + "./extensions/work-hub" + ] } } } From 1cec5e579c0d7513978a95edd17c6aa178594c55 Mon Sep 17 00:00:00 2001 From: Aaron Powell Date: Thu, 6 Aug 2026 11:35:20 +1000 Subject: [PATCH 8/8] feat(plugins): migrate manifests to namespaced composition Move repository composition metadata under com.github.awesome-copilot, materialize reusable extensions into the plugin extensions directory, and improve contributor and PR validation guidance. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8f3a88cb-e01e-4760-8125-460490dc1a76 --- .../skills/create-canvas-extension/SKILL.md | 29 ++++--- .github/workflows/validate-plugins.yml | 7 +- AGENTS.md | 10 +-- CONTRIBUTING.md | 18 ++-- eng/create-plugin.mjs | 6 ++ eng/generate-website-data.mjs | 19 +++-- eng/materialize-plugins.mjs | 82 +++++++++---------- eng/update-readme.mjs | 14 ++-- eng/validate-plugins.mjs | 64 +++++++++++---- plugins/accessibility-kanban/plugin.json | 6 +- plugins/acreadiness-cockpit/plugin.json | 20 +++-- plugins/ai-team-orchestration/plugin.json | 20 +++-- plugins/apng-studio/plugin.json | 6 +- plugins/arcade-canvas/plugin.json | 6 +- plugins/arch/plugin.json | 10 ++- plugins/arize-ax/plugin.json | 26 +++--- plugins/automate-this/plugin.json | 10 ++- plugins/awesome-copilot/plugin.json | 22 +++-- plugins/aws-cloud-development/plugin.json | 28 ++++--- plugins/azure-cloud-development/plugin.json | 34 ++++---- plugins/backlog-swipe-triage/plugin.json | 6 +- plugins/backrooms-canvas/plugin.json | 6 +- plugins/cast-imaging/plugin.json | 14 ++-- plugins/chromium-control-canvas/plugin.json | 6 +- .../plugin.json | 16 ++-- plugins/cms-development/plugin.json | 14 ++-- plugins/color-orb/plugin.json | 6 +- plugins/context-engineering/plugin.json | 20 +++-- plugins/context-matic/plugin.json | 12 ++- plugins/convert-to-md/plugin.json | 14 ++-- plugins/copilot-sdk/plugin.json | 10 ++- plugins/csharp-dotnet-development/plugin.json | 30 ++++--- plugins/database-data-management/plugin.json | 24 +++--- plugins/dataverse-sdk-for-python/plugin.json | 16 ++-- plugins/devops-oncall/plugin.json | 18 ++-- plugins/diagram-viewer/plugin.json | 6 +- plugins/doublecheck/plugin.json | 16 ++-- plugins/edge-ai-tasks/plugin.json | 12 ++- plugins/ember/plugin.json | 22 +++-- plugins/eyeball/plugin.json | 10 ++- plugins/fastah-ip-geo-tools/plugin.json | 10 ++- plugins/feedback-themes/plugin.json | 6 +- plugins/flight-map-canvas/plugin.json | 6 +- plugins/flowstudio-power-automate/plugin.json | 18 ++-- plugins/frontend-web-dev/plugin.json | 20 +++-- plugins/gesture-review/plugin.json | 6 +- plugins/go-mcp-development/plugin.json | 16 ++-- plugins/java-development/plugin.json | 16 ++-- plugins/java-mcp-development/plugin.json | 16 ++-- plugins/java-modernization-studio/plugin.json | 6 +- plugins/kotlin-mcp-development/plugin.json | 16 ++-- plugins/mcp-m365-copilot/plugin.json | 20 +++-- plugins/napkin/plugin.json | 10 ++- plugins/noob-mode/plugin.json | 10 ++- .../plugin.json | 16 ++-- plugins/openapi-to-application-go/plugin.json | 16 ++-- .../plugin.json | 16 ++-- .../plugin.json | 16 ++-- .../plugin.json | 16 ++-- .../plugin.json | 28 ++++--- plugins/ospo-sponsorship/plugin.json | 10 ++- plugins/partners/plugin.json | 48 ++++++----- plugins/phoenix/plugin.json | 14 ++-- plugins/php-mcp-development/plugin.json | 16 ++-- plugins/power-apps-code-apps/plugin.json | 16 ++-- plugins/power-bi-development/plugin.json | 28 ++++--- plugins/power-platform-architect/plugin.json | 10 ++- .../plugin.json | 18 ++-- plugins/pr-artifact-explorer/plugin.json | 6 +- plugins/project-documenter/plugin.json | 18 ++-- plugins/project-planning/plugin.json | 42 +++++----- plugins/python-mcp-development/plugin.json | 16 ++-- plugins/react18-upgrade/plugin.json | 38 +++++---- plugins/react19-upgrade/plugin.json | 28 ++++--- plugins/release-notes-showcase/plugin.json | 6 +- plugins/repo-actions-hub/plugin.json | 6 +- plugins/roundup/plugin.json | 12 ++- plugins/ruby-mcp-development/plugin.json | 16 ++-- plugins/rug-agentic-workflow/plugin.json | 14 ++-- plugins/rust-mcp-development/plugin.json | 16 ++-- plugins/salesforce-development/plugin.json | 26 +++--- plugins/security-best-practices/plugin.json | 10 ++- plugins/signals-dashboard/plugin.json | 6 +- plugins/site-studio/plugin.json | 6 +- plugins/skill-image-gen/plugin.json | 10 ++- plugins/software-engineering-team/plugin.json | 22 +++-- plugins/structured-autonomy/plugin.json | 14 ++-- plugins/swift-mcp-development/plugin.json | 16 ++-- plugins/technical-spike/plugin.json | 16 ++-- plugins/testing-automation/plugin.json | 30 ++++--- plugins/the-workshop/plugin.json | 24 +++--- plugins/tiny-tool-town-submitter/plugin.json | 6 +- plugins/token-pacman/plugin.json | 6 +- .../typescript-mcp-development/plugin.json | 16 ++-- plugins/typespec-m365-copilot/plugin.json | 14 ++-- plugins/uizze/plugin.json | 10 ++- plugins/visual-pr/plugin.json | 16 ++-- plugins/where-was-i/plugin.json | 6 +- plugins/work-hub/plugin.json | 6 +- 99 files changed, 1000 insertions(+), 637 deletions(-) diff --git a/.github/skills/create-canvas-extension/SKILL.md b/.github/skills/create-canvas-extension/SKILL.md index 901192f717..265faaed05 100644 --- a/.github/skills/create-canvas-extension/SKILL.md +++ b/.github/skills/create-canvas-extension/SKILL.md @@ -23,7 +23,7 @@ Before creating files, ask for each missing value: 4. **Preview image**: obtain an existing `assets/preview.png` path or ask the user to add it. Do not invent a binary image or silently use a misleading placeholder. 5. **Plugin registration**: - For a standalone installable canvas plugin, create `plugins/`. - - For an extension that belongs to an existing plugin, ask for the parent plugin ID and add `./extensions/` to that plugin's `extensions.com.github.copilot.directories`. + - For an extension that belongs to an existing plugin, ask for the parent plugin ID and add `./extensions/` to that plugin's `extensions.com.github.awesome-copilot.extensions`. - If the extension should be shipped by multiple plugins, collect all plugin IDs and add the same extension ID to each mapping file. ## Files to create @@ -37,9 +37,7 @@ extensions// โ””โ”€โ”€ preview.png plugins// -โ”œโ”€โ”€ .github/ -โ”‚ โ””โ”€โ”€ plugin/ -โ”‚ โ””โ”€โ”€ plugin.json +โ”œโ”€โ”€ plugin.json โ””โ”€โ”€ README.md ``` @@ -64,25 +62,32 @@ Create `plugins//plugin.json` with this shape: "extensions": { "com.github.copilot": { "logo": "assets/preview.png" + }, + "com.github.awesome-copilot": { + "extensions": [ + "./extensions/" + ] } } } ``` -The manifest must contain only Agent Plugins spec fields. Do not add `x-awesome-copilot`, `standalone`, or other repository-specific fields. +Keep Agent Plugins fields at the manifest top level. Repository composition belongs only under `extensions.com.github.awesome-copilot`; do not put `agents`, `commands`, `hooks`, `mcpServers`, or `skills` at the top level or directly under `extensions`. Do not add `x-awesome-copilot`, `standalone`, or other repository-specific top-level fields. For an existing parent plugin, create or update: ```text -plugins//plugin.json (`extensions.com.github.copilot.directories`) +plugins//plugin.json (`extensions.com.github.awesome-copilot.extensions`) ``` -Its contents must be a sorted JSON array of extension IDs: +Its `extensions` property must contain sorted repository-relative paths: ```json -[ - "" -] +{ + "extensions": [ + "./extensions/" + ] +} ``` Do not copy the extension source into the parent plugin. Materialization resolves the IDs from the root `extensions/` directory, so the same source can be bundled by multiple plugins. @@ -96,7 +101,7 @@ Do not copy the extension source into the parent plugin. Materialization resolve 2. Ask only the missing required questions from the decisions above. 3. Create the source and plugin directories with the required files. 4. If creating a new entrypoint, keep it minimal and clearly mark implementation TODOs rather than fabricating behavior. -5. Add or update `extensions.com.github.copilot.directories` for every parent plugin that should ship the extension. Keep paths alphabetically sorted and unique. +5. Add or update `extensions.com.github.awesome-copilot.extensions` for every parent plugin that should ship the extension. Keep paths alphabetically sorted and unique. 6. Ensure there is no `extensions//.github/plugin/plugin.json`. 7. Run: @@ -115,5 +120,5 @@ When migrating an existing extension: 1. Move its existing manifest to `plugins//plugin.json`. 2. Update the manifest to the namespace-based `extensions.com.github.copilot.logo` shape. 3. Remove the old manifest from `extensions/`. -4. Register the extension in any parent plugin's `extensions.com.github.copilot.directories`. +4. Register the extension in any parent plugin's `extensions.com.github.awesome-copilot.extensions`. 5. Run the validation and build commands above. diff --git a/.github/workflows/validate-plugins.yml b/.github/workflows/validate-plugins.yml index be74fb767b..d97a2f3acc 100644 --- a/.github/workflows/validate-plugins.yml +++ b/.github/workflows/validate-plugins.yml @@ -47,9 +47,12 @@ jobs: 'All internal plugins and extensions must include:', '- `"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json"` in `plugin.json`', '- A valid `name`, `description`, and `version`', - '- For **extensions**: `extensions[""].logo` set to `"assets/preview.png"`', + '- Repository composition (`agents`, `commands`, `hooks`, `mcpServers`, `skills`, and reusable `extensions`) under `extensions["com.github.awesome-copilot"]`', + '- For **extensions**: `extensions["com.github.copilot"].logo` set to `"assets/preview.png"`', '', - 'Run `npm run plugin:validate` locally to see the full list of errors.', + 'Do not put repository composition fields at the manifest top level or directly under `extensions`; they must be nested under `extensions["com.github.awesome-copilot"]`.', + '', + 'Run `npm run plugin:validate` locally to see the full list of errors. See `.github/skills/create-canvas-extension/SKILL.md` and `CONTRIBUTING.md` for examples.', ].join('\n'); const { data: comments } = await github.rest.issues.listComments({ diff --git a/AGENTS.md b/AGENTS.md index f13f3620f7..fc10edd78f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -87,7 +87,7 @@ All agent files (`*.agent.md`) and instruction files (`*.instructions.md`) must - Each extension folder must include `extension.mjs` - Extensions are reusable source components, not standalone plugins - A shippable extension plugin is registered by a matching `plugins//plugin.json` -- A plugin can bundle additional reusable extensions by listing `./extensions/` paths in `extensions.com.github.copilot.directories` +- A plugin can bundle additional reusable extensions by listing `./extensions/` paths in `extensions.com.github.awesome-copilot.extensions` - Each extension must have `assets/preview.png` as the primary visual asset - Extension metadata is sourced from the matching plugin manifest in `plugins/` @@ -120,7 +120,7 @@ All agent files (`*.agent.md`) and instruction files (`*.instructions.md`) must - plugin.json must have `name` field (matching the folder name) - plugin.json must have `description` field (describing the plugin's purpose) - plugin.json must have `version` field (semantic version, e.g., "1.0.0") -- Plugin content is defined declaratively in plugin.json using source-only composition fields (`agents`, `commands`, `skills`). Source files live in top-level directories and are materialized into plugins by CI. These fields are stripped from the served manifest โ€” conventional directory discovery handles them in spec mode. +- Plugin content is defined declaratively in plugin.json under `extensions.com.github.awesome-copilot` using source-only composition fields (`agents`, `commands`, `hooks`, `skills`, and `extensions`). Source files live in top-level directories and are materialized into plugins by CI. This namespace is stripped from the served manifest โ€” conventional directory discovery handles the materialized content in spec mode. - The `marketplace.json` file is automatically generated from all plugins during build - Plugins are discoverable and installable via GitHub Copilot CLI @@ -165,7 +165,7 @@ When adding a new agent, instruction, skill, hook, workflow, or plugin: **For Plugins:** 1. Run `npm run plugin:create -- --name ` to scaffold a new plugin -2. Define agents, commands, and skills in `plugin.json` using the repository's build-time composition fields +2. Define agents, commands, hooks, skills, and reusable extensions under `extensions.com.github.awesome-copilot` in `plugin.json` 3. Edit the generated `plugin.json` with your metadata 4. Run `npm run plugin:validate` to validate the plugin structure 5. Run `npm run build` to update README.md and marketplace.json @@ -192,7 +192,7 @@ When adding a new agent, instruction, skill, hook, workflow, or plugin: 4. Run `npm run plugin:validate` to validate plugin and extension metadata 5. Run `npm run build` to regenerate website data and marketplace output -To bundle an extension into another plugin without making a second source copy, add sorted `./extensions/` paths to `plugins//plugin.json` under `extensions.com.github.copilot.directories`. +To bundle an extension into another plugin without making a second source copy, add sorted `./extensions/` paths to `plugins//plugin.json` under `extensions.com.github.awesome-copilot.extensions`. **For External Plugins:** @@ -330,7 +330,7 @@ For plugins (plugins/\*/): - [ ] `plugin.json` has `version` field (semantic version, e.g., "1.0.0") - [ ] Directory name is lower case with hyphens - [ ] If `keywords` is present, it is an array of lowercase hyphenated strings -- [ ] If `agents`, `commands`, or `skills` arrays are present, each entry is a valid relative path +- [ ] If composition arrays are present under `extensions.com.github.awesome-copilot`, each entry is a valid relative path - [ ] The plugin does not reference non-existent files - [ ] Run `npm run plugin:validate` and `npm run build` to verify the plugin passes all checks diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2e4de3241e..866b33ef7b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -157,7 +157,7 @@ Plugins group related agents, commands, and skills around specific themes or wor 1. **Create your plugin**: Run `npm run plugin:create` to scaffold a new plugin 2. **Follow the naming convention**: Use descriptive, lowercase folder names with hyphens (e.g., `python-web-development`) -3. **Define your content**: List agents, commands, and skills in `plugin.json` using the Claude Code spec fields +3. **Define your content**: List agents, commands, hooks, skills, and reusable extensions under `extensions.com.github.awesome-copilot` in `plugin.json` 4. **Test your plugin**: Run `npm run plugin:validate` to verify your plugin structure #### Creating a plugin @@ -174,7 +174,7 @@ plugins/my-plugin-id/ โ””โ”€โ”€ README.md # Plugin documentation ``` -> **Note:** Plugin content is defined declaratively in plugin.json using Claude Code spec fields (`agents`, `commands`, `skills`). Source files live in top-level directories and are materialized into plugins by CI. +> **Note:** Plugin content is defined declaratively in plugin.json under `extensions.com.github.awesome-copilot`. Source files live in top-level directories and are materialized into plugins by CI. This repository namespace is removed from the served manifest. #### plugin.json example @@ -188,17 +188,21 @@ plugins/my-plugin-id/ "author": { "name": "Awesome Copilot Community" }, "repository": "https://github.com/github/awesome-copilot", "license": "MIT", - "agents": ["./agents/my-agent.md"], - "commands": ["./commands/my-command.md"], - "skills": ["./skills/my-skill/"] + "extensions": { + "com.github.awesome-copilot": { + "agents": ["./agents/my-agent.md"], + "commands": ["./commands/my-command.md"], + "skills": ["./skills/my-skill/"] + } + } } ``` #### Plugin Guidelines -- **Declarative content**: Plugin content is specified via `agents`, `commands`, and `skills` arrays in plugin.json โ€” source files live in top-level directories and are materialized into plugins by CI +- **Declarative content**: Plugin content is specified under `extensions.com.github.awesome-copilot` โ€” source files live in top-level directories and are materialized into plugins by CI - **Valid references**: All paths referenced in plugin.json must point to existing source files in the repository -- **Reusable extensions**: Curated plugins can bundle extensions by adding `./extensions/` paths under `extensions.com.github.copilot.directories`; the same extension can be listed by multiple plugins +- **Reusable extensions**: Curated plugins can bundle extensions by adding `./extensions/` paths under `extensions.com.github.awesome-copilot.extensions`; the same extension can be listed by multiple plugins - **Instructions excluded**: Instructions are standalone resources and are not part of plugins - **Clear purpose**: The plugin should solve a specific problem or workflow - **Validate before submitting**: Run `npm run plugin:validate` to ensure your plugin is valid diff --git a/eng/create-plugin.mjs b/eng/create-plugin.mjs index 32c569f3ea..0dbf35b266 100755 --- a/eng/create-plugin.mjs +++ b/eng/create-plugin.mjs @@ -140,6 +140,12 @@ async function createPlugin() { author: { name: "Awesome Copilot Community" }, repository: "https://github.com/github/awesome-copilot", license: "MIT", + extensions: { + "com.github.awesome-copilot": { + agents: [], + skills: [], + }, + }, }; fs.writeFileSync( diff --git a/eng/generate-website-data.mjs b/eng/generate-website-data.mjs index 2a46c1546c..93721cc03b 100755 --- a/eng/generate-website-data.mjs +++ b/eng/generate-website-data.mjs @@ -557,7 +557,8 @@ function generatePluginsData(gitDates, resourceIndex = {}) { try { const data = JSON.parse(fs.readFileSync(jsonPath, "utf-8")); const relPath = `plugins/${dir.name}`; - const extensionRefs = data.extensions?.["com.github.copilot"]?.directories + const composition = data.extensions?.["com.github.awesome-copilot"] ?? {}; + const extensionRefs = composition.extensions ?.map((entry) => entry.replace(/^\.\/extensions\//, "").replace(/\/$/, "")) .filter(Boolean) ?? []; if (fs.existsSync(path.join(EXTENSIONS_DIR, dir.name, "extension.mjs")) && !extensionRefs.includes(dir.name)) { @@ -570,7 +571,7 @@ function generatePluginsData(gitDates, resourceIndex = {}) { path: `extensions/${entry}`, })); - const agentItems = (data.agents || []).flatMap((agent) => { + const agentItems = (composition.agents || []).flatMap((agent) => { const agentPath = agent.replace("./", ""); const fullPath = path.join(pluginDir, agentPath); @@ -588,11 +589,11 @@ function generatePluginsData(gitDates, resourceIndex = {}) { // Parse mcpServers: supports a path to a .mcp.json file or an inline object const mcpItems = []; - if (data.mcpServers) { + if (composition.mcpServers) { let mcpServersObj = null; let mcpConfigPath = relPath; - if (typeof data.mcpServers === "string") { - const manifestMcpPath = data.mcpServers.replace(/^\.\//, ""); + if (typeof composition.mcpServers === "string") { + const manifestMcpPath = composition.mcpServers.replace(/^\.\//, ""); mcpConfigPath = manifestMcpPath ? `${relPath}/${manifestMcpPath}` : relPath; const mcpJsonPath = path.join(pluginDir, manifestMcpPath); if (fs.existsSync(mcpJsonPath)) { @@ -603,8 +604,8 @@ function generatePluginsData(gitDates, resourceIndex = {}) { // ignore parse errors } } - } else if (typeof data.mcpServers === "object") { - mcpServersObj = data.mcpServers; + } else if (typeof composition.mcpServers === "object") { + mcpServersObj = composition.mcpServers; } if (mcpServersObj) { for (const serverName of Object.keys(mcpServersObj)) { @@ -616,8 +617,8 @@ function generatePluginsData(gitDates, resourceIndex = {}) { // Build items list from spec fields (agents, commands, skills, mcpServers) const items = [ ...agentItems, - ...(data.commands || []).map((p) => ({ kind: "prompt", path: p })), - ...(data.skills || []).map((p) => ({ kind: "skill", path: p })), + ...(composition.commands || []).map((p) => ({ kind: "prompt", path: p })), + ...(composition.skills || []).map((p) => ({ kind: "skill", path: p })), ...extensionItems, ...mcpItems, ].map((item) => resolvePluginItem(item, resourceIndex)); diff --git a/eng/materialize-plugins.mjs b/eng/materialize-plugins.mjs index 8b42ed1481..c99f57a36d 100644 --- a/eng/materialize-plugins.mjs +++ b/eng/materialize-plugins.mjs @@ -7,6 +7,7 @@ import { ROOT_FOLDER } from "./constants.mjs"; const PLUGINS_DIR = path.join(ROOT_FOLDER, "plugins"); const EXTENSIONS_DIR = path.join(ROOT_FOLDER, "extensions"); const COPILOT_NAMESPACE = "com.github.copilot"; +const AWESOME_COPILOT_NAMESPACE = "com.github.awesome-copilot"; /** * Recursively copy a directory. @@ -44,14 +45,21 @@ function resolveSource(relPath) { const extensionName = relPath.replace(/^\.\/extensions\//, "").replace(/\/$/, ""); return path.join(ROOT_FOLDER, "extensions", extensionName); } + if (relPath.startsWith("./hooks/")) { + return path.join(ROOT_FOLDER, "hooks", relPath.replace(/^\.\/hooks\//, "")); + } + if (relPath.startsWith("./commands/")) { + return path.join(ROOT_FOLDER, "commands", relPath.replace(/^\.\/commands\//, "")); + } return null; } function readExtensionReferences(metadata, pluginName) { - const extensionData = metadata.extensions?.[COPILOT_NAMESPACE]; - const directories = extensionData?.directories ?? []; - if (!Array.isArray(directories) || directories.some((entry) => typeof entry !== "string")) { - throw new Error(`extensions["${COPILOT_NAMESPACE}"].directories must contain plugin-relative paths`); + const extensionData = metadata.extensions?.[AWESOME_COPILOT_NAMESPACE]; + const directories = extensionData?.extensions ?? []; + if (!Array.isArray(directories) || + directories.some((entry) => typeof entry !== "string" || !entry.startsWith("./extensions/"))) { + throw new Error(`extensions["${AWESOME_COPILOT_NAMESPACE}"].extensions must contain plugin-relative paths`); } const names = new Set(directories.map((entry) => @@ -102,48 +110,34 @@ function materializePlugins() { const pluginName = metadata.name || dirName; - // Process agents - if (Array.isArray(metadata.agents)) { - for (const relPath of metadata.agents) { - const src = resolveSource(relPath); - if (!src) { - console.warn(` โš  ${pluginName}: Unknown path format: ${relPath}`); - warnings++; - continue; - } - if (!fs.existsSync(src)) { - console.warn(` โš  ${pluginName}: Source not found: ${src}`); - warnings++; - continue; - } - const dest = path.join(pluginPath, relPath.replace(/^\.\//, "")); - fs.mkdirSync(path.dirname(dest), { recursive: true }); - fs.copyFileSync(src, dest); - totalAgents++; - } - } + const composition = metadata.extensions?.[AWESOME_COPILOT_NAMESPACE] ?? {}; - // Process skills - if (Array.isArray(metadata.skills)) { - for (const relPath of metadata.skills) { + // Process repository composition fields. + for (const field of ["agents", "commands", "hooks", "skills"]) { + const entries = composition[field]; + if (!Array.isArray(entries)) continue; + for (const relPath of entries) { const src = resolveSource(relPath); if (!src) { - console.warn(` โš  ${pluginName}: Unknown path format: ${relPath}`); + console.warn(` โš  ${pluginName}: Unknown ${field} path format: ${relPath}`); warnings++; continue; } - if (!fs.existsSync(src) || !fs.statSync(src).isDirectory()) { - console.warn(` โš  ${pluginName}: Source directory not found: ${src}`); + if (!fs.existsSync(src)) { + console.warn(` โš  ${pluginName}: ${field} source not found: ${src}`); warnings++; continue; } const dest = path.join(pluginPath, relPath.replace(/^\.\//, "").replace(/\/$/, "")); - copyDirRecursive(src, dest); - totalSkills++; + fs.mkdirSync(path.dirname(dest), { recursive: true }); + if (fs.statSync(src).isDirectory()) copyDirRecursive(src, dest); + else fs.copyFileSync(src, dest); + if (field === "agents") totalAgents++; + if (field === "skills") totalSkills++; } } - // Process extension directories declared in the Copilot namespace. + // Process reusable extensions declared in the repository namespace. const extensionRefs = readExtensionReferences(metadata, pluginName); for (const extensionName of extensionRefs) { const relPath = `./extensions/${extensionName}`; @@ -158,7 +152,9 @@ function materializePlugins() { warnings++; continue; } - const dest = path.join(pluginPath, COPILOT_NAMESPACE, extensionName); + // Extensions are conventional plugin content and belong under the + // plugin's top-level extensions directory, not the client namespace. + const dest = path.join(pluginPath, "extensions", extensionName); copyDirRecursive(src, dest); totalExtensions++; } @@ -174,15 +170,11 @@ function materializePlugins() { const served = { "$schema": AGENT_PLUGINS_SCHEMA }; for (const [key, val] of Object.entries(metadata)) { if (SPEC_FIELDS.has(key) && key !== "$schema") { - if (key === "extensions" && val?.[COPILOT_NAMESPACE]?.directories) { - served[key] = { - ...val, - [COPILOT_NAMESPACE]: { - ...val[COPILOT_NAMESPACE], - directories: undefined, - }, - }; - delete served[key][COPILOT_NAMESPACE].directories; + if (key === "extensions") { + const copilot = val?.[COPILOT_NAMESPACE]; + if (copilot) { + served.extensions = { [COPILOT_NAMESPACE]: { ...copilot } }; + } } else { served[key] = val; } @@ -192,8 +184,8 @@ function materializePlugins() { fs.writeFileSync(pluginJsonPath, JSON.stringify(served, null, 2) + "\n", "utf8"); const counts = []; - if (metadata.agents?.length) counts.push(`${metadata.agents.length} agents`); - if (metadata.skills?.length) counts.push(`${metadata.skills.length} skills`); + if (composition.agents?.length) counts.push(`${composition.agents.length} agents`); + if (composition.skills?.length) counts.push(`${composition.skills.length} skills`); if (extensionRefs.length) counts.push(`${extensionRefs.length} extensions`); if (counts.length) { console.log(`โœ“ ${pluginName}: ${counts.join(", ")}`); diff --git a/eng/update-readme.mjs b/eng/update-readme.mjs index c75e8f2d16..c8817cbdb5 100644 --- a/eng/update-readme.mjs +++ b/eng/update-readme.mjs @@ -786,10 +786,11 @@ function generatePluginsSection(pluginsDir) { for (const entry of sortedEntries) { const { plugin, dir, name, isFeatured } = entry; const description = formatTableCell(plugin.description || "No description"); + const composition = plugin.extensions?.["com.github.awesome-copilot"] || {}; const itemCount = - (plugin.agents || []).length + - (plugin.commands || []).length + - (plugin.skills || []).length; + (composition.agents || []).length + + (composition.commands || []).length + + (composition.skills || []).length; const keywords = plugin.keywords ? plugin.keywords.join(", ") : ""; const link = `../plugins/${dir}/README.md`; @@ -842,10 +843,11 @@ function generateFeaturedPluginsSection(pluginsDir) { plugin.description || "No description" ); const keywords = plugin.keywords ? plugin.keywords.join(", ") : ""; + const composition = plugin.extensions?.["com.github.awesome-copilot"] || {}; const itemCount = - (plugin.agents || []).length + - (plugin.commands || []).length + - (plugin.skills || []).length; + (composition.agents || []).length + + (composition.commands || []).length + + (composition.skills || []).length; return { dir, diff --git a/eng/validate-plugins.mjs b/eng/validate-plugins.mjs index 6f5c2ce3c4..9f766ee0fa 100755 --- a/eng/validate-plugins.mjs +++ b/eng/validate-plugins.mjs @@ -11,6 +11,7 @@ const EXTENSIONS_DIR = path.join(ROOT_FOLDER, "extensions"); const AGENT_PLUGINS_SCHEMA = "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json"; const COPILOT_NAMESPACE = "com.github.copilot"; +const AWESOME_COPILOT_NAMESPACE = "com.github.awesome-copilot"; // Validation functions function validateName(name, folderName) { @@ -116,35 +117,37 @@ function validateSpecPaths(plugin) { const errors = []; const specs = { agents: { prefix: "./agents/", suffix: ".md", repoDir: "agents", repoSuffix: ".agent.md" }, + commands: { prefix: "./commands/", suffix: ".md", repoDir: "commands", repoSuffix: ".md" }, + hooks: { prefix: "./hooks/", suffix: ".md", repoDir: "hooks", repoSuffix: ".md" }, skills: { prefix: "./skills/", suffix: "/", repoDir: "skills", repoFile: "SKILL.md" }, }; for (const [field, spec] of Object.entries(specs)) { - const arr = plugin[field]; + const arr = plugin.extensions?.[AWESOME_COPILOT_NAMESPACE]?.[field]; if (arr === undefined) continue; if (!Array.isArray(arr)) { - errors.push(`${field} must be an array`); + errors.push(`extensions["${AWESOME_COPILOT_NAMESPACE}"].${field} must be an array`); continue; } if (!arraysEqual(arr, sortPluginEntries(arr))) { - errors.push(`${field} must be sorted alphabetically`); + errors.push(`extensions["${AWESOME_COPILOT_NAMESPACE}"].${field} must be sorted alphabetically`); } for (let i = 0; i < arr.length; i++) { const p = arr[i]; if (typeof p !== "string") { - errors.push(`${field}[${i}] must be a string`); + errors.push(`extensions["${AWESOME_COPILOT_NAMESPACE}"].${field}[${i}] must be a string`); continue; } if (!p.startsWith("./")) { - errors.push(`${field}[${i}] must start with "./"`); + errors.push(`extensions["${AWESOME_COPILOT_NAMESPACE}"].${field}[${i}] must start with "./"`); continue; } if (!p.startsWith(spec.prefix)) { - errors.push(`${field}[${i}] must start with "${spec.prefix}"`); + errors.push(`extensions["${AWESOME_COPILOT_NAMESPACE}"].${field}[${i}] must start with "${spec.prefix}"`); continue; } if (!p.endsWith(spec.suffix)) { - errors.push(`${field}[${i}] must end with "${spec.suffix}"`); + errors.push(`extensions["${AWESOME_COPILOT_NAMESPACE}"].${field}[${i}] must end with "${spec.suffix}"`); continue; } // Validate the source file exists at repo root @@ -153,12 +156,12 @@ function validateSpecPaths(plugin) { const skillDir = path.join(ROOT_FOLDER, spec.repoDir, basename); const skillFile = path.join(skillDir, spec.repoFile); if (!fs.existsSync(skillFile)) { - errors.push(`${field}[${i}] source not found: ${spec.repoDir}/${basename}/SKILL.md`); + errors.push(`extensions["${AWESOME_COPILOT_NAMESPACE}"].${field}[${i}] source not found: ${spec.repoDir}/${basename}/SKILL.md`); } } else { const srcFile = path.join(ROOT_FOLDER, spec.repoDir, basename + spec.repoSuffix); if (!fs.existsSync(srcFile)) { - errors.push(`${field}[${i}] source not found: ${spec.repoDir}/${basename}${spec.repoSuffix}`); + errors.push(`extensions["${AWESOME_COPILOT_NAMESPACE}"].${field}[${i}] source not found: ${spec.repoDir}/${basename}${spec.repoSuffix}`); } } } @@ -168,16 +171,16 @@ function validateSpecPaths(plugin) { function validateExtensionReferences(plugin, pluginDir) { const errors = []; - const directories = plugin.extensions?.[COPILOT_NAMESPACE]?.directories; + const directories = plugin.extensions?.[AWESOME_COPILOT_NAMESPACE]?.extensions; if (directories === undefined) { return errors; } if (!Array.isArray(directories)) { - errors.push(`extensions["${COPILOT_NAMESPACE}"].directories must be an array`); + errors.push(`extensions["${AWESOME_COPILOT_NAMESPACE}"].extensions must be an array`); return errors; } if (!arraysEqual(directories, sortPluginEntries(directories))) { - errors.push(`extensions["${COPILOT_NAMESPACE}"].directories entries must be sorted alphabetically`); + errors.push(`extensions["${AWESOME_COPILOT_NAMESPACE}"].extensions entries must be sorted alphabetically`); } for (const [index, directory] of directories.entries()) { @@ -186,11 +189,38 @@ function validateExtensionReferences(plugin, pluginDir) { : ""; if (typeof directory !== "string" || !directory.startsWith("./extensions/") || !/^[a-z0-9][a-z0-9.-]*[a-z0-9]$|^[a-z0-9]$/.test(name)) { - errors.push(`extensions["${COPILOT_NAMESPACE}"].directories[${index}] must be a valid ./extensions/ path`); + errors.push(`extensions["${AWESOME_COPILOT_NAMESPACE}"].extensions[${index}] must be a valid ./extensions/ path`); continue; } if (!fs.existsSync(path.join(EXTENSIONS_DIR, name, "extension.mjs"))) { - errors.push(`extensions["${COPILOT_NAMESPACE}"].directories[${index}] source not found: extensions/${name}`); + errors.push(`extensions["${AWESOME_COPILOT_NAMESPACE}"].extensions[${index}] source not found: extensions/${name}`); + } + } + + return errors; +} + +function validateCompositionNamespace(plugin) { + const errors = []; + const compositionFields = ["agents", "commands", "hooks", "mcpServers", "skills"]; + const extensions = plugin.extensions; + const composition = extensions?.[AWESOME_COPILOT_NAMESPACE]; + + if (extensions !== undefined && + (typeof extensions !== "object" || extensions === null || Array.isArray(extensions))) { + errors.push(`extensions must be an object containing "${AWESOME_COPILOT_NAMESPACE}"`); + return errors; + } + + if (composition !== undefined && + (typeof composition !== "object" || composition === null || Array.isArray(composition))) { + errors.push(`extensions["${AWESOME_COPILOT_NAMESPACE}"] must be an object`); + return errors; + } + + for (const field of compositionFields) { + if (extensions?.[field] !== undefined) { + errors.push(`extensions.${field} must be moved to extensions["${AWESOME_COPILOT_NAMESPACE}"].${field}`); } } @@ -248,6 +278,12 @@ function validatePlugin(folderName) { // Rule 5b: license (shared with external plugins). Non-SPDX is a warning, not an error. const warnings = []; + for (const field of ["agents", "commands", "hooks", "mcpServers", "skills"]) { + if (plugin[field] !== undefined) { + errors.push(`${field} must be moved to extensions["${AWESOME_COPILOT_NAMESPACE}"].${field}`); + } + } + errors.push(...validateCompositionNamespace(plugin)); const licenseResult = validateLicenseField(plugin.license, { required: false }); errors.push(...licenseResult.errors); warnings.push(...licenseResult.warnings); diff --git a/plugins/accessibility-kanban/plugin.json b/plugins/accessibility-kanban/plugin.json index b9e1b3dd9e..16014aa294 100644 --- a/plugins/accessibility-kanban/plugin.json +++ b/plugins/accessibility-kanban/plugin.json @@ -17,8 +17,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png", - "directories": [ + "logo": "assets/preview.png" + }, + "com.github.awesome-copilot": { + "extensions": [ "./extensions/accessibility-kanban" ] } diff --git a/plugins/acreadiness-cockpit/plugin.json b/plugins/acreadiness-cockpit/plugin.json index 30c89eed55..88aa0e7be1 100644 --- a/plugins/acreadiness-cockpit/plugin.json +++ b/plugins/acreadiness-cockpit/plugin.json @@ -17,12 +17,16 @@ }, "repository": "https://github.com/github/awesome-copilot", "license": "MIT", - "agents": [ - "./agents/ai-readiness-reporter.md" - ], - "skills": [ - "./skills/acreadiness-assess/", - "./skills/acreadiness-generate-instructions/", - "./skills/acreadiness-policy/" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/ai-readiness-reporter.md" + ], + "skills": [ + "./skills/acreadiness-assess/", + "./skills/acreadiness-generate-instructions/", + "./skills/acreadiness-policy/" + ] + } + } } diff --git a/plugins/ai-team-orchestration/plugin.json b/plugins/ai-team-orchestration/plugin.json index 69d770a81c..52b906fd0c 100644 --- a/plugins/ai-team-orchestration/plugin.json +++ b/plugins/ai-team-orchestration/plugin.json @@ -17,12 +17,16 @@ }, "repository": "https://github.com/github/awesome-copilot", "license": "MIT", - "agents": [ - "./agents/ai-team-dev.md", - "./agents/ai-team-producer.md", - "./agents/ai-team-qa.md" - ], - "skills": [ - "./skills/ai-team-orchestration/" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/ai-team-dev.md", + "./agents/ai-team-producer.md", + "./agents/ai-team-qa.md" + ], + "skills": [ + "./skills/ai-team-orchestration/" + ] + } + } } diff --git a/plugins/apng-studio/plugin.json b/plugins/apng-studio/plugin.json index 51827d28df..c65328ed7a 100644 --- a/plugins/apng-studio/plugin.json +++ b/plugins/apng-studio/plugin.json @@ -17,8 +17,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png", - "directories": [ + "logo": "assets/preview.png" + }, + "com.github.awesome-copilot": { + "extensions": [ "./extensions/apng-studio" ] } diff --git a/plugins/arcade-canvas/plugin.json b/plugins/arcade-canvas/plugin.json index 6d48e2d527..d1b58c2f0b 100644 --- a/plugins/arcade-canvas/plugin.json +++ b/plugins/arcade-canvas/plugin.json @@ -17,8 +17,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png", - "directories": [ + "logo": "assets/preview.png" + }, + "com.github.awesome-copilot": { + "extensions": [ "./extensions/arcade-canvas" ] } diff --git a/plugins/arch/plugin.json b/plugins/arch/plugin.json index 5edd00cf1d..9e42a68720 100644 --- a/plugins/arch/plugin.json +++ b/plugins/arch/plugin.json @@ -15,7 +15,11 @@ }, "repository": "https://github.com/github/awesome-copilot", "license": "MIT", - "skills": [ - "./skills/doc-and-modernize/" - ] + "extensions": { + "com.github.awesome-copilot": { + "skills": [ + "./skills/doc-and-modernize/" + ] + } + } } diff --git a/plugins/arize-ax/plugin.json b/plugins/arize-ax/plugin.json index f3f309288e..6c7ee9e2a2 100644 --- a/plugins/arize-ax/plugin.json +++ b/plugins/arize-ax/plugin.json @@ -19,15 +19,19 @@ "experiments", "prompt-optimization" ], - "skills": [ - "./skills/arize-ai-provider-integration/", - "./skills/arize-annotation/", - "./skills/arize-dataset/", - "./skills/arize-evaluator/", - "./skills/arize-experiment/", - "./skills/arize-instrumentation/", - "./skills/arize-link/", - "./skills/arize-prompt-optimization/", - "./skills/arize-trace/" - ] + "extensions": { + "com.github.awesome-copilot": { + "skills": [ + "./skills/arize-ai-provider-integration/", + "./skills/arize-annotation/", + "./skills/arize-dataset/", + "./skills/arize-evaluator/", + "./skills/arize-experiment/", + "./skills/arize-instrumentation/", + "./skills/arize-link/", + "./skills/arize-prompt-optimization/", + "./skills/arize-trace/" + ] + } + } } diff --git a/plugins/automate-this/plugin.json b/plugins/automate-this/plugin.json index 8d11115632..01fb0c250e 100644 --- a/plugins/automate-this/plugin.json +++ b/plugins/automate-this/plugin.json @@ -18,7 +18,11 @@ "productivity", "copilot-cli" ], - "skills": [ - "./skills/automate-this/" - ] + "extensions": { + "com.github.awesome-copilot": { + "skills": [ + "./skills/automate-this/" + ] + } + } } diff --git a/plugins/awesome-copilot/plugin.json b/plugins/awesome-copilot/plugin.json index 74f78258d7..b5bd348825 100644 --- a/plugins/awesome-copilot/plugin.json +++ b/plugins/awesome-copilot/plugin.json @@ -15,13 +15,17 @@ "prompt-engineering", "agents" ], - "agents": [ - "./agents/meta-agentic-project-scaffold.md" - ], - "skills": [ - "./skills/suggest-awesome-github-copilot-agents/", - "./skills/suggest-awesome-github-copilot-instructions/", - "./skills/suggest-awesome-github-copilot-skills/" - ], - "mcpServers": "./.mcp.json" + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/meta-agentic-project-scaffold.md" + ], + "mcpServers": "./.mcp.json", + "skills": [ + "./skills/suggest-awesome-github-copilot-agents/", + "./skills/suggest-awesome-github-copilot-instructions/", + "./skills/suggest-awesome-github-copilot-skills/" + ] + } + } } diff --git a/plugins/aws-cloud-development/plugin.json b/plugins/aws-cloud-development/plugin.json index 6f50e1ffea..e8c433c61c 100644 --- a/plugins/aws-cloud-development/plugin.json +++ b/plugins/aws-cloud-development/plugin.json @@ -19,16 +19,20 @@ "devops", "cdk" ], - "agents": [ - "./agents/aws-principal-architect.md", - "./agents/aws-serverless-architect.md", - "./agents/terraform-aws-implement.md", - "./agents/terraform-aws-planning.md" - ], - "skills": [ - "./skills/aws-cost-optimize/", - "./skills/aws-resource-health-diagnose/", - "./skills/aws-resource-query/", - "./skills/aws-well-architected-review/" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/aws-principal-architect.md", + "./agents/aws-serverless-architect.md", + "./agents/terraform-aws-implement.md", + "./agents/terraform-aws-planning.md" + ], + "skills": [ + "./skills/aws-cost-optimize/", + "./skills/aws-resource-health-diagnose/", + "./skills/aws-resource-query/", + "./skills/aws-well-architected-review/" + ] + } + } } diff --git a/plugins/azure-cloud-development/plugin.json b/plugins/azure-cloud-development/plugin.json index 2d38c83e29..2f896af51b 100644 --- a/plugins/azure-cloud-development/plugin.json +++ b/plugins/azure-cloud-development/plugin.json @@ -18,19 +18,23 @@ "architecture", "devops" ], - "agents": [ - "./agents/azure-logic-apps-expert.md", - "./agents/azure-principal-architect.md", - "./agents/azure-saas-architect.md", - "./agents/azure-verified-modules-bicep.md", - "./agents/azure-verified-modules-terraform.md", - "./agents/terraform-azure-implement.md", - "./agents/terraform-azure-planning.md" - ], - "skills": [ - "./skills/az-cost-optimize/", - "./skills/azure-pricing/", - "./skills/azure-resource-health-diagnose/", - "./skills/import-infrastructure-as-code/" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/azure-logic-apps-expert.md", + "./agents/azure-principal-architect.md", + "./agents/azure-saas-architect.md", + "./agents/azure-verified-modules-bicep.md", + "./agents/azure-verified-modules-terraform.md", + "./agents/terraform-azure-implement.md", + "./agents/terraform-azure-planning.md" + ], + "skills": [ + "./skills/az-cost-optimize/", + "./skills/azure-pricing/", + "./skills/azure-resource-health-diagnose/", + "./skills/import-infrastructure-as-code/" + ] + } + } } diff --git a/plugins/backlog-swipe-triage/plugin.json b/plugins/backlog-swipe-triage/plugin.json index 5aa5ffa52a..2df9431849 100644 --- a/plugins/backlog-swipe-triage/plugin.json +++ b/plugins/backlog-swipe-triage/plugin.json @@ -17,8 +17,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png", - "directories": [ + "logo": "assets/preview.png" + }, + "com.github.awesome-copilot": { + "extensions": [ "./extensions/backlog-swipe-triage" ] } diff --git a/plugins/backrooms-canvas/plugin.json b/plugins/backrooms-canvas/plugin.json index 19827b171c..b8b976d88e 100644 --- a/plugins/backrooms-canvas/plugin.json +++ b/plugins/backrooms-canvas/plugin.json @@ -16,8 +16,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png", - "directories": [ + "logo": "assets/preview.png" + }, + "com.github.awesome-copilot": { + "extensions": [ "./extensions/backrooms-canvas" ] } diff --git a/plugins/cast-imaging/plugin.json b/plugins/cast-imaging/plugin.json index ab53a0337f..d47e4c051e 100644 --- a/plugins/cast-imaging/plugin.json +++ b/plugins/cast-imaging/plugin.json @@ -16,9 +16,13 @@ "impact-analysis", "devops" ], - "agents": [ - "./agents/cast-imaging-impact-analysis.md", - "./agents/cast-imaging-software-discovery.md", - "./agents/cast-imaging-structural-quality-advisor.md" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/cast-imaging-impact-analysis.md", + "./agents/cast-imaging-software-discovery.md", + "./agents/cast-imaging-structural-quality-advisor.md" + ] + } + } } diff --git a/plugins/chromium-control-canvas/plugin.json b/plugins/chromium-control-canvas/plugin.json index 32b933cb01..419c9663bf 100644 --- a/plugins/chromium-control-canvas/plugin.json +++ b/plugins/chromium-control-canvas/plugin.json @@ -18,8 +18,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png", - "directories": [ + "logo": "assets/preview.png" + }, + "com.github.awesome-copilot": { + "extensions": [ "./extensions/chromium-control-canvas" ] } diff --git a/plugins/clojure-interactive-programming/plugin.json b/plugins/clojure-interactive-programming/plugin.json index cbf9094421..c47a5a667c 100644 --- a/plugins/clojure-interactive-programming/plugin.json +++ b/plugins/clojure-interactive-programming/plugin.json @@ -13,10 +13,14 @@ "repl", "interactive-programming" ], - "agents": [ - "./agents/clojure-interactive-programming.md" - ], - "skills": [ - "./skills/remember-interactive-programming/" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/clojure-interactive-programming.md" + ], + "skills": [ + "./skills/remember-interactive-programming/" + ] + } + } } diff --git a/plugins/cms-development/plugin.json b/plugins/cms-development/plugin.json index e7ea958441..9eec577220 100644 --- a/plugins/cms-development/plugin.json +++ b/plugins/cms-development/plugin.json @@ -19,9 +19,13 @@ }, "repository": "https://github.com/github/awesome-copilot", "license": "MIT", - "skills": [ - "./skills/content-management-systems/", - "./skills/markdown-to-html/", - "./skills/quasi-coder/" - ] + "extensions": { + "com.github.awesome-copilot": { + "skills": [ + "./skills/content-management-systems/", + "./skills/markdown-to-html/", + "./skills/quasi-coder/" + ] + } + } } diff --git a/plugins/color-orb/plugin.json b/plugins/color-orb/plugin.json index c5d9ff790c..19a7066685 100644 --- a/plugins/color-orb/plugin.json +++ b/plugins/color-orb/plugin.json @@ -17,8 +17,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png", - "directories": [ + "logo": "assets/preview.png" + }, + "com.github.awesome-copilot": { + "extensions": [ "./extensions/color-orb" ] } diff --git a/plugins/context-engineering/plugin.json b/plugins/context-engineering/plugin.json index e947503452..a7dcd47cdf 100644 --- a/plugins/context-engineering/plugin.json +++ b/plugins/context-engineering/plugin.json @@ -15,12 +15,16 @@ "best-practices", "architecture" ], - "agents": [ - "./agents/context-architect.md" - ], - "skills": [ - "./skills/context-map/", - "./skills/refactor-plan/", - "./skills/what-context-needed/" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/context-architect.md" + ], + "skills": [ + "./skills/context-map/", + "./skills/refactor-plan/", + "./skills/what-context-needed/" + ] + } + } } diff --git a/plugins/context-matic/plugin.json b/plugins/context-matic/plugin.json index 2a1fe69525..752fa1f13c 100644 --- a/plugins/context-matic/plugin.json +++ b/plugins/context-matic/plugin.json @@ -19,8 +19,12 @@ "homepage": "https://www.apimatic.io", "repository": "https://github.com/github/awesome-copilot", "license": "MIT", - "skills": [ - "./skills/integrate-context-matic/", - "./skills/onboard-context-matic/" - ] + "extensions": { + "com.github.awesome-copilot": { + "skills": [ + "./skills/integrate-context-matic/", + "./skills/onboard-context-matic/" + ] + } + } } diff --git a/plugins/convert-to-md/plugin.json b/plugins/convert-to-md/plugin.json index dc26f00062..64182adb68 100644 --- a/plugins/convert-to-md/plugin.json +++ b/plugins/convert-to-md/plugin.json @@ -17,9 +17,13 @@ }, "repository": "https://github.com/github/awesome-copilot", "license": "MIT", - "skills": [ - "./skills/convert-excel-to-md/", - "./skills/convert-pdf-to-md/", - "./skills/convert-word-to-md/" - ] + "extensions": { + "com.github.awesome-copilot": { + "skills": [ + "./skills/convert-excel-to-md/", + "./skills/convert-pdf-to-md/", + "./skills/convert-word-to-md/" + ] + } + } } diff --git a/plugins/copilot-sdk/plugin.json b/plugins/copilot-sdk/plugin.json index 01cf7b409f..31c1a0fb27 100644 --- a/plugins/copilot-sdk/plugin.json +++ b/plugins/copilot-sdk/plugin.json @@ -19,7 +19,11 @@ "ai", "github-copilot" ], - "skills": [ - "./skills/copilot-sdk/" - ] + "extensions": { + "com.github.awesome-copilot": { + "skills": [ + "./skills/copilot-sdk/" + ] + } + } } diff --git a/plugins/csharp-dotnet-development/plugin.json b/plugins/csharp-dotnet-development/plugin.json index 036434653a..23c1b445b5 100644 --- a/plugins/csharp-dotnet-development/plugin.json +++ b/plugins/csharp-dotnet-development/plugin.json @@ -14,17 +14,21 @@ "aspnet", "testing" ], - "agents": [ - "./agents/expert-dotnet-software-engineer.md" - ], - "skills": [ - "./skills/aspnet-minimal-api-openapi/", - "./skills/csharp-async/", - "./skills/csharp-mstest/", - "./skills/csharp-nunit/", - "./skills/csharp-tunit/", - "./skills/csharp-xunit/", - "./skills/dotnet-best-practices/", - "./skills/dotnet-upgrade/" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/expert-dotnet-software-engineer.md" + ], + "skills": [ + "./skills/aspnet-minimal-api-openapi/", + "./skills/csharp-async/", + "./skills/csharp-mstest/", + "./skills/csharp-nunit/", + "./skills/csharp-tunit/", + "./skills/csharp-xunit/", + "./skills/dotnet-best-practices/", + "./skills/dotnet-upgrade/" + ] + } + } } diff --git a/plugins/database-data-management/plugin.json b/plugins/database-data-management/plugin.json index 20478636ca..20e55769b8 100644 --- a/plugins/database-data-management/plugin.json +++ b/plugins/database-data-management/plugin.json @@ -18,14 +18,18 @@ "queries", "data-management" ], - "agents": [ - "./agents/ms-sql-dba.md", - "./agents/postgresql-dba.md" - ], - "skills": [ - "./skills/postgresql-code-review/", - "./skills/postgresql-optimization/", - "./skills/sql-code-review/", - "./skills/sql-optimization/" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/ms-sql-dba.md", + "./agents/postgresql-dba.md" + ], + "skills": [ + "./skills/postgresql-code-review/", + "./skills/postgresql-optimization/", + "./skills/sql-code-review/", + "./skills/sql-optimization/" + ] + } + } } diff --git a/plugins/dataverse-sdk-for-python/plugin.json b/plugins/dataverse-sdk-for-python/plugin.json index 6aa8733988..1de7177c38 100644 --- a/plugins/dataverse-sdk-for-python/plugin.json +++ b/plugins/dataverse-sdk-for-python/plugin.json @@ -14,10 +14,14 @@ "integration", "sdk" ], - "skills": [ - "./skills/dataverse-python-advanced-patterns/", - "./skills/dataverse-python-production-code/", - "./skills/dataverse-python-quickstart/", - "./skills/dataverse-python-usecase-builder/" - ] + "extensions": { + "com.github.awesome-copilot": { + "skills": [ + "./skills/dataverse-python-advanced-patterns/", + "./skills/dataverse-python-production-code/", + "./skills/dataverse-python-quickstart/", + "./skills/dataverse-python-usecase-builder/" + ] + } + } } diff --git a/plugins/devops-oncall/plugin.json b/plugins/devops-oncall/plugin.json index 8167edaad5..2b4aaf89cc 100644 --- a/plugins/devops-oncall/plugin.json +++ b/plugins/devops-oncall/plugin.json @@ -14,11 +14,15 @@ "oncall", "azure" ], - "agents": [ - "./agents/azure-principal-architect.md" - ], - "skills": [ - "./skills/azure-resource-health-diagnose/", - "./skills/multi-stage-dockerfile/" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/azure-principal-architect.md" + ], + "skills": [ + "./skills/azure-resource-health-diagnose/", + "./skills/multi-stage-dockerfile/" + ] + } + } } diff --git a/plugins/diagram-viewer/plugin.json b/plugins/diagram-viewer/plugin.json index d9be58b1e8..5e282915a1 100644 --- a/plugins/diagram-viewer/plugin.json +++ b/plugins/diagram-viewer/plugin.json @@ -17,8 +17,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png", - "directories": [ + "logo": "assets/preview.png" + }, + "com.github.awesome-copilot": { + "extensions": [ "./extensions/diagram-viewer" ] } diff --git a/plugins/doublecheck/plugin.json b/plugins/doublecheck/plugin.json index 96f0cdd457..4e277cd661 100644 --- a/plugins/doublecheck/plugin.json +++ b/plugins/doublecheck/plugin.json @@ -16,10 +16,14 @@ "trust", "safety" ], - "agents": [ - "./agents/doublecheck.md" - ], - "skills": [ - "./skills/doublecheck/" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/doublecheck.md" + ], + "skills": [ + "./skills/doublecheck/" + ] + } + } } diff --git a/plugins/edge-ai-tasks/plugin.json b/plugins/edge-ai-tasks/plugin.json index dee3f2bea4..45fb8559e5 100644 --- a/plugins/edge-ai-tasks/plugin.json +++ b/plugins/edge-ai-tasks/plugin.json @@ -15,8 +15,12 @@ "tasks", "implementation" ], - "agents": [ - "./agents/task-planner.md", - "./agents/task-researcher.md" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/task-planner.md", + "./agents/task-researcher.md" + ] + } + } } diff --git a/plugins/ember/plugin.json b/plugins/ember/plugin.json index 7cf42e751f..139432ca35 100644 --- a/plugins/ember/plugin.json +++ b/plugins/ember/plugin.json @@ -16,13 +16,17 @@ "storytelling", "developer-experience" ], - "agents": [ - "./agents/ember.md" - ], - "skills": [ - "./skills/from-the-other-side-anitta/", - "./skills/from-the-other-side-quinn/", - "./skills/from-the-other-side-vega/", - "./skills/from-the-other-side-wiggins/" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/ember.md" + ], + "skills": [ + "./skills/from-the-other-side-anitta/", + "./skills/from-the-other-side-quinn/", + "./skills/from-the-other-side-vega/", + "./skills/from-the-other-side-wiggins/" + ] + } + } } diff --git a/plugins/eyeball/plugin.json b/plugins/eyeball/plugin.json index 45fffa397b..1f9e685b36 100644 --- a/plugins/eyeball/plugin.json +++ b/plugins/eyeball/plugin.json @@ -17,7 +17,11 @@ "trust", "visual-verification" ], - "skills": [ - "./skills/eyeball/" - ] + "extensions": { + "com.github.awesome-copilot": { + "skills": [ + "./skills/eyeball/" + ] + } + } } diff --git a/plugins/fastah-ip-geo-tools/plugin.json b/plugins/fastah-ip-geo-tools/plugin.json index 977a299093..d0b1600378 100644 --- a/plugins/fastah-ip-geo-tools/plugin.json +++ b/plugins/fastah-ip-geo-tools/plugin.json @@ -20,7 +20,11 @@ "hosting", "ixp" ], - "skills": [ - "./skills/geofeed-tuner/" - ] + "extensions": { + "com.github.awesome-copilot": { + "skills": [ + "./skills/geofeed-tuner/" + ] + } + } } diff --git a/plugins/feedback-themes/plugin.json b/plugins/feedback-themes/plugin.json index c1f0ca1715..0a3a3305a9 100644 --- a/plugins/feedback-themes/plugin.json +++ b/plugins/feedback-themes/plugin.json @@ -17,8 +17,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png", - "directories": [ + "logo": "assets/preview.png" + }, + "com.github.awesome-copilot": { + "extensions": [ "./extensions/feedback-themes" ] } diff --git a/plugins/flight-map-canvas/plugin.json b/plugins/flight-map-canvas/plugin.json index d1d3fc7e68..f70b8b4202 100644 --- a/plugins/flight-map-canvas/plugin.json +++ b/plugins/flight-map-canvas/plugin.json @@ -17,8 +17,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png", - "directories": [ + "logo": "assets/preview.png" + }, + "com.github.awesome-copilot": { + "extensions": [ "./extensions/flight-map-canvas" ] } diff --git a/plugins/flowstudio-power-automate/plugin.json b/plugins/flowstudio-power-automate/plugin.json index 912fa35a2b..d915331a3e 100644 --- a/plugins/flowstudio-power-automate/plugin.json +++ b/plugins/flowstudio-power-automate/plugin.json @@ -19,11 +19,15 @@ "monitoring", "governance" ], - "skills": [ - "./skills/flowstudio-power-automate-build/", - "./skills/flowstudio-power-automate-debug/", - "./skills/flowstudio-power-automate-governance/", - "./skills/flowstudio-power-automate-mcp/", - "./skills/flowstudio-power-automate-monitoring/" - ] + "extensions": { + "com.github.awesome-copilot": { + "skills": [ + "./skills/flowstudio-power-automate-build/", + "./skills/flowstudio-power-automate-debug/", + "./skills/flowstudio-power-automate-governance/", + "./skills/flowstudio-power-automate-mcp/", + "./skills/flowstudio-power-automate-monitoring/" + ] + } + } } diff --git a/plugins/frontend-web-dev/plugin.json b/plugins/frontend-web-dev/plugin.json index 5e56d4f524..d0c15f66b9 100644 --- a/plugins/frontend-web-dev/plugin.json +++ b/plugins/frontend-web-dev/plugin.json @@ -19,12 +19,16 @@ "angular", "vue" ], - "agents": [ - "./agents/electron-angular-native.md", - "./agents/expert-react-frontend-engineer.md" - ], - "skills": [ - "./skills/playwright-explore-website/", - "./skills/playwright-generate-test/" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/electron-angular-native.md", + "./agents/expert-react-frontend-engineer.md" + ], + "skills": [ + "./skills/playwright-explore-website/", + "./skills/playwright-generate-test/" + ] + } + } } diff --git a/plugins/gesture-review/plugin.json b/plugins/gesture-review/plugin.json index 5c26cb8d28..5c178a6956 100644 --- a/plugins/gesture-review/plugin.json +++ b/plugins/gesture-review/plugin.json @@ -17,8 +17,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png", - "directories": [ + "logo": "assets/preview.png" + }, + "com.github.awesome-copilot": { + "extensions": [ "./extensions/gesture-review" ] } diff --git a/plugins/go-mcp-development/plugin.json b/plugins/go-mcp-development/plugin.json index b19bf9446b..51d99dedd8 100644 --- a/plugins/go-mcp-development/plugin.json +++ b/plugins/go-mcp-development/plugin.json @@ -16,10 +16,14 @@ "server-development", "sdk" ], - "agents": [ - "./agents/go-mcp-expert.md" - ], - "skills": [ - "./skills/go-mcp-server-generator/" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/go-mcp-expert.md" + ], + "skills": [ + "./skills/go-mcp-server-generator/" + ] + } + } } diff --git a/plugins/java-development/plugin.json b/plugins/java-development/plugin.json index ae1e62308e..dfb7b8cce1 100644 --- a/plugins/java-development/plugin.json +++ b/plugins/java-development/plugin.json @@ -16,10 +16,14 @@ "junit", "javadoc" ], - "skills": [ - "./skills/create-spring-boot-java-project/", - "./skills/java-docs/", - "./skills/java-junit/", - "./skills/java-springboot/" - ] + "extensions": { + "com.github.awesome-copilot": { + "skills": [ + "./skills/create-spring-boot-java-project/", + "./skills/java-docs/", + "./skills/java-junit/", + "./skills/java-springboot/" + ] + } + } } diff --git a/plugins/java-mcp-development/plugin.json b/plugins/java-mcp-development/plugin.json index bb531544e0..46334adf68 100644 --- a/plugins/java-mcp-development/plugin.json +++ b/plugins/java-mcp-development/plugin.json @@ -18,10 +18,14 @@ "spring-boot", "reactor" ], - "agents": [ - "./agents/java-mcp-expert.md" - ], - "skills": [ - "./skills/java-mcp-server-generator/" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/java-mcp-expert.md" + ], + "skills": [ + "./skills/java-mcp-server-generator/" + ] + } + } } diff --git a/plugins/java-modernization-studio/plugin.json b/plugins/java-modernization-studio/plugin.json index a28e3643e9..8695d78edd 100644 --- a/plugins/java-modernization-studio/plugin.json +++ b/plugins/java-modernization-studio/plugin.json @@ -18,8 +18,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png", - "directories": [ + "logo": "assets/preview.png" + }, + "com.github.awesome-copilot": { + "extensions": [ "./extensions/java-modernization-studio" ] } diff --git a/plugins/kotlin-mcp-development/plugin.json b/plugins/kotlin-mcp-development/plugin.json index 9a0324f1aa..7dca5aa72b 100644 --- a/plugins/kotlin-mcp-development/plugin.json +++ b/plugins/kotlin-mcp-development/plugin.json @@ -16,10 +16,14 @@ "server-development", "ktor" ], - "agents": [ - "./agents/kotlin-mcp-expert.md" - ], - "skills": [ - "./skills/kotlin-mcp-server-generator/" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/kotlin-mcp-expert.md" + ], + "skills": [ + "./skills/kotlin-mcp-server-generator/" + ] + } + } } diff --git a/plugins/mcp-m365-copilot/plugin.json b/plugins/mcp-m365-copilot/plugin.json index c5f624e9ce..9432be3d9c 100644 --- a/plugins/mcp-m365-copilot/plugin.json +++ b/plugins/mcp-m365-copilot/plugin.json @@ -16,12 +16,16 @@ "model-context-protocol", "adaptive-cards" ], - "agents": [ - "./agents/mcp-m365-agent-expert.md" - ], - "skills": [ - "./skills/mcp-create-adaptive-cards/", - "./skills/mcp-create-declarative-agent/", - "./skills/mcp-deploy-manage-agents/" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/mcp-m365-agent-expert.md" + ], + "skills": [ + "./skills/mcp-create-adaptive-cards/", + "./skills/mcp-create-declarative-agent/", + "./skills/mcp-deploy-manage-agents/" + ] + } + } } diff --git a/plugins/napkin/plugin.json b/plugins/napkin/plugin.json index 6acac2b754..ac4542e389 100644 --- a/plugins/napkin/plugin.json +++ b/plugins/napkin/plugin.json @@ -20,7 +20,11 @@ "copilot-cli", "ux" ], - "skills": [ - "./skills/napkin/" - ] + "extensions": { + "com.github.awesome-copilot": { + "skills": [ + "./skills/napkin/" + ] + } + } } diff --git a/plugins/noob-mode/plugin.json b/plugins/noob-mode/plugin.json index 7542fd6092..9f41ee71ac 100644 --- a/plugins/noob-mode/plugin.json +++ b/plugins/noob-mode/plugin.json @@ -17,7 +17,11 @@ "copilot-cli", "ux" ], - "skills": [ - "./skills/noob-mode/" - ] + "extensions": { + "com.github.awesome-copilot": { + "skills": [ + "./skills/noob-mode/" + ] + } + } } diff --git a/plugins/openapi-to-application-csharp-dotnet/plugin.json b/plugins/openapi-to-application-csharp-dotnet/plugin.json index fa73854b88..2c02b96c96 100644 --- a/plugins/openapi-to-application-csharp-dotnet/plugin.json +++ b/plugins/openapi-to-application-csharp-dotnet/plugin.json @@ -16,10 +16,14 @@ "dotnet", "aspnet" ], - "agents": [ - "./agents/openapi-to-application.md" - ], - "skills": [ - "./skills/openapi-to-application-code/" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/openapi-to-application.md" + ], + "skills": [ + "./skills/openapi-to-application-code/" + ] + } + } } diff --git a/plugins/openapi-to-application-go/plugin.json b/plugins/openapi-to-application-go/plugin.json index f2f78a3abb..e3c4bb79fb 100644 --- a/plugins/openapi-to-application-go/plugin.json +++ b/plugins/openapi-to-application-go/plugin.json @@ -15,10 +15,14 @@ "go", "golang" ], - "agents": [ - "./agents/openapi-to-application.md" - ], - "skills": [ - "./skills/openapi-to-application-code/" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/openapi-to-application.md" + ], + "skills": [ + "./skills/openapi-to-application-code/" + ] + } + } } diff --git a/plugins/openapi-to-application-java-spring-boot/plugin.json b/plugins/openapi-to-application-java-spring-boot/plugin.json index 034cbf53f4..0ea1814a9b 100644 --- a/plugins/openapi-to-application-java-spring-boot/plugin.json +++ b/plugins/openapi-to-application-java-spring-boot/plugin.json @@ -15,10 +15,14 @@ "java", "spring-boot" ], - "agents": [ - "./agents/openapi-to-application.md" - ], - "skills": [ - "./skills/openapi-to-application-code/" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/openapi-to-application.md" + ], + "skills": [ + "./skills/openapi-to-application-code/" + ] + } + } } diff --git a/plugins/openapi-to-application-nodejs-nestjs/plugin.json b/plugins/openapi-to-application-nodejs-nestjs/plugin.json index 9402405467..900e58cd5a 100644 --- a/plugins/openapi-to-application-nodejs-nestjs/plugin.json +++ b/plugins/openapi-to-application-nodejs-nestjs/plugin.json @@ -16,10 +16,14 @@ "typescript", "nestjs" ], - "agents": [ - "./agents/openapi-to-application.md" - ], - "skills": [ - "./skills/openapi-to-application-code/" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/openapi-to-application.md" + ], + "skills": [ + "./skills/openapi-to-application-code/" + ] + } + } } diff --git a/plugins/openapi-to-application-python-fastapi/plugin.json b/plugins/openapi-to-application-python-fastapi/plugin.json index fc3281698d..34f7024a2a 100644 --- a/plugins/openapi-to-application-python-fastapi/plugin.json +++ b/plugins/openapi-to-application-python-fastapi/plugin.json @@ -15,10 +15,14 @@ "python", "fastapi" ], - "agents": [ - "./agents/openapi-to-application.md" - ], - "skills": [ - "./skills/openapi-to-application-code/" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/openapi-to-application.md" + ], + "skills": [ + "./skills/openapi-to-application-code/" + ] + } + } } diff --git a/plugins/oracle-to-postgres-migration-expert/plugin.json b/plugins/oracle-to-postgres-migration-expert/plugin.json index d2614adfc0..eb70d318f0 100644 --- a/plugins/oracle-to-postgres-migration-expert/plugin.json +++ b/plugins/oracle-to-postgres-migration-expert/plugin.json @@ -18,16 +18,20 @@ "integration-testing", "stored-procedures" ], - "agents": [ - "./agents/oracle-to-postgres-migration-expert.md" - ], - "skills": [ - "./skills/creating-oracle-to-postgres-master-migration-plan/", - "./skills/creating-oracle-to-postgres-migration-bug-report/", - "./skills/creating-oracle-to-postgres-migration-integration-tests/", - "./skills/migrating-oracle-to-postgres-stored-procedures/", - "./skills/planning-oracle-to-postgres-migration-integration-testing/", - "./skills/reviewing-oracle-to-postgres-migration/", - "./skills/scaffolding-oracle-to-postgres-migration-test-project/" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/oracle-to-postgres-migration-expert.md" + ], + "skills": [ + "./skills/creating-oracle-to-postgres-master-migration-plan/", + "./skills/creating-oracle-to-postgres-migration-bug-report/", + "./skills/creating-oracle-to-postgres-migration-integration-tests/", + "./skills/migrating-oracle-to-postgres-stored-procedures/", + "./skills/planning-oracle-to-postgres-migration-integration-testing/", + "./skills/reviewing-oracle-to-postgres-migration/", + "./skills/scaffolding-oracle-to-postgres-migration-test-project/" + ] + } + } } diff --git a/plugins/ospo-sponsorship/plugin.json b/plugins/ospo-sponsorship/plugin.json index 0de7097f18..5dba685afe 100644 --- a/plugins/ospo-sponsorship/plugin.json +++ b/plugins/ospo-sponsorship/plugin.json @@ -8,7 +8,11 @@ }, "repository": "https://github.com/github/awesome-copilot", "license": "MIT", - "skills": [ - "./skills/sponsor-finder/" - ] + "extensions": { + "com.github.awesome-copilot": { + "skills": [ + "./skills/sponsor-finder/" + ] + } + } } diff --git a/plugins/partners/plugin.json b/plugins/partners/plugin.json index 7fe2bbb010..acc191d855 100644 --- a/plugins/partners/plugin.json +++ b/plugins/partners/plugin.json @@ -20,26 +20,30 @@ "migration", "performance" ], - "agents": [ - "./agents/amplitude-experiment-implementation.md", - "./agents/apify-integration-expert.md", - "./agents/arm-migration.md", - "./agents/comet-opik.md", - "./agents/diffblue-cover.md", - "./agents/droid.md", - "./agents/dynatrace-expert.md", - "./agents/elasticsearch-observability.md", - "./agents/jfrog-sec.md", - "./agents/launchdarkly-flag-cleanup.md", - "./agents/lingodotdev-i18n.md", - "./agents/monday-bug-fixer.md", - "./agents/mongodb-performance-advisor.md", - "./agents/neo4j-docker-client-generator.md", - "./agents/neon-migration-specialist.md", - "./agents/neon-optimization-analyzer.md", - "./agents/octopus-deploy-release-notes-mcp.md", - "./agents/pagerduty-incident-responder.md", - "./agents/stackhawk-security-onboarding.md", - "./agents/terraform.md" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/amplitude-experiment-implementation.md", + "./agents/apify-integration-expert.md", + "./agents/arm-migration.md", + "./agents/comet-opik.md", + "./agents/diffblue-cover.md", + "./agents/droid.md", + "./agents/dynatrace-expert.md", + "./agents/elasticsearch-observability.md", + "./agents/jfrog-sec.md", + "./agents/launchdarkly-flag-cleanup.md", + "./agents/lingodotdev-i18n.md", + "./agents/monday-bug-fixer.md", + "./agents/mongodb-performance-advisor.md", + "./agents/neo4j-docker-client-generator.md", + "./agents/neon-migration-specialist.md", + "./agents/neon-optimization-analyzer.md", + "./agents/octopus-deploy-release-notes-mcp.md", + "./agents/pagerduty-incident-responder.md", + "./agents/stackhawk-security-onboarding.md", + "./agents/terraform.md" + ] + } + } } diff --git a/plugins/phoenix/plugin.json b/plugins/phoenix/plugin.json index fc08905e5d..1a31d714f0 100644 --- a/plugins/phoenix/plugin.json +++ b/plugins/phoenix/plugin.json @@ -18,9 +18,13 @@ "openinference", "instrumentation" ], - "skills": [ - "./skills/phoenix-cli/", - "./skills/phoenix-evals/", - "./skills/phoenix-tracing/" - ] + "extensions": { + "com.github.awesome-copilot": { + "skills": [ + "./skills/phoenix-cli/", + "./skills/phoenix-evals/", + "./skills/phoenix-tracing/" + ] + } + } } diff --git a/plugins/php-mcp-development/plugin.json b/plugins/php-mcp-development/plugin.json index a71524b2a3..aa34284a60 100644 --- a/plugins/php-mcp-development/plugin.json +++ b/plugins/php-mcp-development/plugin.json @@ -17,10 +17,14 @@ "attributes", "composer" ], - "agents": [ - "./agents/php-mcp-expert.md" - ], - "skills": [ - "./skills/php-mcp-server-generator/" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/php-mcp-expert.md" + ], + "skills": [ + "./skills/php-mcp-server-generator/" + ] + } + } } diff --git a/plugins/power-apps-code-apps/plugin.json b/plugins/power-apps-code-apps/plugin.json index 6f1584aa21..0d928f56cd 100644 --- a/plugins/power-apps-code-apps/plugin.json +++ b/plugins/power-apps-code-apps/plugin.json @@ -17,10 +17,14 @@ "dataverse", "connectors" ], - "agents": [ - "./agents/power-platform-expert.md" - ], - "skills": [ - "./skills/power-apps-code-app-scaffold/" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/power-platform-expert.md" + ], + "skills": [ + "./skills/power-apps-code-app-scaffold/" + ] + } + } } diff --git a/plugins/power-bi-development/plugin.json b/plugins/power-bi-development/plugin.json index cfcc570b41..ac889da947 100644 --- a/plugins/power-bi-development/plugin.json +++ b/plugins/power-bi-development/plugin.json @@ -18,16 +18,20 @@ "devops", "business-intelligence" ], - "agents": [ - "./agents/power-bi-data-modeling-expert.md", - "./agents/power-bi-dax-expert.md", - "./agents/power-bi-performance-expert.md", - "./agents/power-bi-visualization-expert.md" - ], - "skills": [ - "./skills/power-bi-dax-optimization/", - "./skills/power-bi-model-design-review/", - "./skills/power-bi-performance-troubleshooting/", - "./skills/power-bi-report-design-consultation/" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/power-bi-data-modeling-expert.md", + "./agents/power-bi-dax-expert.md", + "./agents/power-bi-performance-expert.md", + "./agents/power-bi-visualization-expert.md" + ], + "skills": [ + "./skills/power-bi-dax-optimization/", + "./skills/power-bi-model-design-review/", + "./skills/power-bi-performance-troubleshooting/", + "./skills/power-bi-report-design-consultation/" + ] + } + } } diff --git a/plugins/power-platform-architect/plugin.json b/plugins/power-platform-architect/plugin.json index 5af88cd255..9e40bea7b5 100644 --- a/plugins/power-platform-architect/plugin.json +++ b/plugins/power-platform-architect/plugin.json @@ -17,7 +17,11 @@ }, "repository": "https://github.com/github/awesome-copilot", "license": "MIT", - "skills": [ - "./skills/power-platform-architect/" - ] + "extensions": { + "com.github.awesome-copilot": { + "skills": [ + "./skills/power-platform-architect/" + ] + } + } } diff --git a/plugins/power-platform-mcp-connector-development/plugin.json b/plugins/power-platform-mcp-connector-development/plugin.json index 394598dfe0..eb323e751e 100644 --- a/plugins/power-platform-mcp-connector-development/plugin.json +++ b/plugins/power-platform-mcp-connector-development/plugin.json @@ -15,11 +15,15 @@ "custom-connector", "json-rpc" ], - "agents": [ - "./agents/power-platform-mcp-integration-expert.md" - ], - "skills": [ - "./skills/mcp-copilot-studio-server-generator/", - "./skills/power-platform-mcp-connector-suite/" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/power-platform-mcp-integration-expert.md" + ], + "skills": [ + "./skills/mcp-copilot-studio-server-generator/", + "./skills/power-platform-mcp-connector-suite/" + ] + } + } } diff --git a/plugins/pr-artifact-explorer/plugin.json b/plugins/pr-artifact-explorer/plugin.json index c15f3919be..2841734f7b 100644 --- a/plugins/pr-artifact-explorer/plugin.json +++ b/plugins/pr-artifact-explorer/plugin.json @@ -17,8 +17,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png", - "directories": [ + "logo": "assets/preview.png" + }, + "com.github.awesome-copilot": { + "extensions": [ "./extensions/pr-artifact-explorer" ] } diff --git a/plugins/project-documenter/plugin.json b/plugins/project-documenter/plugin.json index cd21f2db48..b1866c6485 100644 --- a/plugins/project-documenter/plugin.json +++ b/plugins/project-documenter/plugin.json @@ -19,11 +19,15 @@ "project-summary", "auto-discovery" ], - "agents": [ - "./agents/project-documenter.md" - ], - "skills": [ - "./skills/drawio/", - "./skills/md-to-docx/" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/project-documenter.md" + ], + "skills": [ + "./skills/drawio/", + "./skills/md-to-docx/" + ] + } + } } diff --git a/plugins/project-planning/plugin.json b/plugins/project-planning/plugin.json index 1a7f26c8d6..480cc56fc2 100644 --- a/plugins/project-planning/plugin.json +++ b/plugins/project-planning/plugin.json @@ -18,23 +18,27 @@ "architecture", "technical-spike" ], - "agents": [ - "./agents/implementation-plan.md", - "./agents/plan.md", - "./agents/planner.md", - "./agents/prd.md", - "./agents/research-technical-spike.md", - "./agents/task-planner.md", - "./agents/task-researcher.md" - ], - "skills": [ - "./skills/breakdown-epic-arch/", - "./skills/breakdown-epic-pm/", - "./skills/breakdown-feature-implementation/", - "./skills/breakdown-feature-prd/", - "./skills/create-github-issues-feature-from-implementation-plan/", - "./skills/create-implementation-plan/", - "./skills/create-technical-spike/", - "./skills/update-implementation-plan/" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/implementation-plan.md", + "./agents/plan.md", + "./agents/planner.md", + "./agents/prd.md", + "./agents/research-technical-spike.md", + "./agents/task-planner.md", + "./agents/task-researcher.md" + ], + "skills": [ + "./skills/breakdown-epic-arch/", + "./skills/breakdown-epic-pm/", + "./skills/breakdown-feature-implementation/", + "./skills/breakdown-feature-prd/", + "./skills/create-github-issues-feature-from-implementation-plan/", + "./skills/create-implementation-plan/", + "./skills/create-technical-spike/", + "./skills/update-implementation-plan/" + ] + } + } } diff --git a/plugins/python-mcp-development/plugin.json b/plugins/python-mcp-development/plugin.json index 350d5717d3..a8b9a9d2c4 100644 --- a/plugins/python-mcp-development/plugin.json +++ b/plugins/python-mcp-development/plugin.json @@ -15,10 +15,14 @@ "fastmcp", "server-development" ], - "agents": [ - "./agents/python-mcp-expert.md" - ], - "skills": [ - "./skills/python-mcp-server-generator/" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/python-mcp-expert.md" + ], + "skills": [ + "./skills/python-mcp-server-generator/" + ] + } + } } diff --git a/plugins/react18-upgrade/plugin.json b/plugins/react18-upgrade/plugin.json index 4d73415239..306b3b9a65 100644 --- a/plugins/react18-upgrade/plugin.json +++ b/plugins/react18-upgrade/plugin.json @@ -17,21 +17,25 @@ }, "repository": "https://github.com/github/awesome-copilot", "license": "MIT", - "agents": [ - "./agents/react18-auditor.md", - "./agents/react18-batching-fixer.md", - "./agents/react18-class-surgeon.md", - "./agents/react18-commander.md", - "./agents/react18-dep-surgeon.md", - "./agents/react18-test-guardian.md" - ], - "skills": [ - "./skills/react-audit-grep-patterns/", - "./skills/react18-batching-patterns/", - "./skills/react18-dep-compatibility/", - "./skills/react18-enzyme-to-rtl/", - "./skills/react18-legacy-context/", - "./skills/react18-lifecycle-patterns/", - "./skills/react18-string-refs/" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/react18-auditor.md", + "./agents/react18-batching-fixer.md", + "./agents/react18-class-surgeon.md", + "./agents/react18-commander.md", + "./agents/react18-dep-surgeon.md", + "./agents/react18-test-guardian.md" + ], + "skills": [ + "./skills/react-audit-grep-patterns/", + "./skills/react18-batching-patterns/", + "./skills/react18-dep-compatibility/", + "./skills/react18-enzyme-to-rtl/", + "./skills/react18-legacy-context/", + "./skills/react18-lifecycle-patterns/", + "./skills/react18-string-refs/" + ] + } + } } diff --git a/plugins/react19-upgrade/plugin.json b/plugins/react19-upgrade/plugin.json index 5331c3b2a5..1312038cc1 100644 --- a/plugins/react19-upgrade/plugin.json +++ b/plugins/react19-upgrade/plugin.json @@ -16,16 +16,20 @@ }, "repository": "https://github.com/github/awesome-copilot", "license": "MIT", - "agents": [ - "./agents/react19-auditor.md", - "./agents/react19-commander.md", - "./agents/react19-dep-surgeon.md", - "./agents/react19-migrator.md", - "./agents/react19-test-guardian.md" - ], - "skills": [ - "./skills/react19-concurrent-patterns/", - "./skills/react19-source-patterns/", - "./skills/react19-test-patterns/" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/react19-auditor.md", + "./agents/react19-commander.md", + "./agents/react19-dep-surgeon.md", + "./agents/react19-migrator.md", + "./agents/react19-test-guardian.md" + ], + "skills": [ + "./skills/react19-concurrent-patterns/", + "./skills/react19-source-patterns/", + "./skills/react19-test-patterns/" + ] + } + } } diff --git a/plugins/release-notes-showcase/plugin.json b/plugins/release-notes-showcase/plugin.json index 034950661e..79b55e299c 100644 --- a/plugins/release-notes-showcase/plugin.json +++ b/plugins/release-notes-showcase/plugin.json @@ -17,8 +17,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png", - "directories": [ + "logo": "assets/preview.png" + }, + "com.github.awesome-copilot": { + "extensions": [ "./extensions/release-notes-showcase" ] } diff --git a/plugins/repo-actions-hub/plugin.json b/plugins/repo-actions-hub/plugin.json index de30aaf02b..2ecb30c433 100644 --- a/plugins/repo-actions-hub/plugin.json +++ b/plugins/repo-actions-hub/plugin.json @@ -17,8 +17,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png", - "directories": [ + "logo": "assets/preview.png" + }, + "com.github.awesome-copilot": { + "extensions": [ "./extensions/repo-actions-hub" ] } diff --git a/plugins/roundup/plugin.json b/plugins/roundup/plugin.json index 0837fec32d..76828c938f 100644 --- a/plugins/roundup/plugin.json +++ b/plugins/roundup/plugin.json @@ -18,8 +18,12 @@ "roundup", "copilot-cli" ], - "skills": [ - "./skills/roundup-setup/", - "./skills/roundup/" - ] + "extensions": { + "com.github.awesome-copilot": { + "skills": [ + "./skills/roundup-setup/", + "./skills/roundup/" + ] + } + } } diff --git a/plugins/ruby-mcp-development/plugin.json b/plugins/ruby-mcp-development/plugin.json index 8fe28ad858..5a75032fcb 100644 --- a/plugins/ruby-mcp-development/plugin.json +++ b/plugins/ruby-mcp-development/plugin.json @@ -17,10 +17,14 @@ "rails", "gem" ], - "agents": [ - "./agents/ruby-mcp-expert.md" - ], - "skills": [ - "./skills/ruby-mcp-server-generator/" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/ruby-mcp-expert.md" + ], + "skills": [ + "./skills/ruby-mcp-server-generator/" + ] + } + } } diff --git a/plugins/rug-agentic-workflow/plugin.json b/plugins/rug-agentic-workflow/plugin.json index 94ac621e05..07a827ada2 100644 --- a/plugins/rug-agentic-workflow/plugin.json +++ b/plugins/rug-agentic-workflow/plugin.json @@ -15,9 +15,13 @@ "software-engineering", "qa" ], - "agents": [ - "./agents/qa-subagent.md", - "./agents/rug-orchestrator.md", - "./agents/swe-subagent.md" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/qa-subagent.md", + "./agents/rug-orchestrator.md", + "./agents/swe-subagent.md" + ] + } + } } diff --git a/plugins/rust-mcp-development/plugin.json b/plugins/rust-mcp-development/plugin.json index 24235b8bfb..ba36d26b13 100644 --- a/plugins/rust-mcp-development/plugin.json +++ b/plugins/rust-mcp-development/plugin.json @@ -19,10 +19,14 @@ "macros", "rmcp" ], - "agents": [ - "./agents/rust-mcp-expert.md" - ], - "skills": [ - "./skills/rust-mcp-server-generator/" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/rust-mcp-expert.md" + ], + "skills": [ + "./skills/rust-mcp-server-generator/" + ] + } + } } diff --git a/plugins/salesforce-development/plugin.json b/plugins/salesforce-development/plugin.json index 8ca5bb4052..760cfc6926 100644 --- a/plugins/salesforce-development/plugin.json +++ b/plugins/salesforce-development/plugin.json @@ -19,15 +19,19 @@ "crm", "salesforce-dx" ], - "agents": [ - "./agents/salesforce-apex-triggers.md", - "./agents/salesforce-aura-lwc.md", - "./agents/salesforce-flow.md", - "./agents/salesforce-visualforce.md" - ], - "skills": [ - "./skills/salesforce-apex-quality/", - "./skills/salesforce-component-standards/", - "./skills/salesforce-flow-design/" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/salesforce-apex-triggers.md", + "./agents/salesforce-aura-lwc.md", + "./agents/salesforce-flow.md", + "./agents/salesforce-visualforce.md" + ], + "skills": [ + "./skills/salesforce-apex-quality/", + "./skills/salesforce-component-standards/", + "./skills/salesforce-flow-design/" + ] + } + } } diff --git a/plugins/security-best-practices/plugin.json b/plugins/security-best-practices/plugin.json index 6bfc2f7574..bb39305c9e 100644 --- a/plugins/security-best-practices/plugin.json +++ b/plugins/security-best-practices/plugin.json @@ -18,7 +18,11 @@ "optimization", "best-practices" ], - "skills": [ - "./skills/ai-prompt-engineering-safety-review/" - ] + "extensions": { + "com.github.awesome-copilot": { + "skills": [ + "./skills/ai-prompt-engineering-safety-review/" + ] + } + } } diff --git a/plugins/signals-dashboard/plugin.json b/plugins/signals-dashboard/plugin.json index 6efe14fd32..93405eb448 100644 --- a/plugins/signals-dashboard/plugin.json +++ b/plugins/signals-dashboard/plugin.json @@ -15,8 +15,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png", - "directories": [ + "logo": "assets/preview.png" + }, + "com.github.awesome-copilot": { + "extensions": [ "./extensions/signals-dashboard" ] } diff --git a/plugins/site-studio/plugin.json b/plugins/site-studio/plugin.json index 0762279880..f87f126dfb 100644 --- a/plugins/site-studio/plugin.json +++ b/plugins/site-studio/plugin.json @@ -17,8 +17,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png", - "directories": [ + "logo": "assets/preview.png" + }, + "com.github.awesome-copilot": { + "extensions": [ "./extensions/site-studio" ] } diff --git a/plugins/skill-image-gen/plugin.json b/plugins/skill-image-gen/plugin.json index b0fcfafa71..1127ce0a37 100644 --- a/plugins/skill-image-gen/plugin.json +++ b/plugins/skill-image-gen/plugin.json @@ -20,7 +20,11 @@ "homepage": "https://github.com/adamd9/skill-image-gen", "repository": "https://github.com/github/awesome-copilot", "license": "MIT", - "skills": [ - "./skills/generate-image/" - ] + "extensions": { + "com.github.awesome-copilot": { + "skills": [ + "./skills/generate-image/" + ] + } + } } diff --git a/plugins/software-engineering-team/plugin.json b/plugins/software-engineering-team/plugin.json index 5eef6a2cc4..34e55361b3 100644 --- a/plugins/software-engineering-team/plugin.json +++ b/plugins/software-engineering-team/plugin.json @@ -18,13 +18,17 @@ "product", "ai-ethics" ], - "agents": [ - "./agents/se-gitops-ci-specialist.md", - "./agents/se-product-manager-advisor.md", - "./agents/se-responsible-ai-code.md", - "./agents/se-security-reviewer.md", - "./agents/se-system-architecture-reviewer.md", - "./agents/se-technical-writer.md", - "./agents/se-ux-ui-designer.md" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/se-gitops-ci-specialist.md", + "./agents/se-product-manager-advisor.md", + "./agents/se-responsible-ai-code.md", + "./agents/se-security-reviewer.md", + "./agents/se-system-architecture-reviewer.md", + "./agents/se-technical-writer.md", + "./agents/se-ux-ui-designer.md" + ] + } + } } diff --git a/plugins/structured-autonomy/plugin.json b/plugins/structured-autonomy/plugin.json index 6e6307e147..f9d65224ec 100644 --- a/plugins/structured-autonomy/plugin.json +++ b/plugins/structured-autonomy/plugin.json @@ -8,9 +8,13 @@ }, "repository": "https://github.com/github/awesome-copilot", "license": "MIT", - "skills": [ - "./skills/structured-autonomy-generate/", - "./skills/structured-autonomy-implement/", - "./skills/structured-autonomy-plan/" - ] + "extensions": { + "com.github.awesome-copilot": { + "skills": [ + "./skills/structured-autonomy-generate/", + "./skills/structured-autonomy-implement/", + "./skills/structured-autonomy-plan/" + ] + } + } } diff --git a/plugins/swift-mcp-development/plugin.json b/plugins/swift-mcp-development/plugin.json index b57e4a7dcc..c3beb87e67 100644 --- a/plugins/swift-mcp-development/plugin.json +++ b/plugins/swift-mcp-development/plugin.json @@ -20,10 +20,14 @@ "actor", "async-await" ], - "agents": [ - "./agents/swift-mcp-expert.md" - ], - "skills": [ - "./skills/swift-mcp-server-generator/" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/swift-mcp-expert.md" + ], + "skills": [ + "./skills/swift-mcp-server-generator/" + ] + } + } } diff --git a/plugins/technical-spike/plugin.json b/plugins/technical-spike/plugin.json index cb6369e1d4..8a9a57cbd7 100644 --- a/plugins/technical-spike/plugin.json +++ b/plugins/technical-spike/plugin.json @@ -14,10 +14,14 @@ "validation", "research" ], - "agents": [ - "./agents/research-technical-spike.md" - ], - "skills": [ - "./skills/create-technical-spike/" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/research-technical-spike.md" + ], + "skills": [ + "./skills/create-technical-spike/" + ] + } + } } diff --git a/plugins/testing-automation/plugin.json b/plugins/testing-automation/plugin.json index 288857ef0a..153f05aa31 100644 --- a/plugins/testing-automation/plugin.json +++ b/plugins/testing-automation/plugin.json @@ -18,17 +18,21 @@ "jest", "nunit" ], - "agents": [ - "./agents/playwright-tester.md", - "./agents/tdd-green.md", - "./agents/tdd-red.md", - "./agents/tdd-refactor.md" - ], - "skills": [ - "./skills/ai-prompt-engineering-safety-review/", - "./skills/csharp-nunit/", - "./skills/java-junit/", - "./skills/playwright-explore-website/", - "./skills/playwright-generate-test/" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/playwright-tester.md", + "./agents/tdd-green.md", + "./agents/tdd-red.md", + "./agents/tdd-refactor.md" + ], + "skills": [ + "./skills/ai-prompt-engineering-safety-review/", + "./skills/csharp-nunit/", + "./skills/java-junit/", + "./skills/playwright-explore-website/", + "./skills/playwright-generate-test/" + ] + } + } } diff --git a/plugins/the-workshop/plugin.json b/plugins/the-workshop/plugin.json index 705cf8e0ca..5008b66777 100644 --- a/plugins/the-workshop/plugin.json +++ b/plugins/the-workshop/plugin.json @@ -16,19 +16,19 @@ "agent-signals", "developer-experience" ], - "agents": [ - "./agents/workshop-ta.md" - ], - "skills": [ - "./skills/bench-read/", - "./skills/desk-journal/", - "./skills/desk-open/", - "./skills/signal-write/", - "./skills/workshop-create/" - ], "extensions": { - "com.github.copilot": { - "directories": [ + "com.github.awesome-copilot": { + "agents": [ + "./agents/workshop-ta.md" + ], + "skills": [ + "./skills/bench-read/", + "./skills/desk-journal/", + "./skills/desk-open/", + "./skills/signal-write/", + "./skills/workshop-create/" + ], + "extensions": [ "./extensions/signals-dashboard" ] } diff --git a/plugins/tiny-tool-town-submitter/plugin.json b/plugins/tiny-tool-town-submitter/plugin.json index 04f639ffb2..4b9964d85b 100644 --- a/plugins/tiny-tool-town-submitter/plugin.json +++ b/plugins/tiny-tool-town-submitter/plugin.json @@ -17,8 +17,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png", - "directories": [ + "logo": "assets/preview.png" + }, + "com.github.awesome-copilot": { + "extensions": [ "./extensions/tiny-tool-town-submitter" ] } diff --git a/plugins/token-pacman/plugin.json b/plugins/token-pacman/plugin.json index eee9a94a0c..4df2a5a602 100644 --- a/plugins/token-pacman/plugin.json +++ b/plugins/token-pacman/plugin.json @@ -17,8 +17,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png", - "directories": [ + "logo": "assets/preview.png" + }, + "com.github.awesome-copilot": { + "extensions": [ "./extensions/token-pacman" ] } diff --git a/plugins/typescript-mcp-development/plugin.json b/plugins/typescript-mcp-development/plugin.json index 02381e88fe..5711205e84 100644 --- a/plugins/typescript-mcp-development/plugin.json +++ b/plugins/typescript-mcp-development/plugin.json @@ -15,10 +15,14 @@ "nodejs", "server-development" ], - "agents": [ - "./agents/typescript-mcp-expert.md" - ], - "skills": [ - "./skills/typescript-mcp-server-generator/" - ] + "extensions": { + "com.github.awesome-copilot": { + "agents": [ + "./agents/typescript-mcp-expert.md" + ], + "skills": [ + "./skills/typescript-mcp-server-generator/" + ] + } + } } diff --git a/plugins/typespec-m365-copilot/plugin.json b/plugins/typespec-m365-copilot/plugin.json index 6bd023e955..f1200b086e 100644 --- a/plugins/typespec-m365-copilot/plugin.json +++ b/plugins/typespec-m365-copilot/plugin.json @@ -16,9 +16,13 @@ "agent-development", "microsoft-365" ], - "skills": [ - "./skills/typespec-api-operations/", - "./skills/typespec-create-agent/", - "./skills/typespec-create-api-plugin/" - ] + "extensions": { + "com.github.awesome-copilot": { + "skills": [ + "./skills/typespec-api-operations/", + "./skills/typespec-create-agent/", + "./skills/typespec-create-api-plugin/" + ] + } + } } diff --git a/plugins/uizze/plugin.json b/plugins/uizze/plugin.json index b5d53cdf9d..fc30b55c86 100644 --- a/plugins/uizze/plugin.json +++ b/plugins/uizze/plugin.json @@ -19,7 +19,11 @@ "design-review", "quality-gate" ], - "skills": [ - "./skills/anti-ui-slop/" - ] + "extensions": { + "com.github.awesome-copilot": { + "skills": [ + "./skills/anti-ui-slop/" + ] + } + } } diff --git a/plugins/visual-pr/plugin.json b/plugins/visual-pr/plugin.json index 2d4f508533..32b1c8a27f 100644 --- a/plugins/visual-pr/plugin.json +++ b/plugins/visual-pr/plugin.json @@ -18,10 +18,14 @@ }, "repository": "https://github.com/github/awesome-copilot", "license": "MIT", - "skills": [ - "./skills/image-annotations/", - "./skills/pr-screenshots/", - "./skills/screen-recording/", - "./skills/ui-screenshots/" - ] + "extensions": { + "com.github.awesome-copilot": { + "skills": [ + "./skills/image-annotations/", + "./skills/pr-screenshots/", + "./skills/screen-recording/", + "./skills/ui-screenshots/" + ] + } + } } diff --git a/plugins/where-was-i/plugin.json b/plugins/where-was-i/plugin.json index d501f2b105..9685392cc9 100644 --- a/plugins/where-was-i/plugin.json +++ b/plugins/where-was-i/plugin.json @@ -17,8 +17,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png", - "directories": [ + "logo": "assets/preview.png" + }, + "com.github.awesome-copilot": { + "extensions": [ "./extensions/where-was-i" ] } diff --git a/plugins/work-hub/plugin.json b/plugins/work-hub/plugin.json index cff115fbf0..5667cda9b5 100644 --- a/plugins/work-hub/plugin.json +++ b/plugins/work-hub/plugin.json @@ -17,8 +17,10 @@ ], "extensions": { "com.github.copilot": { - "logo": "assets/preview.png", - "directories": [ + "logo": "assets/preview.png" + }, + "com.github.awesome-copilot": { + "extensions": [ "./extensions/work-hub" ] }