GitHub Copilot plugin authoring
Build self-contained, installable plugin packages from canonical primitives and prove both static contracts and runtime discovery.
When to invoke
- "Create a plugin from these existing agents and skills."
- "Migrate this plugin to Agent Plugins 1.0."
- "Why does this installed plugin not expose its agents?"
- "Audit every plugin in the marketplace."
- "Add hooks, MCP, or a client extension to a plugin."
Source and layout decisions
Choose component ownership before editing:
| Mode |
Canonical source |
Runtime package |
library |
harness/github-copilot/agents/ and harness/github-copilot/skills/ |
Agents and skills are generated directly under the plugin's agents/ and skills/. |
plugin |
The plugin's own agents/, skills/, hooks/, or extensions/ |
Canonical content stays directly in those plugin-root directories. |
| Mixed plugin-owned |
Plugin-local components plus selected shared skills |
Keep componentSource: plugin and sharedSkills in manifests/plugin-sources.json, then generate those package copies from the shared harness source. |
Canonical ownership and source references live in
harness/github-copilot/manifests/plugin-sources.json, not in the distributed plugin.json. A
plugin-owned package may declare sharedSkills there to avoid maintaining a second canonical copy.
Do not hand-edit generated shared-source copies.
GitHub Copilot plugins use:
- flat root
plugin.json without the Agent Plugins $schema;
- direct
agents/, skills/, hooks/, and extensions/ paths;
- root
mcp.json, declared through mcpServers, with portable transports;
- no
com.github.copilot/ directory.
Instructions and VS Code prompts are repository workspace customizations, not portable core plugin components. Package a safe publisher skill when they must accompany a plugin.
Procedure
- Inspect the intended capability, existing canonical primitives, same-domain plugins, marketplace entry, and ownership mode.
- Verify current first-party GitHub plugin, marketplace, hook, and Agent Plugins documentation when the user asks for current behavior, the CLI version changed, or local evidence conflicts.
- Start from
docs/templates/plugin.template.json and optionally docs/templates/plugin-mcp.template.json.
- Use a valid plugin name that matches
harness/github-copilot/plugins/<name>/.
- Reference only coherent agents, skills, hooks, MCP servers, or extensions. Reject componentless manifests and arbitrary “bundle everything” packages.
- Search for same-name or high-similarity canonical primitives before adding plugin-local content. Reuse a shared skill through
sharedSkills when the plugin needs a self-contained copy.
- For shared sources, run
python3 harness/github-copilot/scripts/normalize_plugin_manifests.py and python3 harness/github-copilot/scripts/sync_plugin_components.py.
- Add or update the alphabetized
.github/plugin/marketplace.json entry with source, exact manifest description, and exact version.
- Validate schemas, components, ownership, marketplace coverage, generated drift, capability policy, and redundancy classifications.
- Install the plugin in an isolated
COPILOT_HOME, list its skills and MCP servers, invoke a representative namespaced agent, and exercise hooks or extensions when their runtime surface is available.
- Record dated current-platform evidence in
docs/HARNESS-VALIDATION.md and regenerate docs/PLUGIN-AUDIT.md, docs/PRIMITIVE-CONTENT-AUDIT.md, docs/PRIMITIVE-CAPABILITIES.md, docs/PRIMITIVE-REDUNDANCY.md, and docs/catalog/github-copilot.md.
Required checks
python3 harness/github-copilot/scripts/validate_primitives.py --strict
python3 harness/github-copilot/scripts/normalize_plugin_manifests.py --check
python3 harness/github-copilot/scripts/audit_plugins.py --check
python3 harness/github-copilot/scripts/audit_primitive_content.py --check
python3 harness/github-copilot/scripts/audit_primitive_capabilities.py --check
python3 harness/github-copilot/scripts/audit_primitive_redundancy.py --check
python3 harness/github-copilot/scripts/generate_catalog.py --check
python3 harness/github-copilot/scripts/sync_plugin_components.py --check
python3 harness/github-copilot/scripts/sync_installed_primitives.py --check
Also validate every new skill with the skill-creator validator, lint changed workflows with actionlint, compile or syntax-check bundled scripts, and run available package tests.
Runtime acceptance
Static validation is not enough. A representative install must prove the applicable surfaces:
| Surface |
Evidence |
| Plugin |
copilot plugin list shows the expected version. |
| Marketplace |
copilot plugin marketplace browse <name> lists the package. |
| Agent |
copilot --agent <plugin>:<agent> resolves and runs. |
| Skill |
copilot skill list --json reports source: plugin. |
| MCP |
copilot mcp list shows each configured server. |
| Hook |
A safe simulated payload or tool call produces the expected decision. |
| Client extension |
Package install, mirror checks, dependency pinning, syntax, tests, and an interactive client test when available. |
Reinstall into a fresh isolated home after package changes because GitHub Copilot CLI caches installed content.
Safety and quality
- Pin executable dependencies, actions, container images, and MCP packages to reviewed versions or digests.
- Embed no token, secret, tenant value, or private endpoint.
- Keep extension imports tied to an exact upstream commit and preserve source and license metadata.
- Do not claim a client extension works in non-interactive CLI merely because installation succeeds.
- Do not translate Agent Plugins MCP configuration to workspace MCP by copying it verbatim; map transports and validate the result.
- Do not refresh evidence dates without repeating the check.
Troubleshooting
| Symptom |
Likely cause |
Resolution |
| Skills load but agents do not |
Manifest omits or mispoints the direct agent directory |
Declare agents: "agents/" and verify the files are directly present. |
| Manifest contains repository-only metadata |
Canonical ownership leaked into the distributed package |
Move it to manifests/plugin-sources.json and normalize. |
| MCP server is absent |
Legacy .mcp.json, missing schema, or wrong transport vocabulary |
Use root mcp.json and the Agent Plugins MCP schema. |
| Hook does not fire |
Wrong direct path or non-executable script |
Point hooks to the plugin-root config and run direct plus live payload tests. |
| Marketplace install is stale |
Version or entry differs from manifest |
Synchronize description/version and reinstall in a fresh home. |
| Audit reports drift |
Canonical source changed without regeneration |
Run the declared normalizer, importer, synchronizer, or catalog generator. |
| Same skill exists in shared and plugin sources |
Plugin copied and then edited a shared capability |
Keep one shared canonical package, declare it in sharedSkills, and regenerate the plugin copy. |
Limits
- Use the
copilot-primitive-architect agent when package boundaries or component ownership are ambiguous.
- Use
skill-creator for any skill created or repaired as part of the package.
- Do not import third-party code without verified provenance, license metadata, exact upstream commit, and applicable tests.
Output template
## Plugin authoring result
**Plugin:** <name>
**Version:** <version>
**Ownership:** <library|plugin>
**Status:** <created|migrated|repaired|blocked>
### Components
- Agents: <count>
- Skills: <count>
- Hooks: <count>
- MCP servers: <count>
- Client extensions: <count>
### Validation
- Schemas: <result>
- Repository gates: <result>
- Isolated install: <result>
- Runtime surfaces: <result>
- Unavailable tests: <reason or none>
Quality gate
1---2name: copilot-plugin-authoring-33description: Create, migrate, audit, and validate flat GitHub Copilot plugins and marketplaces with direct agents, skills, hooks, extensions, MCP configuration, canonical source ownership, and isolated runtime tests. Use when adding a plugin, repairing a manifest, packaging existing primitives, or refreshing marketplace governance.4---56<!-- Generated from harness/github-copilot/plugins/copilot-plugin-development/skills/copilot-plugin-authoring/SKILL.md by harness/claude-code/scripts/convert_from_copilot.py. Edit the source, not this file. -->78# GitHub Copilot plugin authoring910Build self-contained, installable plugin packages from canonical primitives and prove both static contracts and runtime discovery.1112## When to invoke1314- "Create a plugin from these existing agents and skills."15- "Migrate this plugin to Agent Plugins 1.0."16- "Why does this installed plugin not expose its agents?"17- "Audit every plugin in the marketplace."18- "Add hooks, MCP, or a client extension to a plugin."1920## Source and layout decisions2122Choose component ownership before editing:2324| Mode | Canonical source | Runtime package |25| --- | --- | --- |26| `library` | `harness/github-copilot/agents/` and `harness/github-copilot/skills/` | Agents and skills are generated directly under the plugin's `agents/` and `skills/`. |27| `plugin` | The plugin's own `agents/`, `skills/`, `hooks/`, or `extensions/` | Canonical content stays directly in those plugin-root directories. |28| Mixed plugin-owned | Plugin-local components plus selected shared skills | Keep `componentSource: plugin` and `sharedSkills` in `manifests/plugin-sources.json`, then generate those package copies from the shared harness source. |2930Canonical ownership and source references live in31`harness/github-copilot/manifests/plugin-sources.json`, not in the distributed `plugin.json`. A32plugin-owned package may declare `sharedSkills` there to avoid maintaining a second canonical copy.33Do not hand-edit generated shared-source copies.3435GitHub Copilot plugins use:3637- flat root `plugin.json` without the Agent Plugins `$schema`;38- direct `agents/`, `skills/`, `hooks/`, and `extensions/` paths;39- root `mcp.json`, declared through `mcpServers`, with portable transports;40- no `com.github.copilot/` directory.4142Instructions and VS Code prompts are repository workspace customizations, not portable core plugin components. Package a safe publisher skill when they must accompany a plugin.4344## Procedure45461. Inspect the intended capability, existing canonical primitives, same-domain plugins, marketplace entry, and ownership mode.472. Verify current first-party GitHub plugin, marketplace, hook, and Agent Plugins documentation when the user asks for current behavior, the CLI version changed, or local evidence conflicts.483. Start from `docs/templates/plugin.template.json` and optionally `docs/templates/plugin-mcp.template.json`.494. Use a valid plugin name that matches `harness/github-copilot/plugins/<name>/`.505. Reference only coherent agents, skills, hooks, MCP servers, or extensions. Reject componentless manifests and arbitrary “bundle everything” packages.516. Search for same-name or high-similarity canonical primitives before adding plugin-local content. Reuse a shared skill through `sharedSkills` when the plugin needs a self-contained copy.527. For shared sources, run `python3 harness/github-copilot/scripts/normalize_plugin_manifests.py` and `python3 harness/github-copilot/scripts/sync_plugin_components.py`.538. Add or update the alphabetized `.github/plugin/marketplace.json` entry with source, exact manifest description, and exact version.549. Validate schemas, components, ownership, marketplace coverage, generated drift, capability policy, and redundancy classifications.5510. Install the plugin in an isolated `COPILOT_HOME`, list its skills and MCP servers, invoke a representative namespaced agent, and exercise hooks or extensions when their runtime surface is available.5611. Record dated current-platform evidence in `docs/HARNESS-VALIDATION.md` and regenerate `docs/PLUGIN-AUDIT.md`, `docs/PRIMITIVE-CONTENT-AUDIT.md`, `docs/PRIMITIVE-CAPABILITIES.md`, `docs/PRIMITIVE-REDUNDANCY.md`, and `docs/catalog/github-copilot.md`.5758## Required checks5960```bash61python3 harness/github-copilot/scripts/validate_primitives.py --strict62python3 harness/github-copilot/scripts/normalize_plugin_manifests.py --check63python3 harness/github-copilot/scripts/audit_plugins.py --check64python3 harness/github-copilot/scripts/audit_primitive_content.py --check65python3 harness/github-copilot/scripts/audit_primitive_capabilities.py --check66python3 harness/github-copilot/scripts/audit_primitive_redundancy.py --check67python3 harness/github-copilot/scripts/generate_catalog.py --check68python3 harness/github-copilot/scripts/sync_plugin_components.py --check69python3 harness/github-copilot/scripts/sync_installed_primitives.py --check70```7172Also validate every new skill with the `skill-creator` validator, lint changed workflows with `actionlint`, compile or syntax-check bundled scripts, and run available package tests.7374## Runtime acceptance7576Static validation is not enough. A representative install must prove the applicable surfaces:7778| Surface | Evidence |79| --- | --- |80| Plugin | `copilot plugin list` shows the expected version. |81| Marketplace | `copilot plugin marketplace browse <name>` lists the package. |82| Agent | `copilot --agent <plugin>:<agent>` resolves and runs. |83| Skill | `copilot skill list --json` reports `source: plugin`. |84| MCP | `copilot mcp list` shows each configured server. |85| Hook | A safe simulated payload or tool call produces the expected decision. |86| Client extension | Package install, mirror checks, dependency pinning, syntax, tests, and an interactive client test when available. |8788Reinstall into a fresh isolated home after package changes because GitHub Copilot CLI caches installed content.8990## Safety and quality9192- Pin executable dependencies, actions, container images, and MCP packages to reviewed versions or digests.93- Embed no token, secret, tenant value, or private endpoint.94- Keep extension imports tied to an exact upstream commit and preserve source and license metadata.95- Do not claim a client extension works in non-interactive CLI merely because installation succeeds.96- Do not translate Agent Plugins MCP configuration to workspace MCP by copying it verbatim; map transports and validate the result.97- Do not refresh evidence dates without repeating the check.9899## Troubleshooting100101| Symptom | Likely cause | Resolution |102| --- | --- | --- |103| Skills load but agents do not | Manifest omits or mispoints the direct agent directory | Declare `agents: "agents/"` and verify the files are directly present. |104| Manifest contains repository-only metadata | Canonical ownership leaked into the distributed package | Move it to `manifests/plugin-sources.json` and normalize. |105| MCP server is absent | Legacy `.mcp.json`, missing schema, or wrong transport vocabulary | Use root `mcp.json` and the Agent Plugins MCP schema. |106| Hook does not fire | Wrong direct path or non-executable script | Point `hooks` to the plugin-root config and run direct plus live payload tests. |107| Marketplace install is stale | Version or entry differs from manifest | Synchronize description/version and reinstall in a fresh home. |108| Audit reports drift | Canonical source changed without regeneration | Run the declared normalizer, importer, synchronizer, or catalog generator. |109| Same skill exists in shared and plugin sources | Plugin copied and then edited a shared capability | Keep one shared canonical package, declare it in `sharedSkills`, and regenerate the plugin copy. |110111## Limits112113- Use the `copilot-primitive-architect` agent when package boundaries or component ownership are ambiguous.114- Use `skill-creator` for any skill created or repaired as part of the package.115- Do not import third-party code without verified provenance, license metadata, exact upstream commit, and applicable tests.116117## Output template118119```markdown120## Plugin authoring result121122**Plugin:** <name>123**Version:** <version>124**Ownership:** <library|plugin>125**Status:** <created|migrated|repaired|blocked>126127### Components128- Agents: <count>129- Skills: <count>130- Hooks: <count>131- MCP servers: <count>132- Client extensions: <count>133134### Validation135- Schemas: <result>136- Repository gates: <result>137- Isolated install: <result>138- Runtime surfaces: <result>139- Unavailable tests: <reason or none>140```141142## Quality gate143144- [ ] Package purpose and component composition are coherent.145- [ ] Canonical ownership and generated mirrors are explicit.146- [ ] Manifest, MCP, hook, skill, and marketplace contracts pass.147- [ ] Dependencies and upstream sources are pinned.148- [ ] Isolated install proves every claimed runtime surface or reports an unavailable client test.149- [ ] Audit, catalog, synchronization, and repository gates pass.150- [ ] Current claims have dated first-party or runtime evidence.