* Harden external plugin validation: semver, SPDX, email, unknown fields
Extend the canonical external-plugin validator with Open-Plugins-aligned
rules, reusing the shared validation functions rather than duplicating checks:
- version: enforce Semantic Versioning (allows prerelease/build metadata)
- license: validate SPDX identifiers/expressions; warn (not error) on
well-formed-but-unrecognized ids so existing entries like SSAL-1.0 pass
- author.email: validate format when present
- unknown-field detection: warn on typo'd top-level/author/source keys
- immutable locator: marketplace warns when source lacks ref/sha;
publicSubmission keeps the existing hard error
Add eng/external-plugin-validation.test.mjs (node:test) covering each rule
plus a regression that committed external.json passes marketplace policy
with zero errors. Update CONTRIBUTING.md accordingly.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: eaa5eed6-5b65-4b28-9904-24f380d26728
* Make license non-SPDX a warning and share license check with local plugins
The agent-plugins-spec schema does not enforce SPDX, and plugins may use
proprietary/non-OSS licenses. Relax license validation so any non-empty
license string that isn't a recognized SPDX identifier/expression produces a
warning rather than an error.
Extract the license check into a reusable validateLicenseField() and apply it
to both external plugins and local plugin.json manifests via
eng/validate-plugins.mjs, so licenses are validated consistently in one place.
Update tests and CONTRIBUTING.md accordingly.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: eaa5eed6-5b65-4b28-9904-24f380d26728
* Extract shared license validation into eng/lib/license.mjs
Move the SPDX constants and license validation (validateLicenseField,
isRecognizedSpdxExpression) out of external-plugin-validation.mjs into a
dedicated eng/lib/license.mjs module. Both the external plugin catalog
validator and the local plugin.json validator now import license logic
from this neutral shared module instead of one validator importing from
the other. Behavior is unchanged; tests import from the new home.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: eaa5eed6-5b65-4b28-9904-24f380d26728
* Fix SPDX license parsing correctness and warning-message injection
Rewrite isRecognizedSpdxExpression as a recursive-descent SPDX license
expression parser to address PR review feedback:
- Validate LicenseRef-/DocumentRef- grammar (non-empty idstring; DocumentRef
requires the ":LicenseRef-<id>" suffix) instead of accepting any token with
that prefix.
- Parse parentheses with balance and placement checks rather than stripping
them, so malformed groupings like "(MIT", "MIT)", and "MIT OR (Apache-2.0))"
are no longer silently treated as valid.
- Treat WITH as a distinct operator whose right operand must be a known SPDX
license exception, so "MIT WITH Apache-2.0" and "GPL-2.0-only WITH MIT" are
rejected while "GPL-2.0-only WITH Classpath-exception-2.0" is recognized.
- Sanitize the untrusted license value in the non-SPDX warning (collapse
whitespace, truncate, escape backticks, wrap as inline code) since the
warning is rendered verbatim into a Markdown bot comment during intake.
Malformed SPDX stays a warning (never an error) so proprietary and non-OSS
license strings remain allowed. Adds targeted grammar and sanitization tests.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: eaa5eed6-5b65-4b28-9904-24f380d26728
* Complete backslash escaping and run source unknown-field check for all sources
Address two PR review findings:
- eng/lib/license.mjs: sanitizeForMessage now escapes backslashes before
backticks so the inline-code warning value is fully escaped, resolving a
CodeQL "incomplete string escaping" alert. A raw backslash in a license
value is now doubled rather than left to combine with a following escaped
backtick.
- eng/external-plugin-validation.mjs: move the source unknown-field check out
of validateGitHubSource into the outer source-object branch so it runs for
every object source and then dispatch by source.source. A typo in the source
discriminator (e.g. "soruce") or an unsupported source type now still
surfaces the unknown-field warning instead of being silently skipped.
Adds regression tests for both behaviors.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: eaa5eed6-5b65-4b28-9904-24f380d26728
* Harden Markdown safety of validation warnings via inlineCode helper
External-plugin validation warnings are rendered verbatim as Markdown
list items in the intake bot comment, so untrusted values interpolated
into them are an injection vector.
Add eng/lib/markdown.mjs exporting inlineCode(), which wraps a value in
a code span fenced with more backticks than any run in the content (and
pads leading/trailing backticks). This cannot be broken out of, unlike
the previous backslash escaping, which does not work inside code spans.
- lib/license.mjs: replace sanitizeForMessage with inlineCode for the
non-SPDX license warning.
- external-plugin-validation.mjs: wrap unknown-field keys (attacker
controlled JSON object keys) with inlineCode so newlines/Markdown in a
key can no longer inject a new list item.
- Add inlineCode unit tests and injection-neutralization tests for both
the license value and unknown-field key paths.
Addresses PR review comments 3679379606 and 3679434134.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: eaa5eed6-5b65-4b28-9904-24f380d26728
* Fixing codespell
---------
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: eaa5eed6-5b65-4b28-9904-24f380d26728
* Remove pluginRoots property from marketplace.json
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>
* Migrate java-modernization-studio to plugin.json and update validation 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>
* Add extensions field to all extension plugin.json files
Per https://github.com/github/copilot-agent-runtime/pull/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>
* Enforce convention-based extension metadata and remove x-awesome-copilot
- 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>
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Use standard plugin validation for extensions
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>
---------
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Switch skill CI checks to vally lint
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Adding Vally to allowed words
* case sensitivity
* Migrate external plugin quality gates from skill-validator to vally lint
Replace the downloaded skill-validator binary with
px @microsoft/vally-cli lint
in the external plugin quality gates pipeline:
- Remove downloadSkillValidator() and SKILL_VALIDATOR_ARCHIVE_URL constant
- Replace uildSkillValidatorArgs() +
unSkillValidatorGate() with
uildVallyLintArgs() +
unVallyLintGate() that run
px vally-cli lint
per resolved skill directory (falling back to the full plugin root when no
specific skill paths can be resolved from plugin.json)
- Rename result keys skill_validator_status / skill_validator_output
to ally_lint_status / ally_lint_output throughout both
ng/external-plugin-quality-gates.mjs and ng/external-plugin-intake.mjs
- Update PR comment markdown to show 'vally lint' instead of 'skill-validator'
- Update CONTRIBUTING.md prose references accordingly
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Use @microsoft/vally library directly instead of vally-cli subprocess
Replace the npx-spawned vally-cli process with a direct call to the
@microsoft/vally core library in the external plugin quality gates scripts:
- Add @microsoft/vally as a devDependency in package.json
- Import runLint and LintConsoleReporter from @microsoft/vally
- Replace runVallyLintGate() process spawn with async API call:
- runLint({ rootPath }) returns structured LintResults
- LintConsoleReporter with a Writable capture stream collects
text output without printing to stdout
- Make runExternalPluginQualityGates() async (propagated to
runExternalPluginPrQualityGates() and both main entry points)
- Use Promise.all in runExternalPluginPrQualityGates() for parallel
plugin checks
- Fix remaining skill_validator_status reference in pr-quality-gates
summary string (now vally-lint=...) and YAML workflow table header
- Add 'npm install @microsoft/vally' step to both calling workflows
This removes a layer of indirection (Node -> npx -> CLI -> library)
and replaces it with a direct in-process library call, which is faster,
more reliable, and gives structured access to lint results.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fixing path on chrome devtools external pluginPath is to the folder in the repo where the plugin structure starts, not where the plugin.json file lives.
* Updating validation scripts and guidance to avoid this mistake again
* fix: correct link for adding agents in CONTRIBUTING.md
removing outdated prompts-link
* feat: add Terminal Helper agent for PowerShell and Bash command assistance
* fix: rename task to validate-plugins and update command details
as collections are outdated
https://github.com/github/awesome-copilot/pull/717
* update name format for terminal helper to lowercase
* update scope description for terminal context clarity
The marketplace currently only includes plugins that live as local
directories in plugins/. This makes it impossible to list plugins
hosted in external GitHub repos, npm packages, or other git URLs.
Add plugins/external.json as a hand-curated list of external plugin
entries following the Claude Code plugin marketplace spec. The
generate-marketplace script now reads this file and merges external
entries as-is into the generated marketplace.json, sorted by name.
Changes:
- Add plugins/external.json (empty array, ready for entries)
- Update eng/generate-marketplace.mjs to load, merge, and sort
external plugins; warn on duplicate names; log counts
- Document the external plugin workflow in CONTRIBUTING.md and
AGENTS.md
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The pcf-development plugin had no agents, skills, or commands
referenced - just an empty shell. Convert it to a proper skill
with comprehensive PCF development guidance.
Also resolve merge conflict in CONTRIBUTING.md.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Workflows are now standalone .md files in workflows/ — no subfolders
or README.md needed. Each file contains both the metadata frontmatter
(name, description, triggers, tags) and the agentic workflow definition
(on, permissions, safe-outputs) in a single file.
Updated all build scripts, CI workflows, docs, and review checklists.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add support for contributing Agentic Workflows — AI-powered repository
automations that run coding agents in GitHub Actions, defined in markdown
with natural language instructions (https://github.github.com/gh-aw).
Changes:
- Create workflows/ directory for community-contributed workflows
- Add workflow metadata parsing (yaml-parser.mjs)
- Add workflow README generation (update-readme.mjs, constants.mjs)
- Add workflow data to website generation (generate-website-data.mjs)
- Update README.md, CONTRIBUTING.md, and AGENTS.md with workflow docs,
contributing guidelines, and code review checklists
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Move plugin manifests from .github/plugin/ to .claude-plugin/
- Convert items[] to Claude Code spec fields (agents, commands, skills)
- Rename tags to keywords, drop display/featured/instructions from plugins
- Delete all symlinks and materialized files from plugin directories
- Add eng/materialize-plugins.mjs to copy source files into plugin dirs at publish time
- Add .github/workflows/publish.yml for staged->main publishing
- Update CI triggers to target staged branch
- Update validation, creation, marketplace, and README generation scripts
- Update CONTRIBUTING.md and AGENTS.md documentation
- Include all new content from main (polyglot-test-agent, gem-browser-tester,
fabric-lakehouse, fluentui-blazor, quasi-coder, transloadit-media-processing,
make-repo-contribution hardening, website logo/gradient changes)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace Collections with Plugins as first-class citizens in the repo.
With the Copilot CLI v0.409 release making plugins an on-by-default
marketplace, collections are redundant overhead.
## What changed
### Plugin Infrastructure
- Created eng/validate-plugins.mjs (replaces validate-collections.mjs)
- Created eng/create-plugin.mjs (replaces create-collection.mjs)
- Enhanced all 42 plugin.json files with tags, featured, display, and
items metadata from their corresponding collection.yml files
### Build & Website
- Updated eng/update-readme.mjs to generate plugin docs
- Updated eng/generate-website-data.mjs to emit plugins.json with full
items array for modal rendering
- Renamed website collections page to plugins (/plugins/)
- Fixed plugin modal to use <div> instead of <pre> for proper styling
- Updated README.md featured section from Collections to Plugins
### Documentation & CI
- Updated CONTRIBUTING.md, AGENTS.md, copilot-instructions.md, PR template
- Updated CI workflows to validate plugins instead of collections
- Replaced docs/README.collections.md with docs/README.plugins.md
### Cleanup
- Removed eng/validate-collections.mjs, eng/create-collection.mjs,
eng/collection-to-plugin.mjs
- Removed entire collections/ directory (41 .collection.yml + .md files)
- Removed parseCollectionYaml from yaml-parser.mjs
- Removed COLLECTIONS_DIR from constants.mjs
Closes#711
* Migrating chat modes to agents now that's been released to stable
* Fixing collections
* Fixing names of agents
* Formatting
* name too long
* Escaping C# agent name
* initial prototype of partners collection with featured collection support
* Starting to add the partners
* Preparing the repo for how the custom agents will work
* moving some files around
* Moving a bunch of stuff around to make the file easier to read
* improving the front matter parsing by using a real library
* Some verbage updates
* some more verbage
* Fixing spelling mistake
* tweaking badges
* Updating contributing guide to be correct
* updating casing to match product
* More agents
* Better handling link to mcp registry
* links to install mcp servers fixed up
* Updating collection tags
* writing the mcp registry url out properly
* Adding custom agents for C# and WinForms
Expert custom agents to improve your experience when working with C# and WinForms in Copilot
* Adding to agents readme
* Adding PagerDuty agent
* Fixing description for terraform agent
* Adding custom agents to the README usage
* Removing the button to make the links more obvious
* docs: relocate category READMEs to /docs and update generation + internal links
* Updating prompts for new path
* formatting
---------
Co-authored-by: Chris Patterson <chrispat@github.com>
* feat(chatmodes): Add HLBPA (documentation architect) chat modes
- HLBPA is a high-level, big-picture architect for systems documentation
- It can be used either in VSC as usual or dropped in coding agent for auto-updates
- Depends on user's prompting skills to get the best results
- Will default to a more generalist mode if not enough context is given
- Minor updates to README and CONTRIBUTING to fix formatting errors
Assisted-by: GitHub Copilot & Verdent AI
Signed-off-by: Ashley Childress <6563688+anchildress1@users.noreply.github.com>
* chore(chatmodes): Remove copy from md fence in HLBPA chat mode
- Copilot complains about the copy in the md fence
- Isn't likely to be used in this context anyway
Assisted-by: GitHub Copilot
Signed-off-by: Ashley Childress <6563688+anchildress1@users.noreply.github.com>
---------
Signed-off-by: Ashley Childress <6563688+anchildress1@users.noreply.github.com>
* Delete outdated development instructions for Next.js + Tailwind and Python; add comprehensive guidelines for PostgreSQL DBA, Angular, ASP.NET REST APIs, Azure Functions with TypeScript, Bicep, Blazor, CMake with vcpkg, C#, .NET MAUI, GenAIScript, Terraform for Azure, localization, and markdown standards.
* Update documentation and prompts for consistency and clarity
- Standardized description formatting in various markdown files to use single quotes.
- Added error handling utility in update-readme.js for safer file operations.
- Improved title extraction logic in update-readme.js to handle frontmatter more robustly.
- Updated chat modes section in README to reflect new emoji and sorted chat mode links.
- Cleaned up various instruction files for better readability and consistency.
- Ensured all markdown files end with a newline for better compatibility with version control.
* Remove standardize-frontmatter.js script
* Add usage instructions for creating and switching chat modes in README.md
* Update README.md generation script to enhance instructions and usage details for custom chat modes
* Update README.md and update-readme.js for improved instruction clarity and consistency
* Refactor README.md links and update readme script for improved clarity and consistency in instructions
* Update README.md and update-readme.js for improved instruction clarity and consistency
* Changing from a patch to regen approach for the readme
* Bit more cleanup for how to show things in the readme
* Adding missing description
* Another missing description
---------
Co-authored-by: Aaron Powell <me@aaron-powell.com>