Migrate extension metadata to plugin.json and enforce conventions#2177
Merged
Conversation
The pluginRoots property is not used by install tooling and was only informational about the extension/plugin source directories. Removing it simplifies the marketplace.json structure while maintaining all functionality. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…-install-strategy
…n workflow - Create .github/plugin/plugin.json for java-modernization-studio extension - Remove legacy canvas.json from java-modernization-studio - Update validate-canvas-extensions.yml workflow to check for plugin.json instead of canvas.json - Update workflow to trigger on .schemas/plugin.schema.json changes (instead of canvas.schema.json) - Remove schema validation logic that relied on canvas.schema.json - All 12 extensions now use plugin.json for metadata Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Per github/copilot-agent-runtime#9929, plugins that ship extensions need to include an extensions field specifying where the extension code is located. All 12 extensions now have extensions set to '.' to reference the current directory where extension.mjs is located. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
- Remove x-awesome-copilot.screenshots from all extension plugin.json files - Enforce logo=assets/preview.png convention for all extensions - Enforce extensions=. per copilot-agent-runtime#9929 - Update validate-plugins.mjs to enforce conventions - Update validate-canvas-extensions.yml workflow with convention checks - Update AGENTS.md and CONTRIBUTING.md documentation All 12 extensions validated successfully. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This pull request migrates canvas extension metadata to plugin manifests and updates the validation + website/marketplace pipelines so extensions are installed via copilot plugin install ...@awesome-copilot rather than URL-based installs.
Changes:
- Updates website extension UI to copy a plugin install command by default (with URL copy as fallback).
- Standardizes extension plugin manifests (e.g.,
logo: assets/preview.png,extensions: ".") and publishes extension manifests into.github/plugin/marketplace.json. - Extends build/validation scripts to treat extensions as plugin sources, enforce new extension conventions, and materialize curated plugin extension references.
Show a summary per file
| File | Description |
|---|---|
| website/src/scripts/pages/extensions.ts | Updates extension details modal + click handlers to copy install command and/or install URL. |
| website/src/scripts/pages/extensions-render.ts | Renders “Copy Install” and “Copy URL” buttons with data-install-command support. |
| website/src/pages/extensions.astro | Updates install instructions to prefer plugin install commands. |
| extensions/where-was-i/.github/plugin/plugin.json | Migrates extension metadata to plugin conventions (logo, extensions, slugged name). |
| extensions/site-studio/.github/plugin/plugin.json | Migrates extension metadata to plugin conventions (logo, extensions, slugged name). |
| extensions/release-notes-showcase/.github/plugin/plugin.json | Migrates extension metadata to plugin conventions (logo, extensions, slugged name). |
| extensions/java-modernization-studio/.github/plugin/plugin.json | Migrates extension metadata to plugin conventions (logo, extensions, slugged name). |
| extensions/gesture-review/.github/plugin/plugin.json | Migrates extension metadata to plugin conventions (logo, extensions, slugged name). |
| extensions/feedback-themes/.github/plugin/plugin.json | Migrates extension metadata to plugin conventions (logo, extensions, slugged name). |
| extensions/diagram-viewer/.github/plugin/plugin.json | Migrates extension metadata to plugin conventions (logo, extensions, slugged name). |
| extensions/color-orb/.github/plugin/plugin.json | Migrates extension metadata to plugin conventions (logo, extensions, slugged name). |
| extensions/chromium-control-canvas/.github/plugin/plugin.json | Migrates extension metadata to plugin conventions (logo, extensions, slugged name). |
| extensions/backlog-swipe-triage/.github/plugin/plugin.json | Migrates extension metadata to plugin conventions (logo, extensions, slugged name). |
| extensions/arcade-canvas/.github/plugin/plugin.json | Migrates extension metadata to plugin conventions (logo, extensions, slugged name). |
| extensions/accessibility-kanban/.github/plugin/plugin.json | Migrates extension metadata to plugin conventions (logo, extensions, slugged name). |
| eng/validate-plugins.mjs | Adds extension manifest validation and curated plugin extension reference validation. |
| eng/materialize-plugins.mjs | Adds support for copying extension sources into materialized plugins via x-awesome-copilot.extensions. |
| eng/generate-website-data.mjs | Generates extension install commands and reads extension metadata from .github/plugin/plugin.json. |
| eng/generate-marketplace.mjs | Generates marketplace entries from both plugins/ and extensions/ (as plugin sources). |
| CONTRIBUTING.md | Documents new extension metadata requirements and validation expectations. |
| AGENTS.md | Documents extension metadata conventions and contribution steps. |
| .github/workflows/validate-canvas-extensions.yml | Updates extension validation workflow to require .github/plugin/plugin.json and enforce new conventions. |
| .github/plugin/marketplace.json | Updates generated marketplace output to include extension plugin sources and updated local plugin source paths. |
Review details
Comments suppressed due to low confidence (1)
eng/validate-plugins.mjs:209
validatePluginnow sometimes returns an array (early return when plugin.json is missing), but callers always destructure an object (const { errors, plugin } = validatePlugin(dir)). This will makeerrorsundefined and then throw when accessingerrors.length, breaking validation instead of reporting a clean error list.
// Rule 1: Must have .github/plugin/plugin.json
const pluginJsonPath = path.join(pluginDir, ".github/plugin", "plugin.json");
if (!fs.existsSync(pluginJsonPath)) {
errors.push("missing required file: .github/plugin/plugin.json");
return errors;
}
- Files reviewed: 23/23 changed files
- Comments generated: 1
- Review effort level: Low
…-install-strategy
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Review details
Comments suppressed due to low confidence (1)
eng/validate-plugins.mjs:209
validatePlugin()sometimes returns an array (when plugin.json is missing) but callers now destructure it as an object (const { errors, plugin } = validatePlugin(dir)). That makeserrorsundefined and will crash when accessingerrors.length, breakingnpm run plugin:validateand CI validation.
// Rule 1: Must have .github/plugin/plugin.json
const pluginJsonPath = path.join(pluginDir, ".github/plugin", "plugin.json");
if (!fs.existsSync(pluginJsonPath)) {
errors.push("missing required file: .github/plugin/plugin.json");
return errors;
}
- Files reviewed: 23/23 changed files
- Comments generated: 1
- Review effort level: Low
Comment on lines
36
to
41
| # Note: We're still using canvas.schema.json for now to validate the structure, | ||
| # but in future we may migrate to using plugin.schema.json. | ||
| # For now, plugin.json will be validated against plugin specs separately. | ||
| if ! node ./eng/validate-json-schema.mjs --schema .schemas/plugin.schema.json 2>/dev/null || ! [ -f .schemas/plugin.schema.json ]; then | ||
| echo "Note: plugin.schema.json not yet in use for extension validation. Using plugin validation only." | ||
| fi |
…ell-extension-install-strategy
…-install-strategy # Conflicts: # .github/plugin/marketplace.json
Contributor
There was a problem hiding this comment.
Review details
Comments suppressed due to low confidence (1)
eng/validate-plugins.mjs:209
- validatePlugin now returns an array when plugin.json is missing, but validatePlugins destructures the result as
{ errors, plugin }. If a plugin folder is missing.github/plugin/plugin.json, this will throw at runtime (errors is undefined) and stop validation entirely. Return a consistent object shape here.
// Rule 1: Must have .github/plugin/plugin.json
const pluginJsonPath = path.join(pluginDir, ".github/plugin", "plugin.json");
if (!fs.existsSync(pluginJsonPath)) {
errors.push("missing required file: .github/plugin/plugin.json");
return errors;
}
- Files reviewed: 24/24 changed files
- Comments generated: 3
- Review effort level: Low
Remove the custom extension schema and schema validation helper, and validate extension plugin.json files through the existing plugin validator instead. Update workflows to stop depending on the removed schema. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pull Request Checklist
npm startand verified thatREADME.mdis up to date.mainbranch for this pull request.Description
This updates the extension install strategy to align with plugin-based extension shipping in copilot-agent-runtime and simplify extension authoring.
Key changes:
canvas.jsonto.github/plugin/plugin.jsonfor all extensions."extensions": ".") so extension loading matches github/copilot-agent-runtime#9929 behavior."logo": "assets/preview.png") and removesx-awesome-copilotscreenshot overrides.pluginRootsfrom.github/plugin/marketplace.json.eng/validate-plugins.mjsto enforce the new extension conventions.AGENTS.md,CONTRIBUTING.md) with the new extension metadata and validation requirements.Type of Contribution
Additional Notes
mainbefore finalizing.npm run plugin:validate).By submitting this pull request, I confirm that my contribution abides by the Code of Conduct and will be licensed under the MIT License.