fix(kyberforge): correct field classification and fill provenance gaps in plugin-author and marketplace-author

## Why

The manifest-fields tables in both skills used imprecise labels ("CC-only",
"Copilot-only") that conflated two distinct reasons a field appears in only
one manifest: platform constraint (the other tool does not support the field
at all) versus repo convention (both tools support it, but the scaffold places
it in one manifest by design). This caused agents to treat convention
boundaries as hard platform constraints, producing unnecessary errors when
updating manifests for dual-tool repos.

Provenance was also incomplete: sources.md files were missing entries for
sources that had been consulted and were already contributing to SKILL.md
and manifest-fields.md content, making the evidence chain unverifiable.

## Implementation Notes

Field classification now uses three explicit categories — shared, platform
(one tool does not support the field), and convention (both tools support it;
scaffold places it in one manifest by design). The distinction matters because
convention fields may legitimately appear in the other manifest when there is
a deliberate reason; platform fields may not.

New gotchas added to plugin-author: agent files silently ignore hooks,
mcpServers, and permissionMode frontmatter; claude plugin tag --push requires
a clean working tree; --dry-run preview before tagging; --strict flag on
validate. New gotchas in marketplace-author: metadata object as Copilot CLI
canonical location for top-level fields; strict: false for dual-tool plugins;
sha takes precedence over ref for pinning; --strict flag on validate.

tests/ removed from plugin-author because new-plugin.sh has no branching
logic warranting a bats suite at this stage.

## Impact

Skill prompt changes only — no runtime code affected. Agents using these
skills will now correctly distinguish convention from constraint when deciding
which manifest to update for a given field.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-28 11:09:13 +00:00
parent 4d061bd199
commit 3a91126d3f
9 changed files with 288 additions and 71 deletions

View File

@@ -37,4 +37,3 @@ bash scripts/new-plugin.sh data-tools .
| `references/sources.md` | Research provenance — sources that informed this skill |
| `scripts/README.md` | Directory meta-documentation for scripts/ |
| `references/README.md` | Directory meta-documentation for references/ |
| `tests/README.md` | Test dependency instructions and run command |

View File

@@ -6,14 +6,17 @@ description: >
description", "add keyword", "bump version"), or release a plugin version
("release", "tag", "publish"). Manages both Claude Code
(.claude-plugin/plugin.json) and Copilot CLI (plugin.json) manifests in one
pass. Explicitly out of scope: plugin content (skills, agents, hooks, MCP
servers) and marketplace.json entries — use /marketplace-author for those.
pass. Do not use when the request is about plugin content (skills, agents,
hooks, MCP servers) or marketplace.json entries — use /marketplace-author
for those.
allowed-tools: Bash Read Write Edit
metadata:
category: factory
source_keys:
- context7-websites-code-claude
- claude-code-plugins-docs
- claude-code-subagents-docs
- context7-github-en-copilot
- github-cli-plugin-reference
- github-plugins-creating
- github-plugins-finding-installing
@@ -22,12 +25,14 @@ metadata:
## Gotchas
- Both manifests must carry identical `version` values — version parity is a hard invariant (ADR-0016). Never update version in one manifest without updating the other in the same edit pass.
- `author.email` belongs in the Copilot manifest (`plugin.json`); `author.url` belongs in the CC manifest (`.claude-plugin/plugin.json`). Do not swap them.
- `author.email` is placed in the Copilot manifest by convention; `author.url` is placed in the CC manifest by convention. Both fields are supported by both platforms — do not add them to the other manifest without a deliberate reason.
- `claude plugin tag --push` is irreversible: it creates a git tag and pushes it to remote. Always present the HITL gate and wait for explicit confirmation before running it.
- `claude plugin tag --push` requires a clean working tree and will fail if there are uncommitted changes. Commit or stash all changes before running it.
- `name` in both manifests must be kebab-case and must not use reserved prefixes: `anthropic-*`, `claude-*`, `agent-skills`, `official-claude-plugins`.
- Copilot manifest lookup order: `.plugin/plugin.json` → `plugin.json` → `.github/plugin/plugin.json` → `.claude-plugin/plugin.json`. The canonical location for the Copilot manifest in this repo is `plugin.json` at the plugin root.
- `displayName` is CC-only — do not add it to the Copilot manifest.
- `skills`, `agents`, `hooks`, `mcpServers` are Copilot-only fields — do not add them to the CC manifest.
- `displayName` is a CC platform field — Copilot has no equivalent. Do not add it to the Copilot manifest.
- `skills`, `agents`, `hooks`, `mcpServers` are declared in the Copilot manifest by convention — Copilot requires explicit path declarations while CC auto-discovers content from the plugin root. Both platforms support these fields; omit them from the CC manifest by convention.
- Agent files in a plugin's `agents/` directory silently ignore `hooks`, `mcpServers`, and `permissionMode` frontmatter fields.
## Route
@@ -38,7 +43,7 @@ Determine which flow before touching the filesystem. Read both manifest files if
- **Plugin directory exists + field change intent** ("update description", "add keyword", "change author") → follow **UPDATE flow**
- **Ambiguous** → ask: "Did you mean to create a new plugin, update its configuration, or release a version?"
Validate runs automatically before tagging (in RELEASE flow) and can be invoked explicitly at any time.
Validate runs automatically before tagging (in RELEASE flow) and can be invoked explicitly at any time: `claude plugin validate plugins/<name>`.
## CREATE flow
@@ -83,13 +88,13 @@ Open both manifest files and replace every `FILL_IN_*` placeholder.
- `license` — SPDX identifier (default: `MIT`)
- `keywords` — search/discovery tags (default: `[]`)
**CC-only fields** (`.claude-plugin/plugin.json` only):
- `displayName` — human-readable name shown in plugin manager; capitalised form of `name`
- `author.url` — author URL (e.g. Gitea profile URL)
**CC manifest fields** (`.claude-plugin/plugin.json` only):
- `displayName` — human-readable name shown in plugin manager; capitalised form of `name` (CC platform field — no Copilot equivalent)
- `author.url` — author URL (e.g. Gitea profile URL) (both platforms support this; placed here by convention)
**Copilot-only fields** (`plugin.json` only):
- `author.email` — author email
- `skills`, `agents`, `hooks`, `mcpServers` — paths; defaults are already set by the script
**Copilot manifest fields** (`plugin.json` only):
- `author.email` — author email (both platforms support this; placed here by convention)
- `skills`, `agents`, `hooks`, `mcpServers` — paths; defaults are already set by the script (CC auto-discovers these; Copilot requires explicit declarations)
### Step 3 — Validate
@@ -116,11 +121,15 @@ For every field the user wants to change:
| Change type | What to update |
|---|---|
| Shared field (`name`, `description`, `version`, `author.name`, `license`, `keywords`) | Both manifests in the same edit pass |
| CC-only (`displayName`, `author.url`) | `.claude-plugin/plugin.json` only |
| Copilot-only (`author.email`, `skills`, `agents`, `hooks`, `mcpServers`, `category`, `tags`, `extensions`) | `plugin.json` only |
| CC platform field (`displayName`) | `.claude-plugin/plugin.json` only — Copilot has no equivalent field |
| Copilot platform fields (`category`, `tags`, `extensions`) | `plugin.json` only — not in the CC manifest schema |
| CC scaffold convention (`author.url`) | `.claude-plugin/plugin.json` only — both platforms support this field; it is placed here by convention |
| Copilot scaffold convention (`author.email`, `skills`, `agents`, `hooks`, `mcpServers`) | `plugin.json` only by convention — CC also supports these fields; CC auto-discovers content from the plugin root rather than requiring explicit path declarations |
Never update a shared field in one manifest without updating the other in the same pass.
If the target field is not listed in the classification table, read `references/manifest-fields.md` for the full field list and platform support notes.
### Step 3 — Announce and apply
State which fields change and which files are affected. Then apply. For `version` changes not part of a release, bump both manifests in the same edit.
@@ -147,6 +156,8 @@ Run:
claude plugin validate plugins/<name>
```
Use `--strict` to promote warnings to errors: `claude plugin validate --strict plugins/<name>`.
Stop and report errors if validation fails. Do not proceed to tagging until validation passes.
### Step 4 — HITL gate
@@ -159,6 +170,8 @@ Do not call the tool until the user explicitly confirms in the conversation.
### Step 5 — Tag and release
To preview without tagging or pushing: `claude plugin tag --dry-run`.
After explicit confirmation, run from the repo root:
```bash

View File

@@ -3,6 +3,7 @@ topic: manifest-fields
source_keys:
- context7-websites-code-claude
- claude-code-plugins-docs
- context7-github-en-copilot
- github-cli-plugin-reference
- github-plugins-creating
- github-plugins-finding-installing
@@ -14,6 +15,10 @@ This document covers optional fields beyond the scaffolded defaults. Consult it
## Field Classification
Fields fall into three categories: **shared** (identical in both manifests), **platform** (one platform does not support the field at all), and **convention** (both platforms support the field, but the repo scaffold places it in one manifest only).
> CC auto-discovers content (skills, agents, hooks, MCP servers) from the plugin root; Copilot requires explicit path declarations. Convention fields in the CC manifest are omitted unless you have a deliberate reason to add them.
| Field | Copilot `plugin.json` | CC `.claude-plugin/plugin.json` | Notes |
|---|---|---|---|
| `name` | Yes (shared) | Yes (shared) | Identical in both; kebab-case; max 64 chars (Copilot) |
@@ -22,16 +27,16 @@ This document covers optional fields beyond the scaffolded defaults. Consult it
| `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 |
| `displayName` | No (unsupported) | Yes | CC platform field — Copilot has no equivalent |
| `author.url` | Omitted (convention) | Yes (convention) | Author profile URL; CC scaffold places here; Copilot also supports this field |
| `author.email` | Yes (convention) | Omitted (convention) | Author email; Copilot scaffold places here; CC also supports this field |
| `agents` | Yes (convention) | Omitted (convention) | Path or array; default: `agents/`; Copilot requires explicit declaration; CC auto-discovers |
| `skills` | Yes (convention) | Omitted (convention) | Path or array; default: `skills/`; Copilot requires explicit declaration; CC auto-discovers |
| `hooks` | Yes (convention) | Omitted (convention) | Path to hooks config; Copilot requires explicit declaration; CC auto-discovers |
| `mcpServers` | Yes (convention) | Omitted (convention) | Path or object; Copilot requires explicit declaration; CC auto-discovers |
| `category` | Yes | No (unsupported) | Marketplace category string; Copilot platform field — not in CC manifest schema |
| `tags` | Yes | No (unsupported) | Additional taxonomy tags (distinct from `keywords`); Copilot platform field |
| `extensions` | Yes | No (unsupported) | Path, array, or `{ paths, exclusive: true }` to disable built-ins; Copilot platform field |
| `homepage` | Both (independent) | Both (independent) | Documentation URL; not required to be identical |
| `repository` | Both (independent) | Both (independent) | Source repo URL |

View File

@@ -2,9 +2,21 @@
source_keys:
- context7-websites-code-claude
- claude-code-plugins-docs
- claude-code-subagents-docs
- context7-github-en-copilot
- github-cli-plugin-reference
- github-plugins-creating
- github-plugins-finding-installing
- github-custom-agents-configuration
- github-plugins-marketplace
- github-sdk-custom-agents
- github-changelog-copilot-extensions-ga
- github-changelog-copilot-extensions-sunset
- github-docs-copilot-extensions-skillsets
- github-docs-copilot-extensions-building
- vscode-chat-participant-api
- github-marketplace-copilot-extensions
- github-docs-marketplace-listing-requirements
---
# Sources
@@ -30,7 +42,7 @@ source_keys:
- **URL:** https://docs.github.com/en/copilot/reference/copilot-cli-reference/cli-plugin-reference
- **Research doc:** plugins/kyberforge/docs/research/docs/github-copilot-plugins/sources.md
- **Description:** Full Copilot CLI plugin reference — `plugin.json` schema (all fields, types, constraints), marketplace.json schema, CLI commands, manifest lookup order
- **Contributing files:** SKILL.md, scripts/new-plugin.sh, references/manifest-fields.md
- **Contributing files:** SKILL.md, references/manifest-fields.md
- **Status:** `extracted`
## github-plugins-creating
@@ -38,7 +50,7 @@ source_keys:
- **URL:** https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/plugins-creating
- **Research doc:** plugins/kyberforge/docs/research/docs/github-copilot-plugins/sources.md
- **Description:** How-to for creating Copilot CLI plugins — plugin structure, Copilot manifest fields, development lifecycle, hooks format, MCP config
- **Contributing files:** SKILL.md, scripts/new-plugin.sh
- **Contributing files:** SKILL.md
- **Status:** `extracted`
## github-plugins-finding-installing
@@ -48,3 +60,99 @@ source_keys:
- **Description:** Finding and installing Copilot CLI plugins — install spec formats, marketplace registration, `copilot plugin` CLI commands
- **Contributing files:** SKILL.md
- **Status:** `extracted`
## claude-code-subagents-docs
- **URL:** https://code.claude.com/docs/en/sub-agents
- **Research doc:** plugins/kyberforge/docs/research/docs/claude-code-plugins/sources.md
- **Description:** Official Claude Code subagent reference — definition format, all frontmatter fields, scope priority, built-in agents, CLI flags, environment variables, known limitations
- **Contributing files:** SKILL.md
- **Status:** `extracted`
## context7-github-en-copilot
- **URL:** context7:/websites/github_en_copilot
- **Research doc:** plugins/kyberforge/docs/research/docs/github-copilot-plugins/sources.md
- **Description:** Official GitHub Copilot documentation indexed by Context7; covers CLI plugins, custom agents, SDK, and marketplace
- **Contributing files:** SKILL.md, references/manifest-fields.md
- **Status:** `extracted`
## github-custom-agents-configuration
- **URL:** https://docs.github.com/en/copilot/reference/custom-agents-configuration
- **Research doc:** plugins/kyberforge/docs/research/docs/github-copilot-plugins/sources.md
- **Description:** Reference for cloud and IDE custom agent definition format — frontmatter fields, tool aliases, MCP server config, secrets interpolation, scoping hierarchy
- **Contributing files:** (none)
- **Status:** `extracted`
## github-plugins-marketplace
- **URL:** https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/plugins-marketplace
- **Research doc:** plugins/kyberforge/docs/research/docs/github-copilot-plugins/sources.md
- **Description:** How-to for creating and publishing a plugin marketplace — marketplace.json structure, hosting options, registration commands
- **Contributing files:** (none)
- **Status:** `extracted`
## github-sdk-custom-agents
- **URL:** https://docs.github.com/en/copilot/how-tos/copilot-sdk/features/custom-agents
- **Research doc:** plugins/kyberforge/docs/research/docs/github-copilot-plugins/sources.md
- **Description:** SDK custom agent API — CustomAgentConfig fields in all five languages, session config, sub-agent lifecycle events, tool scoping, permission handling
- **Contributing files:** (none)
- **Status:** `extracted`
## github-changelog-copilot-extensions-ga
- **URL:** https://github.blog/changelog/2025-02-19-announcing-the-general-availability-of-github-copilot-extensions/
- **Research doc:** plugins/kyberforge/docs/research/docs/github-copilot-plugins/sources.md
- **Description:** Announcement of GitHub Copilot Extensions general availability (February 2025) — OIDC auth, all license tiers, VS Code/Visual Studio/JetBrains/GitHub.com support
- **Contributing files:** (none)
- **Status:** `referenced`
## github-changelog-copilot-extensions-sunset
- **URL:** https://github.blog/changelog/2025-09-24-deprecate-github-copilot-extensions-github-apps/
- **Research doc:** plugins/kyberforge/docs/research/docs/github-copilot-plugins/sources.md
- **Description:** Sunset notice for GitHub App-based Copilot Extensions — creation blocked Sep 24, 2025; full shutdown Nov 10, 2025; MCP servers recommended as replacement
- **Contributing files:** (none)
- **Status:** `referenced`
## github-docs-copilot-extensions-skillsets
- **URL:** https://docs.github.com/en/copilot/concepts/build-copilot-extensions/skillsets-for-copilot-extensions
- **Research doc:** plugins/kyberforge/docs/research/docs/github-copilot-plugins/sources.md
- **Description:** Concept doc for Copilot Extension skillsets — up to 5 skills per extension, Copilot handles routing/prompt crafting/response, contrast with agent extensions
- **Contributing files:** (none)
- **Status:** `referenced`
## github-docs-copilot-extensions-building
- **URL:** https://docs.github.com/en/copilot/building-copilot-extensions/setting-up-copilot-extensions
- **Research doc:** plugins/kyberforge/docs/research/docs/github-copilot-plugins/sources.md
- **Description:** How-to for setting up a Copilot Extension — GitHub App registration, Copilot Chat permission, Copilot Editor Context permission, backend URL configuration
- **Contributing files:** (none)
- **Status:** `referenced`
## vscode-chat-participant-api
- **URL:** https://code.visualstudio.com/api/extension-guides/ai/chat
- **Research doc:** plugins/kyberforge/docs/research/docs/github-copilot-plugins/sources.md
- **Description:** VS Code Chat Participant API — createChatParticipant(), package.json contributes.chatParticipants, Language Model API, @mention invocation in Copilot Chat
- **Contributing files:** (none)
- **Status:** `referenced`
## github-marketplace-copilot-extensions
- **URL:** https://github.com/marketplace?type=apps&copilot_app=true
- **Research doc:** plugins/kyberforge/docs/research/docs/github-copilot-plugins/sources.md
- **Description:** GitHub Marketplace listing for Copilot Extensions — browsable list of available extensions (historical; page remains live but product is sunset)
- **Contributing files:** (none)
- **Status:** `referenced`
## github-docs-marketplace-listing-requirements
- **URL:** https://docs.github.com/en/apps/github-marketplace/creating-apps-for-github-marketplace/requirements-for-listing-an-app
- **Research doc:** plugins/kyberforge/docs/research/docs/github-copilot-plugins/sources.md
- **Description:** Requirements for listing a GitHub App on the GitHub Marketplace — verified publisher, capability description, UX stability, submission and review process
- **Contributing files:** (none)
- **Status:** `referenced`

View File

@@ -1,4 +1,5 @@
#!/usr/bin/env bash
# source_keys: github-cli-plugin-reference github-plugins-creating
set -euo pipefail
usage() {

View File

@@ -1,33 +0,0 @@
# tests/
Test files for scripts bundled with this skill.
## When to add tests
Add tests here when the skill has scripts in `scripts/` that are complex enough
to break silently — validators, parsers, generators, anything with branching
logic or edge cases. Test infrastructure (`.bats`, `*_test.*`, `test_*.sh`)
belongs here, not in `scripts/`.
## Dependencies
Tests require [bats-support](https://github.com/bats-core/bats-support) and
[bats-assert](https://github.com/bats-core/bats-assert). The test files load
helpers from the repo root's `tests/test_helper/`.
From the repo root:
```bash
git clone https://github.com/bats-core/bats-support tests/test_helper/bats-support
git clone https://github.com/bats-core/bats-assert tests/test_helper/bats-assert
```
Run all tests for this skill (from the repo root):
```bash
bats plugins/kyberforge/skills/plugin-author/tests/
```
## If no tests are needed
Delete this README and the `tests/` directory entirely.