feat: add plugin-create skill and plugin template

Adds the plugin-create skill (.agents/skills/plugin-create/) that scaffolds
a new plugin from templates/plugin/, substitutes PLUGIN_NAME/AUTHOR_* markers,
registers the plugin in marketplace.json, runs claude plugin validate ., and
hands off to /marketplace-architect. Includes evals and the generic template
with all components (agents, skills, hooks, MCP, bin, docs) with per-directory
READMEs explaining what goes where and which tool reads each directory.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-20 17:24:30 +00:00
parent b5bcf08acb
commit 7fd8177742
16 changed files with 387 additions and 0 deletions

View File

@@ -0,0 +1,118 @@
skill_name: plugin-create
trigger_tests:
- id: explicit-create-named-plugin
name: "Explicit trigger — create named plugin"
query: "create a new plugin called security-tools"
should_trigger: true
- id: explicit-scaffold-plugin
name: "Explicit trigger — scaffold plugin"
query: "scaffold a plugin called developer-tools"
should_trigger: true
- id: implicit-add-marketplace-plugin
name: "Implicit trigger — add plugin to marketplace"
query: "add a new plugin to the marketplace for developer tools"
should_trigger: true
- id: implicit-package-skills-into-plugin
name: "Implicit trigger — package skills into a plugin"
query: "I want to package up my skills into a distributable plugin"
should_trigger: true
- id: negative-validate-marketplace
name: "Negative trigger — validate marketplace.json (routes to /marketplace-architect)"
query: "validate my marketplace.json"
should_trigger: false
- id: negative-write-skill
name: "Negative trigger — write a skill (routes to /write-skill)"
query: "write a skill for code review"
should_trigger: false
- id: negative-adopt-external-plugin
name: "Negative trigger — adopt external plugin (routes to /marketplace-architect)"
query: "adopt this external plugin into my marketplace"
should_trigger: false
output_tests:
- id: gate-a-shows-plan
name: "Gate A presents file list and marketplace entry before writing"
type: deterministic
prompt: >
Create a new plugin called marketplace-tools, description: 'Tools for managing the
holocron marketplace', author: Jane Doe, email: jane@example.com,
URL: https://github.com/jane
expected_output: >
The skill presents a plan listing all files that will be written under
plugins/marketplace-tools/, shows the new marketplace.json entry, and
explicitly asks for approval before writing any file.
assertions:
- "Output lists files to be written under plugins/marketplace-tools/"
- "Output includes a marketplace.json entry with name 'marketplace-tools'"
- "Output explicitly asks for approval and does not proceed without it"
- "Output does not contain any written file confirmation before approval is given"
- id: reserved-name-rejected
name: "Reserved plugin name is rejected before Gate A"
type: deterministic
prompt: "Create a new plugin called claude-tools"
expected_output: >
The skill halts before presenting Gate A, reports that 'claude-tools' matches
the reserved name pattern 'claude-*', and asks the user to provide a different name.
assertions:
- "Output does not present Gate A or a file list"
- "Output identifies 'claude-tools' as a reserved name"
- "Output asks the user to provide a replacement name before continuing"
- id: no-skill-stub-generated
name: "No skill stub generated — skills/ is empty with README only"
type: deterministic
prompt: >
Create a new plugin called marketplace-tools, description: 'Tools for managing the
holocron marketplace', author: Jane Doe, email: jane@example.com,
URL: https://github.com/jane. Approve Gate A and Gate B.
expected_output: >
The plugin scaffold does not include any SKILL.md file. The skills/ directory
is present with a README only. The skill directs the user to /write-skill
to add skill content.
assertions:
- "Output does not include creation of any SKILL.md file"
- "Output includes a skills/ directory entry with README.md only"
- "Output mentions /write-skill for adding skill content"
- id: handoff-message-present
name: "Hand-off message directs user to /marketplace-architect"
type: deterministic
prompt: >
Create a new plugin called marketplace-tools, description: 'Tools for managing the
holocron marketplace', author: Jane Doe, email: jane@example.com,
URL: https://github.com/jane. Approve Gate A and Gate B.
expected_output: >
After writing files and running validation, the skill prints a hand-off message
that names the created plugin and instructs the user to run /marketplace-architect.
assertions:
- "Output contains the string '/marketplace-architect'"
- "Output includes the plugin name 'marketplace-tools' in the hand-off message"
- "Output does not auto-invoke /marketplace-architect itself"
- id: full-flow-quality
name: "Full flow — correct sequencing, substitution, and hand-off"
type: llm-rubric
prompt: >
Create a new plugin called developer-tools with description 'Developer productivity
toolkit', author: Alex Smith, email: alex@example.com, URL: https://github.com/alex.
Approve Gate A and Gate B.
expected_output: >
The skill executes the full create-plugin flow: collects all five inputs one at a
time, presents Gate A with a file plan, copies and substitutes the template, presents
Gate B with full file contents, writes files after Gate B approval, updates
marketplace.json, runs validation, and prints a hand-off message.
assertions:
- "All five inputs (plugin name, description, author name, email, URL) were collected individually before Gate A was presented"
- "Gate A clearly listed all files to be written and the new marketplace.json entry, and waited for explicit approval"
- "Gate B showed the full substituted content of every file before writing"
- "None of the strings PLUGIN_NAME, PLUGIN_DESCRIPTION, AUTHOR_NAME, AUTHOR_EMAIL, or AUTHOR_URL appear in the written file output"
- "The validation step either ran claude plugin validate . and reported output, or explicitly stated it was unavailable"
- "The final message directed the user to run /marketplace-architect and included the plugin name 'developer-tools'"

View File

@@ -0,0 +1,13 @@
```yaml
version: "1.0"
updated: 2026-06-20
when: Invoked when the user wants to create a new plugin in the marketplace. Scaffolds the
directory structure from templates/plugin/, substitutes PLUGIN_NAME/PLUGIN_DESCRIPTION/
AUTHOR_NAME/AUTHOR_EMAIL/AUTHOR_URL placeholders, writes to plugins/<name>/, registers
the plugin in .claude-plugin/marketplace.json, runs claude plugin validate ., and hands
off to /marketplace-architect.
references:
- docs/research/plugin-marketplace-architecture.md
```

View File

@@ -0,0 +1,89 @@
---
name: plugin-create
description: >
Use when the user wants to create a new plugin in the marketplace — scaffold the directory
structure, generate plugin.json manifests for Claude Code and Copilot CLI, and register
the plugin in marketplace.json. Triggers: "create a new plugin", "add a plugin called X",
"scaffold a plugin", "new plugin for Y". Do NOT use when auditing or refactoring existing
plugins (use /marketplace-architect), authoring skill content inside a plugin (use
/write-skill), adopting an external plugin into the marketplace (use /marketplace-architect),
or validating existing manifests without creating anything (use /marketplace-architect).
metadata:
category: marketplace
---
<requirements>
## Required inputs
- **Plugin name** — kebab-case slug; ask if not stated. Validate: lowercase letters, digits, hyphens only; not already present in `plugins/` or `.claude-plugin/marketplace.json`; not a reserved name (`anthropic-*`, `claude-*`, `agent-skills`, `official-claude-plugins`).
- **Plugin description** — one sentence; ask if not stated.
- **Author name** — ask if not stated.
- **Author email** — ask if not stated; used in the Copilot root `plugin.json`.
- **Author URL** — ask if not stated; used in Claude's `.claude-plugin/plugin.json`.
## Constraints
- Verify `templates/plugin/` exists at the repo root before doing anything — stop if missing; do not generate files from memory.
- Plugin name must be kebab-case and not a reserved name (`anthropic-*`, `claude-*`, `agent-skills`, `official-claude-plugins`) — halt and ask for a replacement before Gate A if violated.
- Do not write any file until Gate A (plan approval) and Gate B (file contents approval) are both explicitly confirmed.
- Replace all five placeholder markers — `PLUGIN_NAME`, `PLUGIN_DESCRIPTION`, `AUTHOR_NAME`, `AUTHOR_EMAIL`, `AUTHOR_URL` — in every copied file before Gate B review. No marker may appear in written output.
- Do not generate skill content — `skills/` is scaffolded as an empty directory with README only. Direct the user to `/write-skill` to add skills.
- Do not set `version` in both `plugin.json` and the marketplace entry — `plugin.json` wins silently and blocks updates for existing users.
- Update `.github/plugin/marketplace.json` only if it already exists — do not create it.
- Do not auto-invoke `/marketplace-architect` — hand off by name at the end; let the user trigger it.
</requirements>
<steps>
## Process
1. **Collect inputs.** Ask for plugin name, description, author name, author email, and author URL — one question at a time. Validate the plugin name: kebab-case format, not a reserved name, not already present in `plugins/` or `.claude-plugin/marketplace.json`. If any validation fails, stop and ask for a replacement before continuing.
2. **Check template.** Verify `templates/plugin/` exists at the repo root. If missing, stop and report the path — do not proceed or generate files from memory.
3. **Gate A — plan review.** Present: the list of files that will be written (derived from `templates/plugin/` with `PLUGIN_NAME` substituted into filenames), the new `plugins/<name>/` directory path, the marketplace entry that will be added to `.claude-plugin/marketplace.json`, and whether `.github/plugin/marketplace.json` will also be updated. Wait for explicit approval — do not proceed on "looks good" or silence.
4. **Copy and substitute.** Copy `templates/plugin/` to `plugins/<name>/`. In every copied file, replace all occurrences of `PLUGIN_NAME`, `PLUGIN_DESCRIPTION`, `AUTHOR_NAME`, `AUTHOR_EMAIL`, and `AUTHOR_URL` with the collected values. Rename any file or directory whose name contains `PLUGIN_NAME`.
5. **Gate B — file contents review.** Show every file with its full substituted content. Wait for explicit approval — do not write until confirmed.
6. **Write files.** Write all substituted files to `plugins/<name>/`. Append the new plugin entry to `.claude-plugin/marketplace.json`. If `.github/plugin/marketplace.json` exists, append the same entry there.
7. **Validate.** Run `claude plugin validate .` from `plugins/<name>/`. Report all output inline — do not suppress warnings. If the command is unavailable, note it and suggest the user run it manually after local install.
8. **Hand off.** Print: "Plugin `<name>` created and registered in `marketplace.json`. Fill in skill and agent content, then run `/marketplace-architect` to audit the full marketplace."
## Output format
- `plugins/<name>/` — directory tree copied from `templates/plugin/` with all placeholders substituted
- `.claude-plugin/marketplace.json` — updated with the new plugin entry
- `.github/plugin/marketplace.json` — updated with the same entry, only if it already existed
- Inline validation report from `claude plugin validate .`
</steps>
<checks>
## Failure handling
- `templates/plugin/` not found — stop, report the path searched, do not generate from memory.
- Plugin name already exists in `plugins/` or `marketplace.json` — stop, report the conflict, ask for a different name.
- Reserved name detected — stop, report the name and the reserved list, ask for a replacement before continuing.
- `claude plugin validate .` unavailable — report that automated validation was skipped; suggest running it manually with `claude --plugin-dir ./plugins/<name>`.
## Self-check
- [ ] Plugin name validated: kebab-case, not reserved, not already present in `plugins/` or `marketplace.json`
- [ ] `templates/plugin/` verified to exist before any file generation
- [ ] Gate A presented with file list and marketplace entry — explicit approval received
- [ ] All five markers substituted in all files — none appear in written output
- [ ] Gate B presented with full substituted file contents — explicit approval received
- [ ] Files written only after Gate B approval
- [ ] `.github/plugin/marketplace.json` updated only if it already existed — not created
- [ ] `claude plugin validate .` run and results reported; or unavailability noted
- [ ] Hand-off message printed directing user to `/marketplace-architect`
- [ ] No skill content generated — `skills/` is empty with README only
</checks>