Initial commit
This commit is contained in:
223
commands/plugin-scaffold/.scripts/generate-metadata.py
Executable file
223
commands/plugin-scaffold/.scripts/generate-metadata.py
Executable file
@@ -0,0 +1,223 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Script: generate-metadata.py
|
||||
Purpose: Generate plugin.json metadata from parameters
|
||||
Version: 1.0.0
|
||||
Last Modified: 2025-10-13
|
||||
|
||||
Usage:
|
||||
./generate-metadata.py --name <name> --author <author> --description <desc> --license <license>
|
||||
|
||||
Returns:
|
||||
0 - Success, JSON written to stdout
|
||||
1 - Validation error
|
||||
2 - Missing required arguments
|
||||
|
||||
Dependencies:
|
||||
- python3 (3.7+)
|
||||
- json module (standard library)
|
||||
"""
|
||||
|
||||
import json
|
||||
import sys
|
||||
import argparse
|
||||
import re
|
||||
from datetime import datetime
|
||||
|
||||
# OpenPlugins standard categories
|
||||
VALID_CATEGORIES = [
|
||||
"development", "testing", "deployment", "documentation",
|
||||
"security", "database", "monitoring", "productivity",
|
||||
"quality", "collaboration"
|
||||
]
|
||||
|
||||
VALID_LICENSES = ["MIT", "Apache-2.0", "GPL-3.0", "BSD-3-Clause", "ISC", "LGPL-3.0"]
|
||||
|
||||
def parse_author(author_string):
|
||||
"""Parse author string into name and email components."""
|
||||
# Pattern: "Name <email>" or "Name" or "Name (email)"
|
||||
email_pattern = r'<([^>]+)>'
|
||||
paren_pattern = r'\(([^\)]+)\)'
|
||||
|
||||
name = author_string
|
||||
email = None
|
||||
|
||||
# Check for <email> format
|
||||
email_match = re.search(email_pattern, author_string)
|
||||
if email_match:
|
||||
email = email_match.group(1)
|
||||
name = author_string[:email_match.start()].strip()
|
||||
else:
|
||||
# Check for (email) format
|
||||
paren_match = re.search(paren_pattern, author_string)
|
||||
if paren_match:
|
||||
email = paren_match.group(1)
|
||||
name = author_string[:paren_match.start()].strip()
|
||||
|
||||
result = {"name": name}
|
||||
if email:
|
||||
result["email"] = email
|
||||
|
||||
return result
|
||||
|
||||
def generate_keywords(name, description, category):
|
||||
"""Generate relevant keywords from name, description, and category."""
|
||||
keywords = []
|
||||
|
||||
# Add category
|
||||
keywords.append(category)
|
||||
|
||||
# Extract keywords from name
|
||||
name_parts = name.split('-')
|
||||
for part in name_parts:
|
||||
if len(part) > 3 and part not in ['plugin', 'claude', 'code']:
|
||||
keywords.append(part)
|
||||
|
||||
# Extract keywords from description (simple approach)
|
||||
desc_words = re.findall(r'\b[a-z]{4,}\b', description.lower())
|
||||
common_words = {'with', 'from', 'this', 'that', 'have', 'will', 'your', 'for'}
|
||||
for word in desc_words[:3]: # Take first 3 meaningful words
|
||||
if word not in common_words and word not in keywords:
|
||||
keywords.append(word)
|
||||
|
||||
# Ensure 3-7 keywords
|
||||
return keywords[:7]
|
||||
|
||||
def validate_name(name):
|
||||
"""Validate plugin name format."""
|
||||
pattern = r'^[a-z][a-z0-9-]*[a-z0-9]$|^[a-z]$'
|
||||
if not re.match(pattern, name):
|
||||
return False, "Plugin name must be lowercase with hyphens only"
|
||||
if '--' in name:
|
||||
return False, "Plugin name cannot contain consecutive hyphens"
|
||||
if len(name) < 3 or len(name) > 50:
|
||||
return False, "Plugin name must be 3-50 characters"
|
||||
return True, None
|
||||
|
||||
def validate_description(description):
|
||||
"""Validate description length and content."""
|
||||
length = len(description)
|
||||
if length < 50:
|
||||
return False, f"Description too short ({length} chars, minimum 50)"
|
||||
if length > 200:
|
||||
return False, f"Description too long ({length} chars, maximum 200)"
|
||||
return True, None
|
||||
|
||||
def generate_metadata(args):
|
||||
"""Generate complete plugin.json metadata."""
|
||||
|
||||
# Validate name
|
||||
valid, error = validate_name(args.name)
|
||||
if not valid:
|
||||
print(f"ERROR: {error}", file=sys.stderr)
|
||||
return None
|
||||
|
||||
# Validate description
|
||||
valid, error = validate_description(args.description)
|
||||
if not valid:
|
||||
print(f"ERROR: {error}", file=sys.stderr)
|
||||
return None
|
||||
|
||||
# Validate license
|
||||
if args.license not in VALID_LICENSES:
|
||||
print(f"ERROR: Invalid license. Must be one of: {', '.join(VALID_LICENSES)}", file=sys.stderr)
|
||||
return None
|
||||
|
||||
# Validate category
|
||||
if args.category not in VALID_CATEGORIES:
|
||||
print(f"ERROR: Invalid category. Must be one of: {', '.join(VALID_CATEGORIES)}", file=sys.stderr)
|
||||
return None
|
||||
|
||||
# Parse author
|
||||
author = parse_author(args.author)
|
||||
|
||||
# Generate or use provided keywords
|
||||
if args.keywords:
|
||||
keywords = [k.strip() for k in args.keywords.split(',')]
|
||||
else:
|
||||
keywords = generate_keywords(args.name, args.description, args.category)
|
||||
|
||||
# Build metadata object
|
||||
metadata = {
|
||||
"name": args.name,
|
||||
"version": args.version,
|
||||
"description": args.description,
|
||||
"author": author,
|
||||
"license": args.license
|
||||
}
|
||||
|
||||
# Add optional fields if provided
|
||||
if args.repository:
|
||||
metadata["repository"] = {
|
||||
"type": "git",
|
||||
"url": args.repository
|
||||
}
|
||||
elif args.github_username:
|
||||
metadata["repository"] = {
|
||||
"type": "git",
|
||||
"url": f"https://github.com/{args.github_username}/{args.name}"
|
||||
}
|
||||
metadata["homepage"] = f"https://github.com/{args.github_username}/{args.name}"
|
||||
|
||||
if args.homepage:
|
||||
metadata["homepage"] = args.homepage
|
||||
|
||||
if keywords:
|
||||
metadata["keywords"] = keywords
|
||||
|
||||
if args.category:
|
||||
metadata["category"] = args.category
|
||||
|
||||
return metadata
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Generate plugin.json metadata',
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter
|
||||
)
|
||||
|
||||
# Required arguments
|
||||
parser.add_argument('--name', required=True, help='Plugin name (lowercase-hyphen)')
|
||||
parser.add_argument('--author', required=True, help='Author name or "Name <email>"')
|
||||
parser.add_argument('--description', required=True, help='Plugin description (50-200 chars)')
|
||||
parser.add_argument('--license', required=True, help='License type (MIT, Apache-2.0, etc.)')
|
||||
|
||||
# Optional arguments
|
||||
parser.add_argument('--version', default='1.0.0', help='Initial version (default: 1.0.0)')
|
||||
parser.add_argument('--category', default='development', help='Plugin category')
|
||||
parser.add_argument('--keywords', help='Comma-separated keywords')
|
||||
parser.add_argument('--repository', help='Repository URL')
|
||||
parser.add_argument('--homepage', help='Homepage URL')
|
||||
parser.add_argument('--github-username', help='GitHub username (auto-generates repo URL)')
|
||||
parser.add_argument('--output', help='Output file path (default: stdout)')
|
||||
parser.add_argument('--pretty', action='store_true', help='Pretty-print JSON')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Generate metadata
|
||||
metadata = generate_metadata(args)
|
||||
if metadata is None:
|
||||
return 1
|
||||
|
||||
# Format JSON
|
||||
if args.pretty:
|
||||
json_output = json.dumps(metadata, indent=2, ensure_ascii=False)
|
||||
else:
|
||||
json_output = json.dumps(metadata, ensure_ascii=False)
|
||||
|
||||
# Output
|
||||
if args.output:
|
||||
try:
|
||||
with open(args.output, 'w', encoding='utf-8') as f:
|
||||
f.write(json_output)
|
||||
print(f"✅ Metadata written to {args.output}", file=sys.stderr)
|
||||
except IOError as e:
|
||||
print(f"ERROR: Could not write to {args.output}: {e}", file=sys.stderr)
|
||||
return 1
|
||||
else:
|
||||
print(json_output)
|
||||
|
||||
return 0
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
91
commands/plugin-scaffold/.scripts/validate-name.sh
Executable file
91
commands/plugin-scaffold/.scripts/validate-name.sh
Executable file
@@ -0,0 +1,91 @@
|
||||
#!/bin/bash
|
||||
# Script: validate-name.sh
|
||||
# Purpose: Validate plugin name follows Claude Code conventions
|
||||
# Version: 1.0.0
|
||||
# Last Modified: 2025-10-13
|
||||
#
|
||||
# Usage:
|
||||
# ./validate-name.sh <plugin-name>
|
||||
#
|
||||
# Arguments:
|
||||
# plugin-name: Name to validate
|
||||
#
|
||||
# Returns:
|
||||
# 0 - Valid name
|
||||
# 1 - Invalid name format
|
||||
# 2 - Missing argument
|
||||
#
|
||||
# Dependencies:
|
||||
# - grep (for regex matching)
|
||||
|
||||
# Check for argument
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "ERROR: Plugin name required"
|
||||
echo "Usage: $0 <plugin-name>"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
PLUGIN_NAME="$1"
|
||||
|
||||
# Validation pattern: lowercase letters, numbers, hyphens
|
||||
# Must start with letter, cannot end with hyphen
|
||||
VALID_PATTERN='^[a-z][a-z0-9-]*[a-z0-9]$|^[a-z]$'
|
||||
|
||||
# Check pattern match
|
||||
if echo "$PLUGIN_NAME" | grep -Eq "$VALID_PATTERN"; then
|
||||
# Additional checks
|
||||
|
||||
# Check for consecutive hyphens
|
||||
if echo "$PLUGIN_NAME" | grep -q '\-\-'; then
|
||||
echo "ERROR: Plugin name cannot contain consecutive hyphens"
|
||||
echo "Invalid: $PLUGIN_NAME"
|
||||
echo "Try: $(echo "$PLUGIN_NAME" | sed 's/--/-/g')"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check length (reasonable limit)
|
||||
NAME_LENGTH=${#PLUGIN_NAME}
|
||||
if [ $NAME_LENGTH -gt 50 ]; then
|
||||
echo "ERROR: Plugin name too long ($NAME_LENGTH characters, max 50)"
|
||||
echo "Consider a shorter name"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ $NAME_LENGTH -lt 3 ]; then
|
||||
echo "ERROR: Plugin name too short ($NAME_LENGTH characters, min 3)"
|
||||
echo "Use a more descriptive name"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check for common mistakes
|
||||
if echo "$PLUGIN_NAME" | grep -iq 'plugin$'; then
|
||||
echo "WARNING: Plugin name ends with 'plugin' - this is redundant"
|
||||
echo "Consider: $(echo "$PLUGIN_NAME" | sed 's/-plugin$//' | sed 's/plugin$//')"
|
||||
fi
|
||||
|
||||
# Success
|
||||
echo "✅ Valid plugin name: $PLUGIN_NAME"
|
||||
exit 0
|
||||
else
|
||||
# Invalid format
|
||||
echo "ERROR: Invalid plugin name format: $PLUGIN_NAME"
|
||||
echo ""
|
||||
echo "Plugin names must:"
|
||||
echo " - Start with a lowercase letter"
|
||||
echo " - Contain only lowercase letters, numbers, and hyphens"
|
||||
echo " - Not end with a hyphen"
|
||||
echo " - Be between 3-50 characters"
|
||||
echo ""
|
||||
echo "Valid examples:"
|
||||
echo " - code-formatter"
|
||||
echo " - test-generator"
|
||||
echo " - deploy-automation"
|
||||
echo ""
|
||||
echo "Invalid examples:"
|
||||
echo " - CodeFormatter (uppercase)"
|
||||
echo " - test_generator (underscores)"
|
||||
echo " - -my-plugin (starts with hyphen)"
|
||||
echo " - plugin- (ends with hyphen)"
|
||||
|
||||
exit 1
|
||||
fi
|
||||
445
commands/plugin-scaffold/complete-scaffold.md
Normal file
445
commands/plugin-scaffold/complete-scaffold.md
Normal file
@@ -0,0 +1,445 @@
|
||||
---
|
||||
description: Generate complete plugin structure with all necessary files in one operation
|
||||
---
|
||||
|
||||
# Complete Plugin Scaffolding
|
||||
|
||||
## Parameters
|
||||
|
||||
**Required**:
|
||||
- `name`: Plugin name in lowercase-hyphen format
|
||||
- `description`: Brief description (50-200 characters)
|
||||
- `author`: Author name or "name:email" format
|
||||
- `license`: License type (MIT|Apache-2.0|GPL-3.0|BSD-3-Clause)
|
||||
|
||||
**Optional**:
|
||||
- `category`: OpenPlugins category (default: "development")
|
||||
- `keywords`: Comma-separated keywords (default: auto-generated)
|
||||
- `version`: Initial version (default: "1.0.0")
|
||||
- `with_agent`: Include agent template (format: true|false, default: false)
|
||||
- `with_hooks`: Include hooks template (format: true|false, default: false)
|
||||
|
||||
## Workflow
|
||||
|
||||
### Step 1: Validate Parameters
|
||||
|
||||
**Plugin Name Validation**:
|
||||
- Must match pattern: `^[a-z][a-z0-9-]*$`
|
||||
- Must be lowercase with hyphens only
|
||||
- Cannot start with numbers
|
||||
- Should be descriptive and memorable
|
||||
|
||||
Execute validation script:
|
||||
```bash
|
||||
.scripts/validate-name.sh "{name}"
|
||||
```
|
||||
|
||||
**Description Validation**:
|
||||
- Length: 50-200 characters
|
||||
- Must be specific and actionable
|
||||
- Should answer "What does this do?"
|
||||
|
||||
**Author Format**:
|
||||
- Simple: "John Doe"
|
||||
- With email: "John Doe <john@example.com>"
|
||||
- Object format: handled automatically
|
||||
|
||||
### Step 2: Create Directory Structure
|
||||
|
||||
**Base Structure**:
|
||||
```bash
|
||||
mkdir -p {name}/.claude-plugin
|
||||
mkdir -p {name}/commands
|
||||
mkdir -p {name}/agents # if with_agent:true
|
||||
mkdir -p {name}/hooks # if with_hooks:true
|
||||
```
|
||||
|
||||
**Subdirectories Based on Pattern**:
|
||||
- Simple plugin: No subdirectories needed
|
||||
- Moderate plugin: May create command namespace directories
|
||||
- Complex plugin: Create skill directories with .scripts/
|
||||
|
||||
### Step 3: Generate plugin.json
|
||||
|
||||
Create `plugin.json` at the plugin root with complete metadata:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "{name}",
|
||||
"version": "{version}",
|
||||
"description": "{description}",
|
||||
"author": {
|
||||
"name": "{author_name}",
|
||||
"email": "{author_email}"
|
||||
},
|
||||
"license": "{license}",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/{username}/{name}"
|
||||
},
|
||||
"homepage": "https://github.com/{username}/{name}",
|
||||
"keywords": [{keywords}],
|
||||
"category": "{category}"
|
||||
}
|
||||
```
|
||||
|
||||
Execute metadata generation script:
|
||||
```bash
|
||||
.scripts/generate-metadata.py --name "{name}" --author "{author}" --description "{description}" --license "{license}" --category "{category}"
|
||||
```
|
||||
|
||||
### Step 4: Create README.md
|
||||
|
||||
Generate comprehensive README with sections:
|
||||
|
||||
1. **Title and Badge**
|
||||
2. **Description** (expanded from metadata)
|
||||
3. **Features** (bullet list)
|
||||
4. **Installation** (multiple methods)
|
||||
5. **Usage** (with examples)
|
||||
6. **Configuration** (if applicable)
|
||||
7. **Commands** (document each command)
|
||||
8. **Agents** (if with_agent:true)
|
||||
9. **Hooks** (if with_hooks:true)
|
||||
10. **Examples** (multiple real scenarios)
|
||||
11. **Troubleshooting**
|
||||
12. **Development** (testing, contributing)
|
||||
13. **Changelog** (link to CHANGELOG.md)
|
||||
14. **License**
|
||||
15. **Resources**
|
||||
|
||||
### Step 5: Add LICENSE File
|
||||
|
||||
Based on license parameter, add appropriate LICENSE file:
|
||||
|
||||
**MIT**:
|
||||
```
|
||||
MIT License
|
||||
|
||||
Copyright (c) {year} {author}
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy...
|
||||
```
|
||||
|
||||
**Apache-2.0**:
|
||||
```
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
...
|
||||
```
|
||||
|
||||
**GPL-3.0**:
|
||||
```
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
...
|
||||
```
|
||||
|
||||
**BSD-3-Clause**:
|
||||
```
|
||||
BSD 3-Clause License
|
||||
|
||||
Copyright (c) {year}, {author}
|
||||
...
|
||||
```
|
||||
|
||||
### Step 6: Create CHANGELOG.md
|
||||
|
||||
Initialize changelog with version 1.0.0:
|
||||
|
||||
```markdown
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [1.0.0] - {date}
|
||||
|
||||
### Added
|
||||
- Initial release
|
||||
- {feature 1}
|
||||
- {feature 2}
|
||||
```
|
||||
|
||||
### Step 7: Create .gitignore
|
||||
|
||||
Add plugin development .gitignore:
|
||||
|
||||
```
|
||||
# OS files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Editor directories
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
|
||||
# Logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
|
||||
# Environment
|
||||
.env
|
||||
.env.local
|
||||
|
||||
# Dependencies
|
||||
node_modules/
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Build outputs
|
||||
dist/
|
||||
build/
|
||||
*.egg-info/
|
||||
|
||||
# Test coverage
|
||||
coverage/
|
||||
.coverage
|
||||
.nyc_output
|
||||
|
||||
# Temporary files
|
||||
tmp/
|
||||
temp/
|
||||
*.tmp
|
||||
```
|
||||
|
||||
### Step 8: Create Template Files
|
||||
|
||||
**If with_agent:true**, create `agents/specialist.md`:
|
||||
```markdown
|
||||
---
|
||||
name: {name}-specialist
|
||||
description: Expert in {domain}. Use when users need guidance with {functionality}.
|
||||
capabilities: [capability1, capability2, capability3]
|
||||
tools: Read, Write, Bash, Grep, Glob
|
||||
model: inherit
|
||||
---
|
||||
|
||||
# {Name} Specialist Agent
|
||||
|
||||
You are an expert in {domain}. Your role is to provide guidance and automation for {functionality}.
|
||||
|
||||
## When to Invoke
|
||||
|
||||
This agent is automatically invoked when users:
|
||||
- {trigger condition 1}
|
||||
- {trigger condition 2}
|
||||
|
||||
## Approach
|
||||
|
||||
{Agent's methodology and best practices}
|
||||
```
|
||||
|
||||
**If with_hooks:true**, create `hooks/hooks.json`:
|
||||
```json
|
||||
{
|
||||
"PostToolUse": [
|
||||
{
|
||||
"matcher": "Write|Edit",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "echo 'Hook triggered after file modification'"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Create sample command** in `commands/example.md`:
|
||||
```markdown
|
||||
---
|
||||
description: Example command demonstrating plugin functionality
|
||||
---
|
||||
|
||||
# Example Command
|
||||
|
||||
This is a sample command. Replace with your actual implementation.
|
||||
|
||||
## Usage
|
||||
|
||||
/{name} [arguments]
|
||||
|
||||
## Parameters
|
||||
|
||||
- `arg1`: Description
|
||||
- `arg2`: Description (optional)
|
||||
|
||||
## Implementation
|
||||
|
||||
{Implementation instructions}
|
||||
```
|
||||
|
||||
### Step 9: Verify Structure
|
||||
|
||||
Run structure validation:
|
||||
```bash
|
||||
# Check all required files exist
|
||||
test -f {name}/plugin.json && echo "✅ plugin.json" || echo "❌ plugin.json missing"
|
||||
test -f {name}/README.md && echo "✅ README.md" || echo "✅ README.md" || echo "❌ README.md missing"
|
||||
test -f {name}/LICENSE && echo "✅ LICENSE" || echo "❌ LICENSE missing"
|
||||
test -f {name}/CHANGELOG.md && echo "✅ CHANGELOG.md" || echo "❌ CHANGELOG.md missing"
|
||||
test -d {name}/commands && echo "✅ commands/" || echo "❌ commands/ missing"
|
||||
```
|
||||
|
||||
### Step 10: Generate Success Report
|
||||
|
||||
Provide comprehensive report with:
|
||||
- Structure created confirmation
|
||||
- Files generated list
|
||||
- Next steps for development
|
||||
- Testing instructions
|
||||
- Marketplace submission readiness checklist
|
||||
|
||||
## Output Format
|
||||
|
||||
```markdown
|
||||
## ✅ Plugin Scaffolding Complete
|
||||
|
||||
### Generated Structure
|
||||
|
||||
```
|
||||
{name}/
|
||||
├── .claude-plugin/
|
||||
│ └── plugin.json ✅
|
||||
├── .gitignore ✅
|
||||
├── CHANGELOG.md ✅
|
||||
├── LICENSE ({license}) ✅
|
||||
├── README.md ✅
|
||||
├── commands/
|
||||
│ └── example.md ✅
|
||||
├── agents/ {if applicable}
|
||||
│ └── specialist.md ✅
|
||||
└── hooks/ {if applicable}
|
||||
└── hooks.json ✅
|
||||
```
|
||||
|
||||
### Files Created
|
||||
|
||||
- ✅ **plugin.json**: Complete metadata with all required fields
|
||||
- ✅ **README.md**: Comprehensive documentation template
|
||||
- ✅ **LICENSE**: {license} license file
|
||||
- ✅ **CHANGELOG.md**: Initialized with version 1.0.0
|
||||
- ✅ **.gitignore**: Plugin development exclusions
|
||||
- ✅ **commands/example.md**: Sample command template
|
||||
{Additional files if created}
|
||||
|
||||
### Metadata Summary
|
||||
|
||||
**Name**: {name}
|
||||
**Version**: {version}
|
||||
**Description**: {description}
|
||||
**Author**: {author}
|
||||
**License**: {license}
|
||||
**Category**: {category}
|
||||
**Keywords**: {keywords}
|
||||
|
||||
### Next Steps
|
||||
|
||||
1. **Implement Functionality**
|
||||
- Edit `commands/example.md` with your actual implementation
|
||||
- Add more commands as needed
|
||||
- Implement agent logic if included
|
||||
|
||||
2. **Update Documentation**
|
||||
- Customize README.md with real examples
|
||||
- Document all parameters and usage
|
||||
- Add troubleshooting section
|
||||
|
||||
3. **Local Testing**
|
||||
```bash
|
||||
# Create test marketplace
|
||||
mkdir -p test-marketplace/.claude-plugin
|
||||
# Add marketplace.json
|
||||
# Install and test plugin
|
||||
```
|
||||
|
||||
4. **Prepare for Release**
|
||||
- Update CHANGELOG.md with features
|
||||
- Verify all documentation is complete
|
||||
- Run quality checks
|
||||
- Test all functionality
|
||||
|
||||
5. **Submit to OpenPlugins**
|
||||
- Fork OpenPlugins repository
|
||||
- Add plugin entry to marketplace.json
|
||||
- Create pull request
|
||||
|
||||
### Quality Checklist
|
||||
|
||||
Before submission, ensure:
|
||||
- ✅ Plugin name follows lowercase-hyphen format
|
||||
- ✅ Description is 50-200 characters
|
||||
- ✅ All required metadata fields present
|
||||
- ✅ README has real content (no placeholders)
|
||||
- ✅ LICENSE file included
|
||||
- ✅ At least one functional command
|
||||
- ✅ No hardcoded secrets
|
||||
- ✅ Examples are concrete and realistic
|
||||
|
||||
### Testing Commands
|
||||
|
||||
```bash
|
||||
# Navigate to plugin directory
|
||||
cd {name}
|
||||
|
||||
# Validate plugin.json
|
||||
python3 -m json.tool plugin.json
|
||||
|
||||
# Check file structure
|
||||
ls -la
|
||||
|
||||
# Initialize git repository
|
||||
git init
|
||||
git add .
|
||||
git commit -m "Initial plugin structure"
|
||||
```
|
||||
|
||||
### Resources
|
||||
|
||||
- Plugin Documentation: https://docs.claude.com/en/docs/claude-code/plugins
|
||||
- OpenPlugins Guide: https://github.com/dhofheinz/open-plugins
|
||||
- Submit Plugin: Fork repository and add to marketplace.json
|
||||
|
||||
---
|
||||
|
||||
**Plugin scaffolding complete!** Your plugin is ready for implementation.
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
- **Invalid plugin name** → Show valid pattern and suggest correction
|
||||
- **Directory exists** → Ask for confirmation to overwrite or use different name
|
||||
- **Invalid license type** → List supported licenses: MIT, Apache-2.0, GPL-3.0, BSD-3-Clause
|
||||
- **Missing required parameter** → Request parameter with expected format
|
||||
- **Git not available** → Skip git initialization, provide manual instructions
|
||||
- **File creation fails** → Report specific file and error, provide recovery steps
|
||||
|
||||
## Examples
|
||||
|
||||
### Example 1: Simple Plugin
|
||||
|
||||
**Input**:
|
||||
```
|
||||
/plugin-scaffold complete name:hello-world author:"Jane Smith" license:MIT description:"Simple greeting plugin for Claude Code"
|
||||
```
|
||||
|
||||
**Output**: Complete plugin structure with all files
|
||||
|
||||
### Example 2: Plugin with Agent
|
||||
|
||||
**Input**:
|
||||
```
|
||||
/plugin-scaffold complete name:code-reviewer author:"John Doe <john@example.com>" license:Apache-2.0 description:"Automated code review with security analysis" with_agent:true category:quality
|
||||
```
|
||||
|
||||
**Output**: Plugin structure including agent template
|
||||
|
||||
**Request**: $ARGUMENTS
|
||||
58
commands/plugin-scaffold/skill.md
Normal file
58
commands/plugin-scaffold/skill.md
Normal file
@@ -0,0 +1,58 @@
|
||||
---
|
||||
description: Generate complete plugin directory structures with all necessary files and proper scaffolding
|
||||
---
|
||||
|
||||
# Plugin Scaffold Skill
|
||||
|
||||
Expert plugin structure generation with complete directory scaffolding, metadata creation, and file templates.
|
||||
|
||||
## Operations
|
||||
|
||||
- **create** - Generate complete plugin directory structure
|
||||
- **manifest** - Create or update plugin.json with validation
|
||||
- **readme** - Generate comprehensive README template
|
||||
- **license** - Add LICENSE file with selected license type
|
||||
- **complete** - All-in-one: create full plugin structure with all files
|
||||
|
||||
## Usage Examples
|
||||
|
||||
```bash
|
||||
# Generate complete structure
|
||||
/plugin-scaffold create name:my-plugin author:"John Doe"
|
||||
|
||||
# Create plugin.json
|
||||
/plugin-scaffold manifest name:my-plugin version:1.0.0 description:"Plugin description" license:MIT
|
||||
|
||||
# Generate README
|
||||
/plugin-scaffold readme name:my-plugin description:"Full description"
|
||||
|
||||
# Add license
|
||||
/plugin-scaffold license type:MIT plugin:my-plugin
|
||||
|
||||
# All-in-one scaffolding
|
||||
/plugin-scaffold complete name:my-plugin author:"John Doe" license:MIT description:"Complete plugin"
|
||||
```
|
||||
|
||||
## Router Logic
|
||||
|
||||
Parse the first word of $ARGUMENTS to determine the requested operation:
|
||||
|
||||
1. Extract operation from first word of $ARGUMENTS
|
||||
2. Parse remaining arguments as key:value parameters
|
||||
3. Route to appropriate operation file:
|
||||
- "create" → Read and execute `{plugin-path}/commands/plugin-scaffold/create-structure.md`
|
||||
- "manifest" → Read and execute `{plugin-path}/commands/plugin-scaffold/generate-manifest.md`
|
||||
- "readme" → Read and execute `{plugin-path}/commands/plugin-scaffold/create-readme.md`
|
||||
- "license" → Read and execute `{plugin-path}/commands/plugin-scaffold/add-license.md`
|
||||
- "complete" → Read and execute `{plugin-path}/commands/plugin-scaffold/complete-scaffold.md`
|
||||
|
||||
**Error Handling**:
|
||||
- If operation unknown → List available operations with usage
|
||||
- If required parameters missing → Request with expected format
|
||||
- If plugin name invalid → Suggest valid naming pattern (lowercase-hyphen)
|
||||
- If directory exists → Warn and ask for confirmation to overwrite
|
||||
|
||||
**Base directory**: Plugin commands directory
|
||||
**Current request**: $ARGUMENTS
|
||||
|
||||
Parse operation and route to appropriate instruction file now.
|
||||
Reference in New Issue
Block a user