## Why Plugin and marketplace management had no governed authoring path. Creating or updating a plugin required knowing the dual-manifest convention, version parity rules, and directory skeleton by memory — nothing enforced consistency or guided the process. `/plugin-author` closes that gap by owning the full plugin scaffold lifecycle: create, update, rename, and release. `/marketplace-author` handles the marketplace-facing side: register, deregister, and update plugin entries in `marketplace.json`. ADR-0016 codifies the version parity convention (identical `version` in both `plugin.json` and `.claude-plugin/plugin.json`) that `/plugin-author` now enforces. The two plugin.json files in this repo are backfilled to comply (keys also sorted to pass the pretty-format-json hook). CONTEXT.md gains glossary entries for "plugin scaffold" and "version parity" so future agents have shared vocabulary for these concepts. ## Implementation Notes `/plugin-author` ships a `scripts/new-plugin.sh` scaffold script that generates the directory skeleton and both manifests in one shot; the skill calls the script rather than generating files ad hoc so the scaffold is reviewable and repeatable. Version parity is an invariant, not a suggestion — the skill will fail loudly on create/update if the two versions would diverge. ADR: docs/adr/0016-plugin-version-parity.md
4.5 KiB
topic, source_keys
| topic | source_keys | |||||
|---|---|---|---|---|---|---|
| manifest-fields |
|
Manifest Fields Reference
This document covers optional fields beyond the scaffolded defaults. Consult it when a user asks to add a non-default field to either manifest.
Field Classification
| Field | Copilot plugin.json |
CC .claude-plugin/plugin.json |
Notes |
|---|---|---|---|
name |
Yes (shared) | Yes (shared) | Identical in both; kebab-case; max 64 chars (Copilot) |
description |
Yes (shared) | Yes (shared) | Identical in both; max 1024 chars (Copilot) |
version |
Yes (shared) | Yes (shared) | Identical in both; SemVer; version parity required (ADR-0016) |
author.name |
Yes (shared) | Yes (shared) | Identical in both |
license |
Yes (shared) | Yes (shared) | Identical in both; SPDX identifier |
keywords |
Yes (shared) | Yes (shared) | Identical in both; string array |
displayName |
No | Yes (CC-only) | Human-readable name shown in plugin manager |
author.url |
No | Yes (CC-only) | Author profile or homepage URL |
author.email |
Yes (Copilot-only) | No | Author contact email |
agents |
Yes (Copilot-only) | No | Path or array; default: agents/ |
skills |
Yes (Copilot-only) | No | Path or array; default: skills/ |
hooks |
Yes (Copilot-only) | No | Path to hooks config |
mcpServers |
Yes (Copilot-only) | No | Path or object for MCP server config |
category |
Yes (Copilot-only) | No | Marketplace category string |
tags |
Yes (Copilot-only) | No | Additional taxonomy tags (distinct from keywords) |
extensions |
Yes (Copilot-only) | No | Path, array, or { paths, exclusive: true } to disable built-ins |
homepage |
Both (independent) | Both (independent) | Documentation URL; not required to be identical |
repository |
Both (independent) | Both (independent) | Source repo URL |
Non-Default Optional Fields
homepage
Documentation or project page URL. Shown in the plugin manager. Independent in each manifest — the two values do not need to match.
// Copilot plugin.json
{ "homepage": "https://example.com/docs" }
// CC .claude-plugin/plugin.json
{ "homepage": "https://example.com/docs" }
repository
Source repository URL. Independent in each manifest.
{ "repository": "https://git.example.com/owner/repo" }
category (Copilot-only)
Marketplace browsing category. Single string. Copilot manifest only.
{ "category": "developer-tools" }
tags (Copilot-only)
Additional taxonomy tags for Copilot marketplace browsing. Distinct from keywords.
{ "tags": ["testing", "ci"] }
extensions (Copilot-only)
Path to extension files, an array of paths, or an object. Use { "paths": [...], "exclusive": true } to disable built-in extensions.
{ "extensions": "extensions/" }
// or
{ "extensions": { "paths": ["extensions/"], "exclusive": true } }
lspServers
Language Server Protocol configuration. Supported in both Copilot and CC manifests.
{ "lspServers": ".lsp.json" }
outputStyles (CC-only)
Path to output styles directory. Claude Code manifest only.
{ "outputStyles": "styles/" }
experimental.themes (CC-only)
Path to themes directory. Claude Code manifest only. Experimental — may change.
{ "experimental": { "themes": "themes/" } }
experimental.monitors (CC-only)
Path to monitors.json. Claude Code manifest only. Experimental.
{ "experimental": { "monitors": "monitors.json" } }
dependencies (CC-only)
Plugin dependencies. Each entry is a string (plugin name) or { "name": "<name>", "version": "<semver>" }.
{
"dependencies": [
"base-tools",
{ "name": "data-tools", "version": "^2.0.0" }
]
}
commands (legacy, both)
Explicit list of .md command file paths. Deprecated in favour of skills/. Use skills instead for new plugins.
Version Parity Convention (ADR-0016)
The version field must be present and identical in both manifests at all times. This is a hard invariant enforced by /plugin-author on every create, update, and release operation.
- If only the CC manifest had
versionbefore this convention was introduced, backfill the Copilot manifest immediately. - Never change
versionin one manifest without changing it in the other in the same edit pass. - The RELEASE flow bumps both manifests simultaneously before tagging.