plugins/agent-scaffolders/skills/create-plugin/SKILL.md
Scaffold a complete Claude Code plugin from scratch
npx skillsauth add richfrem/agent-plugins-skills create-pluginInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Follow the create-plugin skill workflow to scaffold a new Claude Code plugin.
$ARGUMENTS — optional plugin name in kebab-case. Omit to start with discovery.$ARGUMENTS provides a plugin name, use it to seed Phase 1plugin.json, implement
each component using the appropriate sub-skill, validate, test, and document.claude-plugin/plugin.json.skills list.agents list.commands list.hooks list.plugin.json. ✅" or list additions made.plugin.json is finalized, scaffold a plugin.yaml at the plugin root for hermes-agent compatibility. Format:
name: <plugin-name>
version: <version>
description: "<description>"
author: <author>
kind: backend # or standalone (no Python scripts)
platforms:
- linux
- macos
- windows
provides_tools: # list script basenames (no .py) that expose callable tools
- script_name
skills: # list skill directory names under skills/
- skill-name
kind: standalone — plugin has no Python scripts that hermes calls directlykind: backend — plugin has scripts in scripts/ that hermes invokes as toolsprovides_tools if scripts/ contains callable tool scriptsskills/plugin.yaml created for hermes compatibility. ✅"__init__.py (Hermes tool/hook wiring — generate when plugin has scripts): If the plugin has callable Python scripts in scripts/, scaffold a root-level __init__.py with a register(ctx) function following this pattern:
from __future__ import annotations
from pathlib import Path
_HERE = Path(__file__).resolve().parent
def register(ctx) -> None:
# Register skills
ctx.register_skill(
name="<skill-name>", # bare name only — hermes auto-prefixes plugin name as namespace
path=_HERE / "skills" / "<skill-name>",
)
# Register tools (if scripts expose callable tools)
# ctx.register_tool(name, toolset, schema, handler)
# Register hooks (if plugin needs lifecycle hooks)
# ctx.register_hook("post_tool_call", handler)
register_skill() calls for every skill in the pluginregister_tool() if the plugin provides callable Python toolsregister_hook() if the plugin needs lifecycle hooks__init__.py, hermes shows "No __init__.py" warning and the plugin won't activate__init__.py created with register() function. ✅"Plugin directory with .claude-plugin/plugin.json, component directories, README.md,
and a .claude/settings.json stub for reliable local discovery.
$ARGUMENTS is empty: begin with Phase 1 discovery — do not pre-fill plugin namecreate-mcp-integration for each one/agent-scaffolders:audit-plugin to validate structureWhen a skill needs to call a Python helper script that is shared across skills in the same
plugin, always create a file-level symlink in the skill's scripts/ folder pointing to the
canonical copy at the plugin root — never duplicate the file.
Standard pattern:
plugins/<plugin>/scripts/<canonical_name>.py ← canonical source (real file)
plugins/<plugin>/skills/<skill>/scripts/<name>.py ← symlink → ../../../scripts/<canonical_name>.py
The symlink name and target name may differ (e.g. execute.py → exploration_optimizer_execute.py).
The bridge installer resolves all symlinks to physical copies when deploying via the marketplace.
Creating symlinks correctly:
# From the skill's scripts/ directory:
ln -s ../../../scripts/<canonical_name>.py <symlink_name>.py
# Or via symlink_manager.py:
python plugins/link-checker/scripts/symlink_manager.py create \
--src plugins/<plugin>/scripts/<canonical_name>.py \
--dst plugins/<plugin>/skills/<skill>/scripts/<symlink_name>.py
⚠️ Windows / core.symlinks warning: If git config core.symlinks is false, git checks
out symlinks as plain-text "stand-in" files. These are silently broken — the bridge installer
copies the path string, not the script. After checkout on Windows or any machine where
symlinks may have degraded, run:
python plugins/link-checker/scripts/bulk_symlink_fixer.py plugins/<plugin-name>
Then manually verify: find plugins/<plugin-name>/skills -path "*/scripts/*" -type f ! -type l
should return nothing (all script references should be real symlinks, not plain files).
When this plugin will be distributed via a marketplace.json, the marketplace entry defaults to strict: true, which requires the plugin to have its own plugin.json. A missing plugin.json silently prevents the entire plugin from loading.
Always:
.claude-plugin/plugin.json inside the plugin directory (this skill does this by default)"strict": true — never rely on the defaultmanage-marketplace skill for the correct marketplace entry formatreferences/ADRs/. Always consult them for standards on plugin architecture, shared scripts, cross-plugin dependencies, symlinking, and loose coupling to avoid repeating yourself.tools
Ingests repository files into the ChromaDB vector store. Builds or updates the vector index from a manifest or directory scan using ingest.py. Use when new files need to be indexed or the vector store is out of date. <example> user: "Index these new plugin files into the vector database" assistant: "I'll use vector-db-ingest to add them to the vector store." </example> <example> user: "The vector store is missing recent files -- update it" assistant: "I'll use vector-db-ingest to re-index the changes." </example>
data-ai
Removes stale and orphaned chunks from the ChromaDB vector store for files that have been deleted or renamed. Use after files are removed or moved to keep the vector index in sync with the filesystem. <example> user: "Clean up the vector store after I deleted some files" assistant: "I'll use vector-db-cleanup to remove orphaned chunks." </example> <example> user: "The vector database has chunks for files that no longer exist" assistant: "I'll run vector-db-cleanup to prune them." </example>
testing
Audit Vector DB coverage -- compares the live filesystem manifest against the ChromaDB index to identify coverage gaps.
development
3-Phase Knowledge Search strategy for the RLM Factory ecosystem. Auto-invoked when tasks involve finding code, documentation, or architecture context in the repository. Enforces the optimal search order: RLM Summary Scan (O(1)) -> Vector DB Semantic Search -> Grep/Exact Match. Never skip phases.