Plugin Validator Usage Guide
Complete usage reference for plugin_validator.py - the comprehensive validation tool for Claude Code plugins.
Quick Start
Basic validation:
uv run plugins/plugin-creator/scripts/plugin_validator.py <path>
Auto-fix issues:
uv run plugins/plugin-creator/scripts/plugin_validator.py --fix <path>
Validate only (no auto-fix):
uv run plugins/plugin-creator/scripts/plugin_validator.py --check <path>
Command-Line Interface
Synopsis
plugin_validator.py [OPTIONS] PATH
Arguments
PATH (required)
- File or directory to validate
- Accepts: SKILL.md, agent .md, command .md, plugin directory
- Examples:
plugins/my-plugin/plugins/my-plugin/skills/my-skill/SKILL.md.claude/agents/my-agent.md~/.claude/commands/my-command.md
Options
--check
- Validate only, do not auto-fix issues
- Useful for CI/CD pipelines
- Exit code 0 = valid, 1 = errors found
--fix
- Auto-fix issues where possible (4 error codes)
- Modifies files in-place
- Re-validates after fixing
- Shows what was fixed
--verbose
- Show all validation checks, including passed checks
- Useful for debugging and understanding validation process
- Displays detailed information about each validator
--no-color
- Disable Rich color output
- Useful for CI/CD or non-TTY environments
- Plain text output only
--help
- Show help message and exit
- Displays all options and usage examples
Exit Codes
| Code | Meaning | Scenario |
|---|---|---|
| 0 | Success | All checks passed (warnings/info allowed) |
| 1 | Validation failed | Errors found |
| 2 | Usage error | Invalid arguments or missing path |
| 130 | User interrupted | Ctrl+C during execution |
Usage Examples
Example 1: Validate Single Skill
uv run plugins/plugin-creator/scripts/plugin_validator.py \
plugins/my-plugin/skills/my-skill/SKILL.md
Output:
Validating: plugins/my-plugin/skills/my-skill/SKILL.md
✅ Frontmatter validation passed
⚠️ Description validation warnings:
- SK005: Description missing trigger phrases (line 3)
Suggestion: Add trigger phrases: 'use when', 'use this', 'trigger', 'activate'
✅ Complexity validation passed (2847 tokens)
✅ Internal link validation passed
ℹ️ Progressive disclosure info:
- PD001: No references/ directory
- PD002: No examples/ directory
Validation: PASSED (0 errors, 1 warning, 2 info)
Example 2: Validate Entire Plugin
uv run plugins/plugin-creator/scripts/plugin_validator.py plugins/my-plugin
Output:
Validating plugin: plugins/my-plugin
✅ Plugin structure validation passed
✅ Frontmatter validation passed (3 skills, 2 agents, 1 command)
⚠️ Complexity warnings:
- skills/large-skill/SKILL.md: SK006: 4523 tokens (consider splitting)
✅ Link validation passed
ℹ️ Progressive disclosure opportunities:
- 2 skills missing references/ directories
- 1 skill missing examples/ directory
Validation: PASSED (0 errors, 1 warning, 3 info)
Example 3: Auto-Fix Frontmatter Issues
uv run plugins/plugin-creator/scripts/plugin_validator.py --fix \
plugins/my-plugin/skills/my-skill/SKILL.md
Output:
Validating: plugins/my-plugin/skills/my-skill/SKILL.md
🔧 Auto-fixing issues...
Fixed (4 changes):
- FM007: Converted tools YAML array to comma-separated string
- FM008: Converted skills YAML array to comma-separated string
- FM009: Quoted description containing colons
- FM004: Removed multiline indicator from description
Re-validating after fixes...
✅ All checks passed
Validation: PASSED (0 errors, 0 warnings, 0 info)
Example 4: Validate for CI/CD
# Check-only mode for CI pipeline
uv run plugins/plugin-creator/scripts/plugin_validator.py \
--check --no-color plugins/my-plugin
# Exit code 0 = pass, 1 = fail
if [ $? -eq 0 ]; then
echo "Validation passed"
else
echo "Validation failed"
exit 1
fi
Example 5: Verbose Output for Debugging
uv run plugins/plugin-creator/scripts/plugin_validator.py \
--verbose plugins/my-plugin/skills/my-skill/SKILL.md
Output:
Validating: plugins/my-plugin/skills/my-skill/SKILL.md
Running validators:
1. FrontmatterValidator
- Checking YAML syntax... ✅
- Checking required fields... ✅
- Checking field types... ✅
- Checking tools format... ✅
- Checking name pattern... ✅
2. NameFormatValidator
- Checking for uppercase... ✅
- Checking for underscores... ✅
- Checking for invalid hyphens... ✅
3. DescriptionValidator
- Checking minimum length... ✅ (45 chars)
- Checking trigger phrases... ⚠️ SK005: Missing trigger phrases
4. ComplexityValidator
- Measuring token count... ✅ (2847 tokens)
- Checking warning threshold... ✅ (<4000)
- Checking error threshold... ✅ (<6400)
5. InternalLinkValidator
- Extracting markdown links... (3 links found)
- Checking link validity... ✅
- Checking ./ prefix... ✅
6. ProgressiveDisclosureValidator
- Checking references/ directory... ℹ️ PD001: Not found
- Checking examples/ directory... ℹ️ PD002: Not found
- Checking scripts/ directory... ✅ (2 scripts)
Validation: PASSED (0 errors, 1 warning, 2 info)
Example 6: Validate Agent File
uv run plugins/plugin-creator/scripts/plugin_validator.py \
.claude/agents/my-agent.md
Output:
Validating: .claude/agents/my-agent.md
✅ Frontmatter validation passed
✅ Name format validation passed
⚠️ Description validation warnings:
- SK004: Description too short (18 chars, minimum 20)
Validation: PASSED (0 errors, 1 warning)
Example 7: Validate Command File
uv run plugins/plugin-creator/scripts/plugin_validator.py \
~/.claude/commands/my-command.md
Output:
Validating: ~/.claude/commands/my-command.md
✅ Frontmatter validation passed
✅ Name format validation passed
✅ Description validation passed
Validation: PASSED (0 errors)
Common Workflows
Workflow 1: Pre-Commit Validation
Goal: Validate plugin components before committing to git
Steps:
- Stage changes:
git add plugins/my-plugin/skills/my-skill/SKILL.md
- Validate changes:
uv run plugins/plugin-creator/scripts/plugin_validator.py \
--check plugins/my-plugin/skills/my-skill/SKILL.md
- Fix issues if validation fails:
uv run plugins/plugin-creator/scripts/plugin_validator.py \
--fix plugins/my-plugin/skills/my-skill/SKILL.md
- Commit:
git add plugins/my-plugin/skills/my-skill/SKILL.md
git commit -m "fix(my-skill): correct frontmatter formatting"
Workflow 2: Create New Skill
Goal: Create and validate a new skill from scratch
Steps:
- Create skill directory and SKILL.md:
mkdir -p plugins/my-plugin/skills/new-skill
touch plugins/my-plugin/skills/new-skill/SKILL.md
Write frontmatter and content (use editor)
Validate:
uv run plugins/plugin-creator/scripts/plugin_validator.py \
plugins/my-plugin/skills/new-skill/SKILL.md
- Fix issues:
uv run plugins/plugin-creator/scripts/plugin_validator.py \
--fix plugins/my-plugin/skills/new-skill/SKILL.md
- Add to plugin.json:
{
"skills": [
"./skills/new-skill/"
]
}
- Validate entire plugin:
uv run plugins/plugin-creator/scripts/plugin_validator.py \
plugins/my-plugin
Workflow 3: Refactor Oversized Skill
Goal: Split skill exceeding token thresholds
Steps:
- Check token count:
uv run plugins/plugin-creator/scripts/plugin_validator.py \
--verbose plugins/my-plugin/skills/large-skill/SKILL.md
Output shows: SK006: 4523 tokens (consider splitting)
- Create progressive disclosure structure:
mkdir -p plugins/my-plugin/skills/large-skill/references
mkdir -p plugins/my-plugin/skills/large-skill/examples
- Move detailed content to references/:
# Extract detailed sections from SKILL.md into reference files
mv detailed-section.md plugins/my-plugin/skills/large-skill/references/
- Update SKILL.md with links to reference files:
For detailed information, see [detailed guide](./references/detailed-section.md).
- Re-validate:
uv run plugins/plugin-creator/scripts/plugin_validator.py \
--verbose plugins/my-plugin/skills/large-skill/SKILL.md
Output shows: ✅ Complexity validation passed (2847 tokens)
Workflow 4: Batch Validate All Plugins
Goal: Validate all plugins in repository
Steps:
- Create validation script:
#!/usr/bin/env bash
# validate-all-plugins.sh
set -euo pipefail
failed_plugins=()
for plugin_dir in plugins/*/; do
echo "Validating $plugin_dir..."
if ! uv run plugins/plugin-creator/scripts/plugin_validator.py \
--check --no-color "$plugin_dir"; then
failed_plugins+=("$plugin_dir")
fi
done
if [ ${#failed_plugins[@]} -eq 0 ]; then
echo "✅ All plugins validated successfully"
exit 0
else
echo "❌ Validation failed for:"
printf ' - %s\n' "${failed_plugins[@]}"
exit 1
fi
- Make executable and run:
chmod +x validate-all-plugins.sh
./validate-all-plugins.sh
Workflow 5: Fix All Auto-Fixable Issues
Goal: Automatically fix all frontmatter formatting issues
Steps:
- Create fix-all script:
#!/usr/bin/env bash
# fix-all-frontmatter.sh
set -euo pipefail
# Find all SKILL.md, agent, and command files
find plugins -name "SKILL.md" -o -name "*.md" | while read -r file; do
echo "Fixing $file..."
uv run plugins/plugin-creator/scripts/plugin_validator.py --fix "$file"
done
- Make executable and run:
chmod +x fix-all-frontmatter.sh
./fix-all-frontmatter.sh
- Review changes:
git diff
- Commit if changes look correct:
git add -A
git commit -m "fix: auto-fix frontmatter formatting across all plugins"
Integration Patterns
Pre-Commit Hook Integration
Add to .pre-commit-config.yaml:
repos:
- repo: local
hooks:
- id: plugin-validator
name: Validate Plugin Components
entry: uv run plugins/plugin-creator/scripts/plugin_validator.py
language: system
files: '^plugins/.*/.*\.(md|json)$'
pass_filenames: false
args: [--check, --no-color]
Usage:
# Install pre-commit
pip install pre-commit
# Install hooks
pre-commit install
# Run manually
pre-commit run plugin-validator --all-files
CI/CD Pipeline Integration
GitHub Actions:
name: Validate Plugins
on: [push, pull_request]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install uv
run: curl -LsSf https://astral.sh/uv/install.sh | sh
- name: Validate plugins
run: |
for plugin in plugins/*/; do
uv run plugins/plugin-creator/scripts/plugin_validator.py \
--check --no-color "$plugin"
done
GitLab CI:
validate-plugins:
image: python:3.11
script:
- curl -LsSf https://astral.sh/uv/install.sh | sh
- export PATH="$HOME/.cargo/bin:$PATH"
- for plugin in plugins/*/; do
uv run plugins/plugin-creator/scripts/plugin_validator.py \
--check --no-color "$plugin";
done
Pre-Release Validation
Create release checklist script:
#!/usr/bin/env bash
# release-check.sh
set -euo pipefail
echo "Running pre-release validation..."
# 1. Validate all plugins
echo "✓ Validating plugins..."
for plugin in plugins/*/; do
uv run plugins/plugin-creator/scripts/plugin_validator.py \
--check --no-color "$plugin"
done
# 2. Check for oversized skills
echo "✓ Checking skill complexity..."
for skill in plugins/*/skills/*/SKILL.md; do
if ! uv run plugins/plugin-creator/scripts/plugin_validator.py \
--check --no-color "$skill" 2>&1 | grep -q "SK007"; then
continue
else
echo "ERROR: Oversized skill detected: $skill"
exit 1
fi
done
# 3. Check for broken links
echo "✓ Checking internal links..."
# (plugin_validator.py handles this)
# 4. Validate plugin.json files
echo "✓ Validating plugin.json files..."
for plugin_json in plugins/*/.claude-plugin/plugin.json; do
python3 -m json.tool "$plugin_json" > /dev/null
done
echo "✅ Pre-release validation passed"
Troubleshooting
Issue: "Invalid YAML syntax" but YAML looks correct
Symptom: FM002 error but YAML syntax appears valid
Cause: Common YAML pitfalls:
- Unquoted strings with colons (
:) - Unquoted strings with special characters
- Incorrect indentation (spaces vs tabs)
Fix:
- Quote all strings containing special characters
- Use spaces, not tabs, for indentation
- Validate YAML with external tool:
python3 -c "import yaml; yaml.safe_load(open('SKILL.md').read().split('---')[1])"
Issue: "Token count exceeds 6400" but file looks reasonable
Symptom: SK007 error but file doesn't seem oversized
Cause: Token count measures what Claude processes, not visual line count. Complex markdown, code blocks, and repeated phrases increase token count.
Fix:
- Check actual token count:
uv run plugins/plugin-creator/scripts/plugin_validator.py \
--verbose plugins/my-plugin/skills/my-skill/SKILL.md
- Apply progressive disclosure:
- Move detailed reference material to
./references/ - Move code examples to
./examples/ - Move implementation scripts to
./scripts/ - Keep only high-level guidance in SKILL.md
- Move detailed reference material to
Issue: Auto-fix changes content unexpectedly
Symptom: --fix modifies content in unintended ways
Cause: Auto-fix applies specific transformations:
- Converts YAML arrays to CSV strings
- Quotes descriptions with colons
- Removes multiline indicators
Fix:
- Review changes before committing:
git diff
- Manually adjust if auto-fix produces incorrect result
- Use
--checkmode first to preview issues:
uv run plugins/plugin-creator/scripts/plugin_validator.py \
--check plugins/my-plugin/skills/my-skill/SKILL.md
Issue: Validation passes but claude plugin validate fails
Symptom: plugin_validator.py passes but claude plugin validate reports errors
Cause: Different validation scopes:
plugin_validator.pyvalidates component filesclaude plugin validatevalidates plugin.json structure
Fix:
- Run both validators:
# Component validation
uv run plugins/plugin-creator/scripts/plugin_validator.py plugins/my-plugin
# Structure validation
claude plugin validate plugins/my-plugin
- Fix plugin.json issues reported by Claude CLI
Issue: Performance is slow on large plugins
Symptom: Validation takes >30 seconds
Cause: Large plugins with many components, complex token counting
Optimization:
- Validate individual components instead of entire plugin:
# Fast: validate single file
uv run plugins/plugin-creator/scripts/plugin_validator.py \
plugins/my-plugin/skills/my-skill/SKILL.md
# Slow: validate entire plugin
uv run plugins/plugin-creator/scripts/plugin_validator.py plugins/my-plugin
Use
--checkmode to skip auto-fix overheadProfile with verbose output to identify slow validators
See Also
- ERROR_CODES.md - Complete error code reference
- ARCHITECTURE.md - Validator design and implementation
- plugin_validator.py - Source code
- Claude Code Plugin Documentation - Official plugin documentation