Ariff-claude-plugins plugin-checker
git clone https://github.com/a-ariff/ariff-claude-plugins
T=$(mktemp -d) && git clone --depth=1 https://github.com/a-ariff/ariff-claude-plugins "$T" && mkdir -p ~/.claude/skills && cp -r "$T/plugins/plugin-checker/skills/plugin-checker" ~/.claude/skills/a-ariff-ariff-claude-plugins-plugin-checker && rm -rf "$T"
plugins/plugin-checker/skills/plugin-checker/SKILL.mdPlugin Checker Skill
This skill provides comprehensive validation guidelines for Claude Code plugins, helping identify structural issues, misconfigurations, and best practice violations.
Validation Checklist
1. Plugin Manifest Validation
Check
.claude-plugin/plugin.json:
Required:
- File exists at
.claude-plugin/plugin.json - Valid JSON syntax
-
field present and validname
Name validation:
- Uses kebab-case (lowercase letters, numbers, hyphens)
- Length between 3-50 characters
- No spaces or special characters
- Starts with a letter
Optional fields (if present):
-
follows semver (X.Y.Z)version -
is a non-empty stringdescription -
hasauthor
field (string)name -
is valid email format (if present)author.email
2. Directory Structure Validation
Required structure:
plugin-name/ ├── .claude-plugin/ │ └── plugin.json ← REQUIRED
Valid optional directories:
-
- Containsagents/
files only.md -
- Contains subdirectories withskills/SKILL.md -
- Containscommands/
files only.md -
- Containshooks/hooks.json -
- Contains executable scriptsscripts/
Invalid patterns to flag:
- ❌
at root (should beAGENTS.md
)agents/*.md - ❌
at root (should beSKILL.md
)skills/*/SKILL.md - ❌ Nested
directories.claude-plugin/ - ❌ Files directly in
(should be in subdirs)skills/
3. Agent File Validation
For each file in
agents/*.md:
Frontmatter checks:
- File starts with
--- - Valid YAML frontmatter
-
field presentname -
field presentdescription
Name field:
- Lowercase letters, numbers, hyphens only
- 3-50 characters
- Matches filename (recommended)
Description field:
- Contains trigger conditions
- Has at least one
block (recommended)<example> - Example has
,user:
,assistant:<commentary>
Model field (if present):
- Valid value:
,inherit
,sonnet
,opushaiku
Color field (if present):
- Valid value:
,blue
,cyan
,green
,yellow
,magentared
Tools field (if present):
- Is an array
- Contains valid tool names
Content check:
- Has system prompt after frontmatter
- System prompt is substantial (>20 chars)
4. Skill Directory Validation
For each directory in
skills/*/:
Structure:
- Contains
fileSKILL.md -
has YAML frontmatterSKILL.md
Frontmatter:
-
field presentname -
field present with trigger phrasesdescription
Optional subdirectories:
-
- Additional documentationreferences/ -
- Working examplesexamples/ -
- Utility scriptsscripts/
5. Command File Validation
For each file in
commands/*.md:
Frontmatter:
-
field presentdescription -
is string (if present)argument-hint -
is array (if present)allowed-tools
Naming:
- Filename is kebab-case
- No spaces or special characters
6. Hooks Validation
For
hooks/hooks.json:
JSON structure:
- Valid JSON syntax
- Has
object at root (or inhooks
+description
)hooks
Event names (if present):
-
PreToolUse -
PostToolUse -
Stop -
SubagentStop -
SessionStart -
SessionEnd -
UserPromptSubmit -
PreCompact -
Notification -
PermissionRequest
Hook entries:
-
field present (for tool events)matcher -
array presenthooks - Each hook has
("command" or "prompt")type - Command hooks have
fieldcommand - Prompt hooks have
fieldprompt
Path portability:
- Uses
for plugin paths${CLAUDE_PLUGIN_ROOT} - No hardcoded absolute paths
Script references:
- Referenced scripts exist
- Scripts are executable (have shebang)
7. Security Checks
Credentials:
- No hardcoded API keys or tokens
- No passwords in configuration
- Environment variables used for secrets
URLs:
- MCP servers use HTTPS/WSS (not HTTP/WS)
Scripts:
- No obvious command injection vulnerabilities
- Input validation present
- Variables properly quoted
Common Issues and Fixes
Issue: "plugin not found"
Cause: Missing or invalid plugin.json Fix: Create
.claude-plugin/plugin.json with valid JSON and name field
Issue: "agents not loading"
Cause: Agents not in correct location Fix: Move to
agents/ directory with .md extension
Issue: "skill not triggering"
Cause: Weak trigger description or wrong structure Fix:
- Ensure
structureskills/{name}/SKILL.md - Add specific trigger phrases to description
Issue: "hooks not running"
Cause: Invalid hooks.json or script permissions Fix:
- Validate JSON syntax
- Make scripts executable:
chmod +x scripts/*.sh - Use
in paths${CLAUDE_PLUGIN_ROOT}
Issue: "command not appearing"
Cause: Missing frontmatter or wrong location Fix: Ensure
commands/*.md with description in frontmatter
Validation Commands
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
Validation Report Format
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]
Quick Validation Script
#!/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 ==="
References
- Plugin structure: https://code.claude.com/docs/en/plugins-reference
- Hooks reference: https://code.claude.com/docs/en/hooks
- Official examples: https://github.com/anthropics/claude-code/tree/main/plugins