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:
118
.agents/evals/marketplace/plugin-create/eval.yaml
Normal file
118
.agents/evals/marketplace/plugin-create/eval.yaml
Normal 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'"
|
||||
13
.agents/skills/plugin-create/META.md
Normal file
13
.agents/skills/plugin-create/META.md
Normal 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
|
||||
```
|
||||
89
.agents/skills/plugin-create/SKILL.md
Normal file
89
.agents/skills/plugin-create/SKILL.md
Normal 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>
|
||||
Reference in New Issue
Block a user