Use this skill when asked to "validate plugin", "check plugin structure", "verify plugin", "audit plugin", "is my plugin correct", "plugin issues", or when troubleshooting plugin problems.
Inherits all available tools
Additional assets for this skill
This skill inherits all available tools. When active, it can use any tool Claude has access to.
This skill provides comprehensive validation guidelines for Claude Code plugins, helping identify structural issues, misconfigurations, and best practice violations.
Check .claude-plugin/plugin.json:
Required:
.claude-plugin/plugin.jsonname field present and validName validation:
Optional fields (if present):
version follows semver (X.Y.Z)description is a non-empty stringauthor has name field (string)author.email is valid email format (if present)Required structure:
plugin-name/
├── .claude-plugin/
│ └── plugin.json ← REQUIRED
Valid optional directories:
agents/ - Contains .md files onlyskills/ - Contains subdirectories with SKILL.mdcommands/ - Contains .md files onlyhooks/ - Contains hooks.jsonscripts/ - Contains executable scriptsInvalid patterns to flag:
AGENTS.md at root (should be agents/*.md)SKILL.md at root (should be skills/*/SKILL.md).claude-plugin/ directoriesskills/ (should be in subdirs)For each file in agents/*.md:
Frontmatter checks:
---name field presentdescription field presentName field:
Description field:
<example> block (recommended)user:, assistant:, <commentary>Model field (if present):
inherit, sonnet, opus, haikuColor field (if present):
blue, cyan, green, yellow, magenta, redTools field (if present):
Content check:
For each directory in skills/*/:
Structure:
SKILL.md fileSKILL.md has YAML frontmatterFrontmatter:
name field presentdescription field present with trigger phrasesOptional subdirectories:
references/ - Additional documentationexamples/ - Working examplesscripts/ - Utility scriptsFor each file in commands/*.md:
Frontmatter:
description field presentargument-hint is string (if present)allowed-tools is array (if present)Naming:
For hooks/hooks.json:
JSON structure:
hooks object at root (or in description + hooks)Event names (if present):
PreToolUsePostToolUseStopSubagentStopSessionStartSessionEndUserPromptSubmitPreCompactNotificationPermissionRequestHook entries:
matcher field present (for tool events)hooks array presenttype ("command" or "prompt")command fieldprompt fieldPath portability:
${CLAUDE_PLUGIN_ROOT} for plugin pathsScript references:
Credentials:
URLs:
Scripts:
Cause: Missing or invalid plugin.json
Fix: Create .claude-plugin/plugin.json with valid JSON and name field
Cause: Agents not in correct location
Fix: Move to agents/ directory with .md extension
Cause: Weak trigger description or wrong structure Fix:
skills/{name}/SKILL.md structureCause: Invalid hooks.json or script permissions Fix:
chmod +x scripts/*.sh${CLAUDE_PLUGIN_ROOT} in pathsCause: Missing frontmatter or wrong location
Fix: Ensure commands/*.md with description in frontmatter
Quick structure check:
# Check plugin.json exists and is valid
jq . my-plugin/.claude-plugin/plugin.json
# List all components
find my-plugin -name "*.md" -o -name "*.json" | head -20
# Check hooks.json
jq . my-plugin/hooks/hooks.json 2>/dev/null || echo "No hooks.json"
Test plugin locally:
claude --plugin-dir /path/to/my-plugin
Debug mode:
claude --debug --plugin-dir /path/to/my-plugin
When reporting validation results:
## Plugin Validation Report
### Plugin: [name]
Location: [path]
### Summary
[PASS/FAIL] - [brief assessment]
### Critical Issues (must fix)
- [ ] `path/to/file` - [issue] - [fix]
### Warnings (should fix)
- [ ] `path/to/file` - [issue] - [recommendation]
### Components Found
- Agents: [count] files
- Skills: [count] directories
- Commands: [count] files
- Hooks: [present/not present]
### Positive Findings
- [What's done correctly]
### Recommendations
1. [Priority fix]
2. [Improvement suggestion]
#!/bin/bash
# validate-plugin.sh <plugin-dir>
PLUGIN_DIR="${1:-.}"
echo "=== Plugin Validation ==="
# Check plugin.json
if [ -f "$PLUGIN_DIR/.claude-plugin/plugin.json" ]; then
echo "✓ plugin.json exists"
NAME=$(jq -r '.name' "$PLUGIN_DIR/.claude-plugin/plugin.json" 2>/dev/null)
if [ -n "$NAME" ] && [ "$NAME" != "null" ]; then
echo "✓ name: $NAME"
else
echo "✗ ERROR: name field missing or invalid"
fi
else
echo "✗ CRITICAL: .claude-plugin/plugin.json not found"
fi
# Check agents
if [ -d "$PLUGIN_DIR/agents" ]; then
AGENT_COUNT=$(find "$PLUGIN_DIR/agents" -name "*.md" | wc -l)
echo "✓ agents/: $AGENT_COUNT files"
fi
# Check skills
if [ -d "$PLUGIN_DIR/skills" ]; then
SKILL_COUNT=$(find "$PLUGIN_DIR/skills" -name "SKILL.md" | wc -l)
echo "✓ skills/: $SKILL_COUNT SKILL.md files"
fi
# Check commands
if [ -d "$PLUGIN_DIR/commands" ]; then
CMD_COUNT=$(find "$PLUGIN_DIR/commands" -name "*.md" | wc -l)
echo "✓ commands/: $CMD_COUNT files"
fi
# Check hooks
if [ -f "$PLUGIN_DIR/hooks/hooks.json" ]; then
if jq empty "$PLUGIN_DIR/hooks/hooks.json" 2>/dev/null; then
echo "✓ hooks/hooks.json: valid JSON"
else
echo "✗ hooks/hooks.json: invalid JSON"
fi
fi
echo "=== Validation Complete ==="