Initial commit

This commit is contained in:
Zhongwei Li
2025-11-29 18:28:02 +08:00
commit 4ea8c8d0b0
15 changed files with 4003 additions and 0 deletions

View File

@@ -0,0 +1,21 @@
{
"name": "claude-plugin",
"description": "Plugin management and scaffolding tools for creating and maintaining Claude Code plugins",
"version": "1.0.0",
"author": {
"name": "Geoff Johnson",
"url": "https://github.com/geoffjay"
},
"skills": [
"./skills/marketplace-update",
"./skills/documentation-update"
],
"agents": [
"./agents/plugin-architect.md"
],
"commands": [
"./commands/create.md",
"./commands/update.md",
"./commands/documentation.md"
]
}

3
README.md Normal file
View File

@@ -0,0 +1,3 @@
# claude-plugin
Plugin management and scaffolding tools for creating and maintaining Claude Code plugins

345
agents/plugin-architect.md Normal file
View File

@@ -0,0 +1,345 @@
---
name: plugin-architect
description: Expert agent for designing and implementing Claude Code plugins following granular, composable architecture principles
model: claude-sonnet-4
subagent_type: claude-plugin
---
# Plugin Architect Agent
You are an expert plugin architect specializing in designing and implementing Claude Code plugins that follow granular, composable architecture principles. Your role is to help users create focused, single-purpose plugins that integrate seamlessly into the Claude Code ecosystem.
## Purpose
Design and implement well-structured Claude Code plugins that:
- Follow the single responsibility principle (one plugin does one thing well)
- Maintain composability with other plugins
- Optimize for context efficiency and minimal token usage
- Comply with Anthropic's Agent Skills Specification
- Use progressive disclosure patterns for skills
## Core Philosophy
### Single Responsibility
- Each plugin focuses on one domain or use case
- Clear, focused purposes describable in 5-10 words
- No bloated or multi-purpose plugins
- Average 3-4 components per plugin (agents, commands, skills)
### Composability Over Bundling
- Design plugins to work independently or together
- Clear boundaries between plugin functionality
- No forced feature bundling
- Enable workflow orchestrators to compose multiple plugins
### Context Efficiency
- Smaller, focused components for faster LLM processing
- Better fit in context windows
- Progressive disclosure for skills (metadata → instructions → resources)
- Load only what's needed when it's needed
### Quality Standards
- Clear hyphen-case naming conventions
- Complete YAML frontmatter in all files
- Comprehensive documentation (what, when, how)
- Spec-compliant with Anthropic guidelines
## Model Selection Guidance
When designing agents within plugins, recommend appropriate models:
**Use Haiku for:**
- Code generation from well-defined specifications
- Test creation following established patterns
- Documentation with clear templates
- Infrastructure operations
- Deployment pipelines
- Deterministic, repeatable tasks
**Use Sonnet for:**
- System architecture design
- Technology selection decisions
- Security audits and reviews
- Complex reasoning tasks
- Language-specific expertise
- Multi-agent workflow orchestration
- Business-critical decisions
## Plugin Structure
Every plugin must contain at least one agent OR one command, with optional skills:
```
plugins/{plugin-name}/
├── agents/ # Specialized domain experts (optional)
│ └── {agent-name}.md
├── commands/ # Tools and workflows (optional)
│ └── {command-name}.md
└── skills/ # Modular knowledge packages (optional)
└── {skill-name}/
├── SKILL.md
├── assets/
└── references/
```
## Agent File Structure
Location: `plugins/{plugin-name}/agents/{agent-name}.md`
Required frontmatter:
```yaml
---
name: agent-name
description: Clear description of agent's purpose
model: claude-haiku-4|claude-sonnet-4
---
```
Content sections (recommended):
1. **Purpose** - What the agent does and why it exists
2. **Core Capabilities** - Key functionality and expertise
3. **Guidelines** - How the agent should operate
4. **Examples** - Common use cases and patterns
5. **Constraints** - Limitations and boundaries
## Command File Structure
Location: `plugins/{plugin-name}/commands/{command-name}.md`
Commands should:
- Accept and use `$ARGUMENTS` for dynamic inputs
- Include clear documentation of expected arguments
- Invoke agents using: `Use Task tool with subagent_type="{plugin-name}"`
- Provide helpful prompts when arguments are missing
- Follow clear workflow patterns
Example command structure:
```markdown
---
name: command-name
description: What the command does
---
# Command Name
This command [does something specific].
## Arguments
- `$1` - First argument description
- `$2` - Second argument description (optional)
## Usage
[Instructions for using the command]
## Workflow
1. Step one
2. Step two
3. Use Task tool with subagent_type="{plugin-name}"
```
## Skill File Structure
Location: `plugins/{plugin-name}/skills/{skill-name}/SKILL.md`
Required frontmatter (must be under 1024 characters):
```yaml
---
name: skill-name
description: What the skill does. Use when [trigger criteria].
---
```
Skills should follow progressive disclosure:
1. **Metadata** (frontmatter) - Always loaded
2. **Instructions** - Core guidance loaded when activated
3. **Resources** (assets/) - Loaded on demand
Additional skill components:
- `assets/` - Templates, configurations, code examples
- `references/` - Additional documentation and examples
## Example Uses
### Creating a New Language Plugin
When a user wants to create a plugin for a specific programming language (e.g., Rust, Python, Go):
1. **Analyze Requirements**
- Identify the language-specific needs
- Determine if agents, commands, or skills are needed
- Plan the component structure
2. **Design Agents**
- Create language expert agent (Sonnet for complex reasoning)
- Consider framework-specific agents if needed
- Define clear expertise boundaries
3. **Create Commands**
- Project scaffolding commands
- Code generation utilities
- Test creation automation
4. **Build Skills**
- Language patterns and idioms
- Framework-specific knowledge
- Best practices and conventions
### Creating a Workflow Orchestrator Plugin
When a user needs multi-agent coordination:
1. **Identify Workflow Steps**
- Map out the complete workflow
- Identify which plugins/agents are needed
- Define coordination strategy
2. **Design Orchestration Command**
- Create command that invokes multiple agents
- Handle sequential and parallel execution
- Manage state between agents
3. **Document Dependencies**
- List required plugins
- Document expected inputs/outputs
- Provide usage examples
### Creating a Tool Plugin
When a user needs specific functionality (security scanning, testing, etc.):
1. **Define Tool Scope**
- Single, focused purpose
- Clear input/output contracts
- Integration points with other plugins
2. **Choose Model Appropriately**
- Haiku for deterministic operations
- Sonnet for analysis and decision-making
3. **Provide Clear Documentation**
- Usage examples
- Expected behavior
- Error handling
## Best Practices
### Naming Conventions
- Use hyphen-case for all names
- Be descriptive but concise
- Follow pattern: `{domain}-{purpose}`
- Examples: `golang-development`, `security-scanning`, `test-automation`
### Documentation
- Always include frontmatter with name and description
- Provide clear examples
- Document all arguments and parameters
- Explain when to use the component
### Plugin Updates
- Maintain backward compatibility
- Use semantic versioning
- Document breaking changes
- Provide migration guides
### Quality Checklist
- [ ] Clear, descriptive name in hyphen-case
- [ ] Complete YAML frontmatter
- [ ] Focused single responsibility
- [ ] Appropriate model selection
- [ ] Comprehensive documentation
- [ ] Usage examples included
- [ ] Spec compliance verified
- [ ] Tested functionality
## Workflow
When helping users create or update plugins:
1. **Understand Requirements**
- Ask clarifying questions about the plugin's purpose
- Identify whether agents, commands, or skills are needed
- Determine appropriate model selection
2. **Plan Structure**
- Propose plugin directory structure
- Recommend component breakdown
- Suggest naming conventions
3. **Generate Components**
- Create agent files with proper frontmatter
- Write command files with argument handling
- Build skill files with progressive disclosure
4. **Update Marketplace**
- Add plugin entry to `.claude-plugin/marketplace.json`
- Update documentation files using skills
5. **Validate**
- Verify frontmatter compliance
- Check naming conventions
- Ensure documentation completeness
- Test functionality
## Integration with Skills
Use the following skills when performing plugin operations:
- **marketplace-update** - Update `.claude-plugin/marketplace.json` when adding or modifying plugins
- **documentation-update** - Update documentation files (agent-skills.md, agents.md, plugins.md, usage.md)
Always invoke these skills after creating or updating plugins to maintain consistency across the repository.
## Error Handling
When issues arise:
- Provide clear, actionable error messages
- Suggest corrections based on spec compliance
- Validate frontmatter format
- Check for naming convention violations
- Verify file structure correctness
## Success Criteria
A well-designed plugin should:
- ✓ Have a clear, single purpose
- ✓ Use appropriate model for the task
- ✓ Include complete frontmatter
- ✓ Follow naming conventions
- ✓ Be properly documented
- ✓ Have marketplace entry
- ✓ Update relevant documentation
- ✓ Work independently or composably with others

275
commands/create.md Normal file
View File

@@ -0,0 +1,275 @@
---
name: claude-plugin:create
description: Create a new Claude Code plugin with agents, commands, and/or skills
---
# Create Plugin Command
Create a new Claude Code plugin following granular, composable architecture principles.
## Arguments
- `$1` - Plugin name (required, hyphen-case format)
- `$2` - Plugin description (required)
- `$3` - Components to create: `agents`, `commands`, `skills`, or combinations like `agents,commands` (optional, defaults to prompting)
- `$4` - Additional configuration as JSON (optional)
## Usage
```bash
# Basic usage - will prompt for details
/claude-plugin:create my-plugin-name "Plugin description"
# Specify components
/claude-plugin:create my-plugin-name "Plugin description" agents,commands
# Full configuration
/claude-plugin:create golang-advanced "Advanced Go development tools" agents,commands,skills '{"category":"languages","model":"claude-sonnet-4"}'
```
## Workflow
This command orchestrates plugin creation by:
1. **Validating Input**
- Verify plugin name follows hyphen-case convention
- Ensure plugin doesn't already exist
- Validate component specifications
2. **Gathering Requirements**
- If components not specified, ask user what to create
- Request additional details about agents (names, purposes, models)
- Request command details (names, purposes, workflows)
- Request skill details (names, triggers, content structure)
3. **Creating Plugin Structure**
- Create plugin directory: `plugins/$PLUGIN_NAME/`
- Create component directories as needed
- Set up skill subdirectories (SKILL.md, assets/, references/)
4. **Generating Components**
- Use Task tool with subagent_type="claude-plugin" to design and implement components
- Create agent files with proper frontmatter
- Create command files with argument handling
- Create skill files with progressive disclosure
5. **Updating Marketplace**
- Invoke marketplace-update skill to add plugin entry
- Invoke documentation-update skill to update docs
---
## Implementation
**Plugin Name:** ${1:-"[REQUIRED]"}
**Description:** ${2:-"[REQUIRED]"}
**Components:** ${3:-"[PROMPT USER]"}
**Configuration:** ${4:-"{}"}
### Step 1: Validate Plugin Name
The plugin name must:
- Be in hyphen-case format (e.g., `my-plugin-name`)
- Not already exist in `plugins/` directory
- Be descriptive and focused on a single purpose
### Step 2: Determine Components
If components are not specified in `$3`, ask the user:
**"What components should this plugin include?"**
Options:
- **Agents** - Specialized domain experts with deep knowledge
- **Commands** - Tools and workflow automation
- **Skills** - Modular knowledge packages with progressive disclosure
The plugin must have at least one agent OR one command.
### Step 3: Gather Component Details
For each component type selected:
#### Agents
- Agent name (hyphen-case)
- Agent purpose and description
- Recommended model (haiku for deterministic tasks, sonnet for complex reasoning)
- Key capabilities
- Example use cases
#### Commands
- Command name (hyphen-case)
- Command purpose and description
- Expected arguments
- Workflow steps
- Integration points
#### Skills
- Skill name (hyphen-case)
- Skill description with "Use when" trigger
- Progressive disclosure structure
- Required assets (templates, examples)
- Reference documentation needs
### Step 4: Invoke Plugin Architect
Use Task tool with subagent_type="claude-plugin" to design and implement the plugin:
```
I need to create a new plugin called "$PLUGIN_NAME" with the following specifications:
Description: $PLUGIN_DESCRIPTION
Components: $COMPONENTS
Details: [collected from user]
Please design and implement this plugin following the architecture principles:
- Single responsibility
- Composability
- Context efficiency
- Spec compliance
Create all necessary files with proper frontmatter, documentation, and examples.
```
### Step 5: Update Repository
After plugin creation:
1. **Update Marketplace**
Invoke the marketplace-update skill by running the Python script:
```bash
python plugins/claude-plugin/skills/marketplace-update/marketplace_update.py add \
--name "$PLUGIN_NAME" \
--description "$PLUGIN_DESCRIPTION" \
--version "1.0.0" \
--category "$CATEGORY" \
--agents "$(ls plugins/$PLUGIN_NAME/agents/*.md 2>/dev/null | xargs -n1 basename | tr '\n' ',')" \
--commands "$(ls plugins/$PLUGIN_NAME/commands/*.md 2>/dev/null | xargs -n1 basename | tr '\n' ',')" \
--skills "$(ls -d plugins/$PLUGIN_NAME/skills/*/ 2>/dev/null | xargs -n1 basename | tr '\n' ',')"
```
2. **Update Documentation**
Invoke the documentation-update skill by running the Python script:
```bash
python plugins/claude-plugin/skills/documentation-update/doc_generator.py
```
This regenerates:
- `docs/agents.md` - Agent reference
- `docs/agent-skills.md` - Skills catalog
- `docs/plugins.md` - Plugin directory
- `docs/usage.md` - Usage guide
3. **Verify Structure**
- Check all files have proper frontmatter
- Verify naming conventions
- Ensure documentation is complete
- Confirm marketplace.json is valid
- Verify all documentation files were regenerated
### Step 6: Confirm Success
Report to the user:
- ✓ Plugin created at `plugins/$PLUGIN_NAME/`
- ✓ Components created: [list]
- ✓ Marketplace updated
- ✓ Documentation updated
- Next steps or usage instructions
## Examples
### Example 1: Create Language Plugin
```bash
/claude-plugin:create rust-development "Rust language development tools" agents,commands,skills
```
This would:
- Create `plugins/rust-development/`
- Prompt for agent details (e.g., rust-pro agent)
- Prompt for command details (e.g., rust-scaffold command)
- Prompt for skill details (e.g., rust-patterns skill)
- Generate all components with proper structure
- Update marketplace and documentation
### Example 2: Create Security Plugin
```bash
/claude-plugin:create security-scanning "Security vulnerability scanning and analysis" agents,commands
```
This would:
- Create `plugins/security-scanning/`
- Prompt for security agent details
- Prompt for scanning command details
- Generate components without skills
- Update marketplace and documentation
### Example 3: Create Minimal Plugin
```bash
/claude-plugin:create test-helper "Test generation helper utilities" commands
```
This would:
- Create `plugins/test-helper/`
- Prompt for command details only
- Generate command file
- Update marketplace and documentation
## Error Handling
Common issues and resolutions:
### Plugin Already Exists
If `plugins/$PLUGIN_NAME/` exists:
- Error: "Plugin '$PLUGIN_NAME' already exists. Use /claude-plugin:update to modify existing plugins."
- Suggest using `/claude-plugin:update` command instead
### Invalid Plugin Name
If plugin name is not hyphen-case:
- Error: "Plugin name must be in hyphen-case format (e.g., 'my-plugin-name')"
- Suggest correct format
### No Components Specified
If user doesn't specify components and doesn't respond to prompts:
- Error: "At least one component (agent or command) is required"
- Prompt again with clear options
### Missing Required Arguments
If `$1` or `$2` are not provided:
- Error: "Usage: /claude-plugin:create <plugin-name> <description> [components] [config]"
- Show examples
## Notes
- This command creates new plugins only. Use `/claude-plugin:update` to modify existing plugins.
- All generated files will include proper YAML frontmatter
- The plugin-architect agent ensures adherence to architecture principles
- Skills are invoked automatically for marketplace and documentation updates
- Generated code follows best practices and spec compliance

659
commands/documentation.md Normal file
View File

@@ -0,0 +1,659 @@
---
name: claude-plugin:documentation
description: Regenerate all documentation files from marketplace data and plugin metadata
---
# Documentation Generation Command
Regenerate all documentation files (agents.md, agent-skills.md, plugins.md, usage.md) from the marketplace catalog and plugin metadata using Jinja2 templates.
## Arguments
- `$1` - Specific file to generate: `agents`, `agent-skills`, `plugins`, `usage`, or `all` (optional, defaults to `all`)
- `$2` - Additional options as JSON (optional)
## Usage
```bash
# Regenerate all documentation files
/claude-plugin:documentation
# Regenerate specific file
/claude-plugin:documentation agents
# Dry run to preview changes
/claude-plugin:documentation all '{"dry_run": true}'
# Specify custom paths
/claude-plugin:documentation all '{"marketplace": ".claude-plugins/marketplace.json", "output": "docs"}'
```
## Workflow
This command orchestrates documentation generation by:
1. **Validating Prerequisites**
- Verify marketplace.json exists and is valid
- Check template files exist in documentation-update skill
- Ensure plugin directories are accessible
- Verify output directory exists or can be created
2. **Preparing Context**
- Load marketplace catalog
- Scan all plugin directories
- Extract agent/command/skill metadata
- Build component indexes
- Calculate statistics
3. **Generating Documentation**
- Invoke documentation-update skill
- Render Jinja2 templates with context
- Write output to docs/ directory
- Report any warnings or errors
4. **Verifying Output**
- Check all requested files were generated
- Verify file formatting and structure
- Validate links and references
- Report success and statistics
---
## Implementation
**Target File:** ${1:-"all"}
**Options:** ${2:-"{}"}
### Step 1: Validate Prerequisites
Check that all required components exist:
```bash
# Check marketplace exists
if [ ! -f .claude-plugins/marketplace.json ]; then
echo "Error: Marketplace file not found at .claude-plugins/marketplace.json"
exit 1
fi
# Check skill exists
if [ ! -f plugins/claude-plugin/skills/documentation-update/doc_generator.py ]; then
echo "Error: Documentation update skill not found"
exit 1
fi
# Check templates exist
if [ ! -d plugins/claude-plugin/skills/documentation-update/assets ]; then
echo "Error: Template directory not found"
exit 1
fi
# Create docs directory if needed
mkdir -p docs
```
### Step 2: Parse Options
Extract configuration from `$2` JSON parameter:
- `dry_run`: Preview output without writing files
- `marketplace`: Custom path to marketplace.json
- `templates`: Custom path to template directory
- `output`: Custom output directory
- `verbose`: Show detailed progress
### Step 3: Invoke Documentation Update Skill
Run the documentation generation script:
```bash
# Build command with options
PYTHON_CMD="python plugins/claude-plugin/skills/documentation-update/doc_generator.py"
# Add file filter if specified
if [ "$TARGET_FILE" != "all" ]; then
PYTHON_CMD="$PYTHON_CMD --file $TARGET_FILE"
fi
# Add custom paths if provided
if [ -n "$MARKETPLACE_PATH" ]; then
PYTHON_CMD="$PYTHON_CMD --marketplace $MARKETPLACE_PATH"
fi
if [ -n "$TEMPLATES_PATH" ]; then
PYTHON_CMD="$PYTHON_CMD --templates $TEMPLATES_PATH"
fi
if [ -n "$OUTPUT_PATH" ]; then
PYTHON_CMD="$PYTHON_CMD --output $OUTPUT_PATH"
fi
# Add dry-run flag if requested
if [ "$DRY_RUN" = "true" ]; then
PYTHON_CMD="$PYTHON_CMD --dry-run"
fi
# Add verbose flag if requested
if [ "$VERBOSE" = "true" ]; then
PYTHON_CMD="$PYTHON_CMD --verbose"
fi
# Execute command
echo "Generating documentation..."
eval $PYTHON_CMD
```
### Step 4: Report Results
After successful generation:
```
✓ Documentation generation completed
Files generated:
- docs/agents.md (25 agents across 10 plugins)
- docs/agent-skills.md (30 skills with progressive disclosure)
- docs/plugins.md (10 plugins in 4 categories)
- docs/usage.md (Usage guide and examples)
Statistics:
- Total plugins: 10
- Total agents: 25
- Total commands: 15
- Total skills: 30
All documentation files are now synchronized with the marketplace catalog.
```
If errors occurred:
```
❌ Documentation generation failed
Errors encountered:
- Template not found: assets/agents.md.j2
- Invalid frontmatter in plugins/example/agents/test.md
Please fix the errors above and run the command again.
```
## Examples
### Example 1: Full Documentation Update
```bash
/claude-plugin:documentation
```
**Output:**
```
Generating documentation...
✓ Loading marketplace.json
✓ Scanning plugin directories
✓ Extracting metadata from 10 plugins
✓ Building component indexes
✓ Rendering templates
✓ Writing docs/agents.md
✓ Writing docs/agent-skills.md
✓ Writing docs/plugins.md
✓ Writing docs/usage.md
Documentation generation completed successfully.
```
### Example 2: Generate Single File
```bash
/claude-plugin:documentation agents
```
**Output:**
```
Generating documentation...
✓ Loading marketplace.json
✓ Scanning plugin directories
✓ Extracting agent metadata
✓ Rendering agents.md.j2 template
✓ Writing docs/agents.md
Generated docs/agents.md with 25 agents.
```
### Example 3: Dry Run
```bash
/claude-plugin:documentation all '{"dry_run": true}'
```
**Output:**
```
Dry run mode - no files will be written
Preview of docs/agents.md:
===========================
# Agent Reference
This document lists all agents available across plugins in the marketplace.
## Languages
### rust-development
...
Preview of docs/agent-skills.md:
=================================
...
Dry run completed. Run without --dry-run to write files.
```
### Example 4: Custom Paths
```bash
/claude-plugin:documentation all '{"marketplace": "custom/marketplace.json", "output": "generated-docs"}'
```
**Output:**
```
Generating documentation...
✓ Loading custom/marketplace.json
✓ Using default templates
✓ Output directory: generated-docs
✓ Generating all documentation files
✓ Writing generated-docs/agents.md
✓ Writing generated-docs/agent-skills.md
✓ Writing generated-docs/plugins.md
✓ Writing generated-docs/usage.md
Documentation generation completed successfully.
```
## Generated Files
This command generates the following documentation files:
### 1. docs/agents.md
**Purpose:** Complete reference of all agents across all plugins
**Contents:**
- Agents organized by plugin and category
- Agent name, description, and model
- Links to agent files
- Agent capabilities and use cases
- Statistics on total agents
**Example Structure:**
```markdown
# Agent Reference
## Languages
### rust-development
**Agents:**
- **rust-pro** (`claude-sonnet-4`)
- Master Rust 1.75+ with modern async patterns...
- File: `plugins/rust-development/agents/rust-pro.md`
```
### 2. docs/agent-skills.md
**Purpose:** Catalog of all skills with progressive disclosure details
**Contents:**
- Skills organized by plugin
- Skill name and description
- "Use when" triggers
- Skill structure and location
- Statistics on total skills
**Example Structure:**
```markdown
# Agent Skills Reference
## Plugin Management
### claude-plugin
**Skills:**
#### documentation-update
Regenerates documentation files from marketplace data using Jinja templates. Use when plugins are added, updated, or removed.
- **Location:** `plugins/claude-plugin/skills/documentation-update/`
- **Structure:** SKILL.md + assets/ + references/
```
### 3. docs/plugins.md
**Purpose:** Directory of all plugins in the marketplace
**Contents:**
- Plugins organized by category
- Plugin name, description, and version
- List of components (agents, commands, skills)
- Installation and usage information
- Statistics on total plugins
**Example Structure:**
```markdown
# Plugin Directory
## Plugin Management
### claude-plugin (v1.0.0)
Plugin management and scaffolding tools.
**Components:**
- Agents: plugin-architect
- Commands: create, update, documentation
- Skills: marketplace-update, documentation-update
**Installation:** Available by default
```
### 4. docs/usage.md
**Purpose:** Usage guide and command reference
**Contents:**
- Getting started instructions
- Command usage examples
- Workflow patterns
- Integration guides
- Best practices
**Example Structure:**
```markdown
# Usage Guide
## Getting Started
This marketplace provides Claude Code plugins following a granular, composable architecture...
## Creating Plugins
Use the `/claude-plugin:create` command to create new plugins:
\`\`\`bash
/claude-plugin:create my-plugin "Plugin description"
\`\`\`
## Updating Documentation
After making changes to plugins, regenerate documentation:
\`\`\`bash
/claude-plugin:documentation
\`\`\`
```
## Integration with Other Commands
This command is automatically invoked by:
### /claude-plugin:create
After creating a new plugin:
```
✓ Plugin created at plugins/my-plugin/
✓ Marketplace updated
⏳ Updating documentation...
✓ Documentation updated
```
### /claude-plugin:update
After updating an existing plugin:
```
✓ Plugin updated at plugins/my-plugin/
✓ Marketplace updated
⏳ Updating documentation...
✓ Documentation updated
```
### Manual Invocation
Users can also run this command manually:
- After editing plugin files directly
- To refresh documentation after git pull
- To verify documentation is up to date
- To preview changes with dry-run
## Error Handling
Common issues and resolutions:
### Marketplace Not Found
```
Error: Marketplace file not found at .claude-plugins/marketplace.json
Suggestion:
- Verify you're in the repository root
- Check that .claude-plugins/marketplace.json exists
- Run /claude-plugin:create to create your first plugin
```
### Template Not Found
```
Error: Template file not found: assets/agents.md.j2
Suggestion:
- Verify claude-plugin plugin is properly installed
- Check that all template files exist in:
plugins/claude-plugin/skills/documentation-update/assets/
- Reinstall the claude-plugin plugin if needed
```
### Invalid Frontmatter
```
Warning: Could not parse frontmatter in plugins/my-plugin/agents/my-agent.md
Suggestion:
- Check YAML frontmatter syntax in the agent file
- Ensure frontmatter is enclosed in --- markers
- Verify required fields: name, description
- Fix syntax errors and run command again
```
### Missing Plugin Directory
```
Warning: Plugin 'my-plugin' in marketplace.json but directory not found
Suggestion:
- Verify plugins/my-plugin/ directory exists
- Remove stale entry from marketplace.json
- Recreate plugin if it was accidentally deleted
```
### Permission Denied
```
Error: Permission denied writing to docs/agents.md
Suggestion:
- Check write permissions on docs/ directory
- Ensure docs/ directory is not read-only
- Run with appropriate permissions
```
### Python Not Found
```
Error: python command not found
Suggestion:
- Install Python 3.8 or later
- Ensure python is in your PATH
- Try using python3 instead of python
```
## Template System
The documentation generation uses Jinja2 templates located in:
```
plugins/claude-plugin/skills/documentation-update/assets/
├── agents.md.j2
├── agent-skills.md.j2
├── plugins.md.j2
└── usage.md.j2
```
### Template Context
All templates receive the following context:
```python
{
"marketplace": {
"name": "marketplace-name",
"owner": {...},
"metadata": {...},
"plugins": [...]
},
"plugins_by_category": {
"category-name": [plugin1, plugin2, ...]
},
"all_agents": [...],
"all_skills": [...],
"all_commands": [...],
"stats": {
"total_plugins": 10,
"total_agents": 25,
"total_commands": 15,
"total_skills": 30
},
"now": "2025-10-17"
}
```
### Customizing Templates
To customize documentation output:
1. **Edit Existing Templates**
- Modify templates in assets/ directory
- Use Jinja2 syntax for dynamic content
- Test with dry-run before committing
2. **Add New Templates**
- Create new template file in assets/
- Update doc_generator.py to render new template
- Define output path for new file
3. **Test Changes**
- Run with --dry-run to preview
- Verify formatting and structure
- Check for template errors
## Best Practices
1. **Run After Every Plugin Change**
- Documentation should always reflect current state
- Commit documentation with plugin changes
- Include in pull request reviews
2. **Use Dry Run for Testing**
- Preview changes before writing
- Test template modifications
- Verify output structure
3. **Keep Templates Simple**
- Use clear Jinja2 syntax
- Document template variables
- Handle missing data gracefully
4. **Validate Output**
- Check generated files for correctness
- Verify all links work
- Test formatting renders properly
5. **Version Control**
- Commit documentation changes
- Include meaningful commit messages
- Tag major documentation updates
## Success Criteria
After running this command:
- ✓ All requested documentation files generated
- ✓ Content matches marketplace state
- ✓ All links are valid and correct
- ✓ Formatting is consistent
- ✓ Statistics are accurate
- ✓ No template rendering errors
- ✓ All plugins represented
- ✓ Metadata correctly extracted
## Troubleshooting
### Templates Not Rendering
**Problem:** Templates fail to render with Jinja2 errors
**Solutions:**
- Check Jinja2 syntax in templates
- Verify all variables are defined
- Use default filters for optional values
- Test templates with minimal data first
### Missing Component Data
**Problem:** Some agents/commands/skills not appearing in docs
**Solutions:**
- Verify frontmatter exists and is valid
- Check file naming follows conventions
- Ensure files have correct extensions (.md)
- Verify plugin directory structure
### Outdated Documentation
**Problem:** Documentation doesn't match current plugin state
**Solutions:**
- Run this command to regenerate
- Check marketplace.json is up to date
- Verify all plugin files exist
- Look for stale cache or old files
### Performance Issues
**Problem:** Generation takes too long with many plugins
**Solutions:**
- Use --file option to generate single files
- Optimize template complexity
- Consider caching marketplace data
- Profile doc_generator.py for bottlenecks
## Related Commands
- `/claude-plugin:create` - Create new plugin (auto-generates docs)
- `/claude-plugin:update` - Update existing plugin (auto-generates docs)
## Related Skills
- `marketplace-update` - Update marketplace.json catalog
- `documentation-update` - The skill this command invokes
## Notes
- This command is idempotent - safe to run multiple times
- Generated files should be committed to version control
- Templates use Python's built-in string formatting (no external dependencies)
- The command will create the docs/ directory if it doesn't exist
- Existing documentation files are overwritten without backup
- The documentation-update skill has no external dependencies

430
commands/update.md Normal file
View File

@@ -0,0 +1,430 @@
---
name: claude-plugin:update
description: Update an existing Claude Code plugin by adding, modifying, or removing components
---
# Update Plugin Command
Update an existing Claude Code plugin by adding new components, modifying existing ones, or removing obsolete components.
## Arguments
- `$1` - Plugin name (required, must exist in plugins/)
- `$2` - Update operation: `add`, `modify`, or `remove` (required)
- `$3` - Component type: `agent`, `command`, or `skill` (required)
- `$4` - Component name (required for modify/remove, optional for add)
- `$5` - Additional configuration as JSON (optional)
## Usage
```bash
# Add a new agent to existing plugin
/claude-plugin:update golang-development add agent golang-testing
# Modify an existing command
/claude-plugin:update golang-development modify command golang-scaffold
# Remove a skill
/claude-plugin:update golang-development remove skill golang-patterns
# Add with configuration
/claude-plugin:update rust-development add agent rust-async '{"model":"claude-sonnet-4","description":"Async Rust expert"}'
```
## Workflow
This command orchestrates plugin updates by:
1. **Validating Input**
- Verify plugin exists in `plugins/` directory
- Validate operation type (add/modify/remove)
- Ensure component type is valid
- Check component existence for modify/remove operations
2. **Gathering Requirements**
- For **add**: collect new component details
- For **modify**: identify what needs to change
- For **remove**: confirm removal and check dependencies
3. **Performing Update**
- Use Task tool with subagent_type="claude-plugin" to execute changes
- Create, modify, or remove component files
- Maintain spec compliance and naming conventions
4. **Updating Marketplace**
- Invoke marketplace-update skill to update plugin entry
- Invoke documentation-update skill to regenerate docs
---
## Implementation
**Plugin Name:** ${1:-"[REQUIRED]"}
**Operation:** ${2:-"[REQUIRED: add|modify|remove]"}
**Component Type:** ${3:-"[REQUIRED: agent|command|skill]"}
**Component Name:** ${4:-"[REQUIRED for modify/remove]"}
**Configuration:** ${5:-"{}"}
### Step 1: Validate Plugin Exists
Check that `plugins/$PLUGIN_NAME/` exists:
- If not found: Error "Plugin '$PLUGIN_NAME' not found. Use /create to create new plugins."
- If found: Continue to operation validation
### Step 2: Validate Operation
Based on `$2` operation type:
#### Add Operation
- Create new component in existing plugin
- Component name can be provided in `$4` or prompted
- Gather full component specifications
#### Modify Operation
- Update existing component
- Component name must be provided in `$4`
- Verify component file exists
- Ask what needs to be changed
#### Remove Operation
- Delete existing component
- Component name must be provided in `$4`
- Verify component file exists
- Confirm removal with user
- Check for dependencies
### Step 3: Execute Operation
Use Task tool with subagent_type="claude-plugin" to perform the update:
#### For Add Operation
```
I need to add a new $COMPONENT_TYPE to the "$PLUGIN_NAME" plugin:
Component Name: $COMPONENT_NAME
Component Type: $COMPONENT_TYPE
Configuration: $CONFIGURATION
Please design and implement this component following architecture principles:
- Single responsibility
- Spec compliance
- Proper frontmatter
- Complete documentation
Integrate it with the existing plugin structure.
```
#### For Modify Operation
```
I need to modify the $COMPONENT_TYPE named "$COMPONENT_NAME" in the "$PLUGIN_NAME" plugin:
Changes Requested: [gathered from user]
Configuration: $CONFIGURATION
Please update the component while:
- Maintaining backward compatibility
- Following spec compliance
- Updating documentation
- Preserving existing functionality where appropriate
```
#### For Remove Operation
```
I need to remove the $COMPONENT_TYPE named "$COMPONENT_NAME" from the "$PLUGIN_NAME" plugin:
Reason: [gathered from user if needed]
Please:
- Remove the component file
- Check for and warn about any dependencies
- Update plugin structure
- Clean up any orphaned assets
```
### Step 4: Update Repository
After component update:
1. **Update Marketplace**
Invoke the marketplace-update skill by running the appropriate Python command:
**For Add Operation:**
```bash
python plugins/claude-plugin/skills/marketplace-update/marketplace_update.py update \
--name "$PLUGIN_NAME" \
--add-agent "$COMPONENT_NAME.md" # if adding agent
--add-command "$COMPONENT_NAME.md" # if adding command
--add-skill "$COMPONENT_NAME" # if adding skill
```
**For Remove Operation:**
```bash
python plugins/claude-plugin/skills/marketplace-update/marketplace_update.py update \
--name "$PLUGIN_NAME" \
--remove-agent "$COMPONENT_NAME.md" # if removing agent
--remove-command "$COMPONENT_NAME.md" # if removing command
--remove-skill "$COMPONENT_NAME" # if removing skill
```
**For Modify Operation (version update):**
```bash
python plugins/claude-plugin/skills/marketplace-update/marketplace_update.py update \
--name "$PLUGIN_NAME" \
--version "1.0.1" # or appropriate version bump
```
2. **Update Documentation**
Invoke the documentation-update skill by running the Python script:
```bash
python plugins/claude-plugin/skills/documentation-update/doc_generator.py
```
This regenerates all documentation files to reflect the changes.
3. **Verify Integrity**
- Check plugin still has at least one agent or command
- Verify all references are valid
- Ensure frontmatter is correct
- Confirm marketplace.json is valid
- Verify documentation was regenerated
### Step 5: Confirm Success
Report to the user:
- ✓ Operation completed: [$OPERATION $COMPONENT_TYPE $COMPONENT_NAME]
- ✓ Plugin updated at `plugins/$PLUGIN_NAME/`
- ✓ Marketplace updated
- ✓ Documentation updated
- ✓ Current plugin structure: [list components]
## Operation Details
### Add Operation
When adding a new component:
**For Agents:**
- Prompt for agent name (hyphen-case)
- Prompt for purpose and description
- Prompt for model selection (haiku/sonnet)
- Prompt for capabilities and guidelines
- Create `plugins/$PLUGIN_NAME/agents/$AGENT_NAME.md`
**For Commands:**
- Prompt for command name (hyphen-case)
- Prompt for purpose and description
- Prompt for arguments and workflow
- Create `plugins/$PLUGIN_NAME/commands/$COMMAND_NAME.md`
**For Skills:**
- Prompt for skill name (hyphen-case)
- Prompt for description with "Use when" trigger
- Prompt for asset requirements
- Create skill directory structure:
- `plugins/$PLUGIN_NAME/skills/$SKILL_NAME/SKILL.md`
- `plugins/$PLUGIN_NAME/skills/$SKILL_NAME/assets/`
- `plugins/$PLUGIN_NAME/skills/$SKILL_NAME/references/`
### Modify Operation
When modifying an existing component:
1. **Read Current Component**
- Load existing file
- Parse frontmatter and content
- Show current structure to user
2. **Identify Changes**
- Ask user what needs to change:
- Update description
- Change model (agents only)
- Modify workflow
- Update examples
- Add/remove sections
3. **Apply Changes**
- Update file maintaining structure
- Preserve frontmatter format
- Update version if significant changes
4. **Validate**
- Ensure spec compliance
- Verify frontmatter is valid
- Check documentation completeness
### Remove Operation
When removing a component:
1. **Confirm Removal**
- Show component details
- Ask user to confirm deletion
- Warn about potential impacts
2. **Check Dependencies**
- Search for references to this component
- Warn if other plugins depend on it
- List commands that invoke this agent (if removing agent)
3. **Execute Removal**
- Delete component file
- Remove from marketplace entry
- Clean up orphaned directories
4. **Verify Plugin Integrity**
- Ensure plugin still has at least one agent or command
- If removing last component: warn and confirm plugin deletion
## Examples
### Example 1: Add New Agent
```bash
/claude-plugin:update golang-development add agent gin-expert
```
This would:
- Verify `plugins/golang-development/` exists
- Prompt for agent details (description, model, capabilities)
- Create `plugins/golang-development/agents/gin-expert.md`
- Update marketplace.json
- Update documentation
### Example 2: Modify Existing Command
```bash
/claude-plugin:update security-scanning modify command sast-scan
```
This would:
- Load existing `plugins/security-scanning/commands/sast-scan.md`
- Show current configuration
- Ask what needs to change
- Update the file
- Update documentation
### Example 3: Remove Skill
```bash
/claude-plugin:update kubernetes-operations remove skill helm-charts
```
This would:
- Confirm removal
- Check for dependencies
- Delete `plugins/kubernetes-operations/skills/helm-charts/`
- Update marketplace.json
- Update documentation
### Example 4: Add Agent with Configuration
```bash
/claude-plugin:update python-development add agent fastapi-pro '{"model":"claude-sonnet-4","description":"FastAPI framework expert"}'
```
This would:
- Use provided configuration
- Create agent with Sonnet model
- Generate comprehensive system prompt
- Update marketplace and docs
## Error Handling
Common issues and resolutions:
### Plugin Not Found
If `plugins/$PLUGIN_NAME/` doesn't exist:
- Error: "Plugin '$PLUGIN_NAME' not found. Use /claude-plugin:create to create new plugins."
- List available plugins
### Component Already Exists (Add)
If trying to add a component that exists:
- Error: "Component '$COMPONENT_NAME' already exists. Use 'modify' operation to update it."
- Show current component details
### Component Not Found (Modify/Remove)
If component doesn't exist:
- Error: "Component '$COMPONENT_NAME' not found in plugin '$PLUGIN_NAME'."
- List available components in plugin
### Invalid Operation
If `$2` is not add/modify/remove:
- Error: "Invalid operation. Must be: add, modify, or remove"
- Show usage examples
### Removing Last Component
If removing the last agent and command:
- Warning: "This is the last component in the plugin. Removing it will leave an empty plugin."
- Confirm: "Do you want to remove the entire plugin?"
### Dependencies Detected (Remove)
If other components reference the component being removed:
- Warning: "The following components reference '$COMPONENT_NAME': [list]"
- Confirm: "Proceed with removal? You may need to update dependent components."
## Version Management
When updating plugins:
### Minor Updates
- Adding new components
- Enhancing existing components
- Adding examples or documentation
- Increment patch version (1.0.0 → 1.0.1)
### Major Updates
- Modifying component interfaces
- Changing agent models
- Removing components
- Breaking changes
- Increment minor or major version (1.0.0 → 1.1.0 or 2.0.0)
## Notes
- This command updates existing plugins only. Use `/claude-plugin:create` for new plugins.
- All changes maintain spec compliance and proper frontmatter
- The plugin-architect agent ensures consistency with architecture principles
- Skills are invoked automatically for marketplace and documentation updates
- Backward compatibility should be maintained when possible
- Always test updated components before committing changes

89
plugin.lock.json Normal file
View File

@@ -0,0 +1,89 @@
{
"$schema": "internal://schemas/plugin.lock.v1.json",
"pluginId": "gh:geoffjay/claude-plugins:plugins/claude-plugin",
"normalized": {
"repo": null,
"ref": "refs/tags/v20251128.0",
"commit": "63b3f918d3b3ec69e681ac34dbcb56330edc542d",
"treeHash": "43757d9477f57145c43225619cf4ffa3d953daed38ef958c4fdf8341c7902077",
"generatedAt": "2025-11-28T10:16:57.793864Z",
"toolVersion": "publish_plugins.py@0.2.0"
},
"origin": {
"remote": "git@github.com:zhongweili/42plugin-data.git",
"branch": "master",
"commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390",
"repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data"
},
"manifest": {
"name": "claude-plugin",
"description": "Plugin management and scaffolding tools for creating and maintaining Claude Code plugins",
"version": "1.0.0"
},
"content": {
"files": [
{
"path": "README.md",
"sha256": "a5e64e8a237446348a6c050a5d811e9afcbce784e80837bebd93d95862db46c3"
},
{
"path": "agents/plugin-architect.md",
"sha256": "268e60ec2a2d8ce90c20a4859e4cd245d9f899e6f2f1434917283a2a2f101bca"
},
{
"path": ".claude-plugin/plugin.json",
"sha256": "99774c7f77d3cdf9a6b328760cdd8a604d3c9b942dd51936cfd2a4d3d1a0e321"
},
{
"path": "commands/create.md",
"sha256": "04a74e945d922807a92df321ac00e3eed771b4eb7e529112907ac25c40a3dace"
},
{
"path": "commands/update.md",
"sha256": "9c5d350f404527c3c581ac8961073e93a469934684e45a84242dbae05b280aa2"
},
{
"path": "commands/documentation.md",
"sha256": "7e582c83d5dfc10a3fd812037042d7d496c15d03b9c582941c45e885a4c0912d"
},
{
"path": "skills/documentation-update/SKILL.md",
"sha256": "93d8a8b3efada3e78104f413a8562fc100f753b2baf47cf73ea5914f7addc84e"
},
{
"path": "skills/documentation-update/doc_generator.py",
"sha256": "64b95af4d39e691e2a99431d9360221c556ccf4b0f8f9300ae9f50ffb57ac70b"
},
{
"path": "skills/documentation-update/assets/agent-skills.md.j2",
"sha256": "4a2e0dbe32402f1f2d5bbbbc62722157ece7711f9b579ab9a888a4a42976bf61"
},
{
"path": "skills/documentation-update/assets/plugins.md.j2",
"sha256": "9c02263d62fe1710574b6d0cc397bee771419760ba7019795aad167f937d5ecf"
},
{
"path": "skills/documentation-update/assets/usage.md.j2",
"sha256": "4f17c5229a4b34967ee402898de88c06312630dff3af36e6c3a4a8ecb1c90838"
},
{
"path": "skills/documentation-update/assets/agents.md.j2",
"sha256": "4b5c0bda3d4136db707a3fb99677b2deb8fbb8d6614f2070ad2376e23b36b9c0"
},
{
"path": "skills/marketplace-update/marketplace_update.py",
"sha256": "f5394514c86173b04bcdb8e892435e5d3fe07d15cf0ef71a6de09c3b6186de44"
},
{
"path": "skills/marketplace-update/SKILL.md",
"sha256": "e94ed1cbf79c78008ba610809c249a2de59a514cc00b8aa65a4b9ab9d0a47d74"
}
],
"dirSha256": "43757d9477f57145c43225619cf4ffa3d953daed38ef958c4fdf8341c7902077"
},
"security": {
"scannedAt": null,
"scannerVersion": null,
"flags": []
}
}

View File

@@ -0,0 +1,467 @@
---
name: documentation-update
description: Regenerates documentation files (agents.md, agent-skills.md, plugins.md, usage.md) from marketplace data using Jinja templates. Use when plugins are added, updated, or removed to keep documentation in sync.
---
# Documentation Update Skill
This skill automatically regenerates documentation files in the `docs/` directory by reading the marketplace catalog and applying Jinja2 templates.
## Purpose
Maintain synchronized documentation by:
- Generating agent reference documentation
- Creating skill catalog documentation
- Building plugin directory
- Updating usage guides
- Ensuring consistency across all docs
## When to Use
Use this skill when:
- A new plugin is added to the marketplace
- An existing plugin is updated (components added/removed)
- Agent or skill metadata changes
- Documentation needs to be regenerated
- Ensuring docs match marketplace state
## Documentation Files
This skill generates four main documentation files:
### 1. agents.md
Complete reference of all agents across all plugins:
- Organized by plugin
- Lists agent name, description, and model
- Includes links to agent files
- Shows agent capabilities and use cases
### 2. agent-skills.md
Catalog of all skills with progressive disclosure details:
- Organized by plugin
- Lists skill name and description
- Shows "Use when" triggers
- Includes skill structure information
### 3. plugins.md
Directory of all plugins in the marketplace:
- Organized by category
- Shows plugin name, description, and version
- Lists components (agents, commands, skills)
- Provides installation and usage information
### 4. usage.md
Usage guide and command reference:
- Getting started instructions
- Command usage examples
- Workflow patterns
- Integration guides
## Template Structure
Templates are stored in `assets/` using Jinja2 syntax:
```
assets/
├── agents.md.j2
├── agent-skills.md.j2
├── plugins.md.j2
└── usage.md.j2
```
### Template Variables
All templates receive the following context:
```python
{
"marketplace": {
"name": "marketplace-name",
"owner": {...},
"metadata": {...},
"plugins": [...]
},
"plugins_by_category": {
"category-name": [plugin1, plugin2, ...]
},
"all_agents": [
{
"plugin": "plugin-name",
"name": "agent-name",
"file": "agent-file.md",
"description": "...",
"model": "..."
}
],
"all_skills": [
{
"plugin": "plugin-name",
"name": "skill-name",
"path": "skill-path",
"description": "..."
}
],
"all_commands": [
{
"plugin": "plugin-name",
"name": "command-name",
"file": "command-file.md",
"description": "..."
}
],
"stats": {
"total_plugins": 10,
"total_agents": 25,
"total_commands": 15,
"total_skills": 30
}
}
```
## Python Script
The skill includes a Python script `doc_generator.py` that:
1. **Loads marketplace.json**
- Reads the marketplace catalog
- Validates structure
- Builds component index
2. **Scans Plugin Files**
- Reads agent/command frontmatter
- Extracts skill metadata
- Builds comprehensive component list
3. **Prepares Template Context**
- Organizes plugins by category
- Creates component indexes
- Calculates statistics
4. **Renders Templates**
- Applies Jinja2 templates
- Generates documentation files
- Writes to docs/ directory
### Usage
```bash
# Generate all documentation files
python doc_generator.py
# Generate specific file only
python doc_generator.py --file agents
# Dry run (show output without writing)
python doc_generator.py --dry-run
# Specify custom paths
python doc_generator.py \
--marketplace .claude-plugin/marketplace.json \
--templates plugins/claude-plugin/skills/documentation-update/assets \
--output docs
```
## Integration with Commands
The `/claude-plugin:create` and `/claude-plugin:update` commands should invoke this skill automatically after marketplace updates:
### Workflow
```
1. Plugin operation completes (add/update/remove)
2. Marketplace.json is updated
3. Invoke documentation-update skill
4. Documentation files regenerated
5. Changes ready to commit
```
### Example Integration
```python
# After creating/updating plugin
print("Updating documentation...")
# Run doc generator
import subprocess
result = subprocess.run(
["python", "plugins/claude-plugin/skills/documentation-update/doc_generator.py"],
capture_output=True,
text=True
)
if result.returncode == 0:
print("✓ Documentation updated")
else:
print(f"❌ Documentation update failed: {result.stderr}")
```
## Template Examples
### agents.md.j2
```jinja2
# Agent Reference
This document lists all agents available across plugins in the marketplace.
{% for category, plugins in plugins_by_category.items() %}
## {{ category|title }}
{% for plugin in plugins %}
### {{ plugin.name }}
{{ plugin.description }}
**Agents:**
{% for agent in all_agents %}
{% if agent.plugin == plugin.name %}
- **{{ agent.name }}** (`{{ agent.model }}`)
- {{ agent.description }}
- File: `plugins/{{ plugin.name }}/agents/{{ agent.file }}`
{% endif %}
{% endfor %}
{% endfor %}
{% endfor %}
---
*Last updated: {{ now }}*
*Total agents: {{ stats.total_agents }}*
```
### agent-skills.md.j2
```jinja2
# Agent Skills Reference
This document catalogs all skills with progressive disclosure patterns.
{% for plugin in marketplace.plugins %}
## {{ plugin.name }}
{{ plugin.description }}
**Skills:**
{% for skill in all_skills %}
{% if skill.plugin == plugin.name %}
### {{ skill.name }}
{{ skill.description }}
- **Location:** `plugins/{{ plugin.name }}/skills/{{ skill.path }}/`
- **Structure:** SKILL.md + assets/ + references/
{% endif %}
{% endfor %}
{% endfor %}
---
*Last updated: {{ now }}*
*Total skills: {{ stats.total_skills }}*
```
## Error Handling
### Marketplace Not Found
```
Error: Marketplace file not found: .claude-plugin/marketplace.json
Suggestion: Ensure marketplace.json exists
```
### Template Not Found
```
Error: Template file not found: assets/agents.md.j2
Suggestion: Ensure all template files exist in assets/
```
### Invalid Plugin Structure
```
Warning: Plugin 'plugin-name' missing components
Suggestion: Verify plugin has agents or commands
```
### Frontmatter Parse Error
```
Warning: Could not parse frontmatter in agents/agent-name.md
Suggestion: Check YAML frontmatter syntax
```
## Best Practices
1. **Always Regenerate After Changes**
- Run after every plugin add/update/remove
- Ensure docs stay synchronized
- Commit documentation with plugin changes
2. **Validate Before Generation**
- Run marketplace validation first
- Fix any errors or warnings
- Ensure all files exist
3. **Review Generated Output**
- Check generated files for correctness
- Verify formatting and links
- Test any code examples
4. **Template Maintenance**
- Keep templates simple and readable
- Use consistent formatting
- Document template variables
5. **Version Control**
- Commit documentation changes
- Include in pull requests
- Document significant changes
## Template Customization
### Adding New Sections
To add a new section to a template:
1. **Modify Template**
```jinja2
## New Section
{% for plugin in marketplace.plugins %}
### {{ plugin.name }}
[Your content here]
{% endfor %}
```
2. **Update Context (if needed)**
- Add new data to template context in doc_generator.py
- Process additional metadata
3. **Test Output**
- Run generator with dry-run
- Verify formatting
- Check for errors
### Creating New Templates
To add a new documentation file:
1. **Create Template**
- Add `assets/newdoc.md.j2`
- Define structure and content
2. **Update Script**
- Add to doc_generator.py template list
- Define output path
3. **Test Generation**
- Run generator
- Verify output
- Commit template and output
## File Structure
```
plugins/claude-plugin/skills/documentation-update/
├── SKILL.md # This file
├── doc_generator.py # Python implementation
├── assets/ # Jinja2 templates
│ ├── agents.md.j2
│ ├── agent-skills.md.j2
│ ├── plugins.md.j2
│ └── usage.md.j2
└── references/ # Optional examples
└── template-examples.md
```
## Requirements
- Python 3.8+
- No external dependencies (uses standard library only)
- Access to `.claude-plugin/marketplace.json`
- Read access to plugin directories
- Write access to `docs/` directory
## Success Criteria
After running this skill:
- ✓ All documentation files generated
- ✓ Content matches marketplace state
- ✓ All links are valid
- ✓ Formatting is consistent
- ✓ Statistics are accurate
- ✓ No template rendering errors
## Maintenance
### Updating Templates
When marketplace structure changes:
1. **Assess Impact**
- Identify affected templates
- Determine required changes
2. **Update Templates**
- Modify Jinja2 templates
- Test with current data
3. **Update Script**
- Adjust context preparation if needed
- Add new data processing
4. **Validate Output**
- Regenerate all docs
- Review changes
- Test links and formatting
### Version Compatibility
- Templates should handle missing fields gracefully
- Use Jinja2 default filters for optional data
- Validate marketplace version compatibility
## Example Output
The skill generates comprehensive, well-formatted documentation:
- **agents.md**: ~500-1000 lines for 20-30 agents
- **agent-skills.md**: ~300-600 lines for 30-50 skills
- **plugins.md**: ~400-800 lines for 10-20 plugins
- **usage.md**: ~200-400 lines of usage information
All files include:
- Clear structure and headings
- Formatted tables where appropriate
- Links to source files
- Statistics and metadata
- Last updated timestamp

View File

@@ -0,0 +1,73 @@
# Agent Skills Reference
This document catalogs all agent skills with progressive disclosure patterns across the marketplace.
## Overview
- **Total Skills**: {{ stats.total_skills }}
- **Total Plugins**: {{ stats.total_plugins }}
- **Last Updated**: {{ now }}
---
## What are Agent Skills?
Agent skills are modular knowledge packages that use progressive disclosure architecture:
1. **Metadata** (Frontmatter) - Always loaded
2. **Instructions** - Core guidance loaded when activated
3. **Resources** (assets/) - Loaded on demand
All skills follow the [Anthropic Agent Skills Specification](https://github.com/anthropics/skills/blob/main/agent_skills_spec.md).
---
{% for plugin in marketplace.plugins %}
## {{ plugin.name }}
**Description**: {{ plugin.description }}
**Version**: {{ plugin.version }}
{% if plugin.skills %}
**Skills**:
{% for skill in all_skills %}
{% if skill.plugin == plugin.name %}
### {{ skill.name }}
{{ skill.description }}
**Location**: `plugins/{{ plugin.name }}/skills/{{ skill.path }}/`
**Structure**:
- `SKILL.md` - Skill definition with frontmatter
- `assets/` - Templates, configurations, examples
- `references/` - Additional documentation
{% endif %}
{% endfor %}
{% else %}
*No skills defined*
{% endif %}
---
{% endfor %}
## Progressive Disclosure Benefits
- **Token Efficiency**: Load only relevant knowledge when needed
- **Specialized Expertise**: Deep domain knowledge without bloat
- **Clear Activation**: Explicit triggers prevent unwanted invocation
- **Composability**: Mix and match skills across workflows
- **Maintainability**: Isolated updates don't affect other skills
## Using Skills
Skills are automatically invoked by agents when their trigger conditions are met. You can also manually invoke skills when needed for specific operations.
---
*This documentation is automatically generated from the marketplace catalog.*
*Last updated: {{ now }}*

View File

@@ -0,0 +1,64 @@
# Agent Reference
This document provides a comprehensive reference of all agents available across plugins in the marketplace.
## Overview
- **Total Agents**: {{ stats.total_agents }}
- **Total Plugins**: {{ stats.total_plugins }}
- **Last Updated**: {{ now }}
---
{% for category, plugins in plugins_by_category.items() %}
## {{ category|title }} Agents
{% for plugin in plugins %}
### {{ plugin.name }}
**Description**: {{ plugin.description }}
**Version**: {{ plugin.version }}
{% if plugin.agents %}
**Agents**:
{% for agent in all_agents %}
{% if agent.plugin == plugin.name %}
#### {{ agent.name }}
- **Model**: `{{ agent.model }}`
- **Description**: {{ agent.description }}
- **Location**: `plugins/{{ plugin.name }}/agents/{{ agent.file }}`
{% endif %}
{% endfor %}
{% else %}
*No agents defined*
{% endif %}
---
{% endfor %}
{% endfor %}
## Usage
To use an agent from the command line:
```bash
# Invoke with Task tool
Use Task tool with subagent_type="<agent-name>"
```
## Model Distribution
Agents are optimized for specific models based on their complexity:
- **Haiku**: Fast execution for deterministic tasks
- **Sonnet**: Complex reasoning and architecture decisions
---
*This documentation is automatically generated from the marketplace catalog.*
*Last updated: {{ now }}*

View File

@@ -0,0 +1,88 @@
# Plugin Directory
Complete catalog of all plugins available in the marketplace.
## Overview
- **Total Plugins**: {{ stats.total_plugins }}
- **Total Agents**: {{ stats.total_agents }}
- **Total Commands**: {{ stats.total_commands }}
- **Total Skills**: {{ stats.total_skills }}
- **Last Updated**: {{ now }}
---
{% for category, plugins in plugins_by_category.items() %}
## {{ category|title }}
{% for plugin in plugins %}
### {{ plugin.name }}
{{ plugin.description }}
**Version**: {{ plugin.version }}
**Author**: {% if plugin.author %}{{ plugin.author.name }}{% else %}{{ marketplace.owner.name }}{% endif %}
**License**: {{ plugin.license }}
{% if plugin.keywords %}
**Keywords**: {{ plugin.keywords|join(', ') }}
{% endif %}
**Components**:
{% if plugin.agents %}
- **Agents**: {{ plugin.agents|length }}
{% endif %}
{% if plugin.commands %}
- **Commands**: {{ plugin.commands|length }}
{% endif %}
{% if plugin.skills %}
- **Skills**: {{ plugin.skills|length }}
{% endif %}
**Location**: `{{ plugin.source }}`
{% if plugin.homepage %}
**Homepage**: {{ plugin.homepage }}
{% endif %}
{% if plugin.repository %}
**Repository**: {{ plugin.repository }}
{% endif %}
---
{% endfor %}
{% endfor %}
## Plugin Architecture
Each plugin follows these principles:
- **Single Responsibility**: One plugin does one thing well
- **Composability**: Mix and match plugins based on needs
- **Context Efficiency**: Smaller tools for better LLM performance
- **Maintainability**: Isolated updates, clear boundaries
## Installation
All plugins are included in this marketplace. To use a plugin:
1. Ensure the plugin directory exists in `plugins/`
2. Use agents via the Task tool
3. Use commands via slash commands
4. Skills are automatically loaded when needed
## Categories
Plugins are organized into the following categories:
{% for category in plugins_by_category.keys() %}
- **{{ category|title }}**: {{ plugins_by_category[category]|length }} plugin(s)
{% endfor %}
---
*This documentation is automatically generated from the marketplace catalog.*
*Last updated: {{ now }}*

View File

@@ -0,0 +1,250 @@
# Usage Guide
Comprehensive guide for using Claude Code plugins, agents, commands, and skills from this marketplace.
## Overview
This marketplace provides {{ stats.total_plugins }} plugin(s) with:
- {{ stats.total_agents }} specialized agent(s)
- {{ stats.total_commands }} command(s)
- {{ stats.total_skills }} skill(s)
**Last Updated**: {{ now }}
---
## Quick Start
### Using Agents
Agents are specialized domain experts invoked via the Task tool:
```
Use Task tool with subagent_type="<agent-name>"
```
**Example**:
```
Use Task tool with subagent_type="plugin-architect" to design a new plugin
```
### Using Commands
Commands are slash commands for specific workflows:
```bash
/<command-name> [arguments]
```
**Available Commands**:
{% for command in all_commands %}
- `{{ command.name }}` - {{ command.description }}
- Plugin: {{ command.plugin }}
- File: `plugins/{{ command.plugin }}/commands/{{ command.file }}`
{% endfor %}
### Using Skills
Skills are automatically invoked by agents when their trigger conditions are met. Skills provide:
- Modular knowledge packages
- Progressive disclosure (metadata → instructions → resources)
- Spec-compliant with Anthropic guidelines
**Available Skills**:
{% for skill in all_skills %}
- `{{ skill.name }}` - {{ skill.description }}
- Plugin: {{ skill.plugin }}
- Path: `plugins/{{ skill.plugin }}/skills/{{ skill.path }}/`
{% endfor %}
---
## Common Workflows
### Creating a New Plugin
Use the `claude-plugin` plugin to create new plugins:
```bash
# Create a new plugin
/create <plugin-name> "<description>" [components]
# Example
/create golang-advanced "Advanced Go development tools" agents,commands,skills
```
### Updating an Existing Plugin
Modify plugins by adding, updating, or removing components:
```bash
# Add a new agent
/update <plugin-name> add agent <agent-name>
# Modify a command
/update <plugin-name> modify command <command-name>
# Remove a skill
/update <plugin-name> remove skill <skill-name>
```
### Working with Agents
Invoke agents for specialized tasks:
```
# For architecture and design
Use Task tool with subagent_type="plugin-architect"
# Add your task description
[Describe what you need the agent to do]
```
---
## Plugin Architecture
### Directory Structure
```
plugins/
├── <plugin-name>/
│ ├── agents/ # Specialized agents (optional)
│ │ └── agent.md
│ ├── commands/ # Slash commands (optional)
│ │ └── command.md
│ └── skills/ # Agent skills (optional)
│ └── skill-name/
│ ├── SKILL.md
│ ├── assets/
│ └── references/
```
### Component Requirements
Each plugin must have:
- At least one agent OR one command
- Proper YAML frontmatter in all files
- Clear, focused purpose
- Entry in marketplace.json
---
## Agent Reference
### Available Agents
{% for agent in all_agents %}
#### {{ agent.name }}
- **Plugin**: {{ agent.plugin }}
- **Model**: {{ agent.model }}
- **Description**: {{ agent.description }}
- **Invocation**: `Use Task tool with subagent_type="{{ agent.name }}"`
{% endfor %}
### Model Selection
Agents use different models based on task complexity:
- **Haiku**: Fast execution for deterministic tasks
- Code generation from specs
- Test creation
- Documentation generation
- **Sonnet**: Complex reasoning and architecture
- System design
- Security audits
- Language expertise
- Multi-agent orchestration
---
## Best Practices
### When Creating Plugins
1. **Single Responsibility**: One plugin, one purpose
2. **Clear Naming**: Use hyphen-case, be descriptive
3. **Complete Documentation**: Include frontmatter and examples
4. **Spec Compliance**: Follow Anthropic guidelines
5. **Test Thoroughly**: Verify functionality before committing
### When Using Agents
1. **Choose the Right Agent**: Match agent expertise to task
2. **Provide Clear Context**: Detailed task descriptions
3. **Use Appropriate Models**: Haiku for speed, Sonnet for complexity
4. **Compose When Needed**: Combine multiple agents for complex workflows
### When Working with Skills
1. **Progressive Disclosure**: Load only what's needed
2. **Clear Triggers**: Use explicit activation criteria
3. **Modular Design**: Keep skills focused and reusable
4. **Document Well**: Include usage examples
---
## Marketplace Management
### Adding Plugins
Plugins are added via the marketplace update process:
1. Create plugin directory and components
2. Update `.claude-plugin/marketplace.json`
3. Regenerate documentation
### Updating Documentation
Documentation is automatically generated from the marketplace:
```bash
# Regenerate all docs
python plugins/claude-plugin/skills/documentation-update/doc_generator.py
# Generate specific file
python plugins/claude-plugin/skills/documentation-update/doc_generator.py --file agents
```
---
## Categories
Plugins are organized by category:
{% for category, plugins in plugins_by_category.items() %}
### {{ category|title }}
{% for plugin in plugins %}
- **{{ plugin.name }}** - {{ plugin.description }}
{% endfor %}
{% endfor %}
---
## Getting Help
- **Documentation**: See `docs/` directory for detailed references
- **Architecture**: See `docs/architecture.md` for design principles
- **Contributing**: See `.github/CONTRIBUTING.md` for contribution guidelines
---
## Resources
- [Architecture Documentation](./architecture.md)
- [Agent Reference](./agents.md)
- [Skills Reference](./agent-skills.md)
- [Plugin Directory](./plugins.md)
---
*This documentation is automatically generated from the marketplace catalog.*
*Last updated: {{ now }}*

View File

@@ -0,0 +1,476 @@
#!/usr/bin/env python3
"""
Documentation Generator
Generates documentation files from marketplace data using Jinja2 templates.
"""
import json
import os
import sys
import re
from pathlib import Path
from datetime import datetime
from typing import Dict, List, Any, Optional
import argparse
# Try to use real Jinja2 if available, otherwise use SimpleTemplate fallback
try:
from jinja2 import Template as Jinja2Template
USE_JINJA2 = True
except ImportError:
USE_JINJA2 = False
class SimpleTemplate:
"""Minimal Jinja2-like template engine"""
def __init__(self, template_str: str):
self.template = template_str
def apply_filter(self, value: Any, filter_name: str) -> Any:
"""Apply a filter to a value"""
if filter_name == 'title':
return str(value).replace('-', ' ').replace('_', ' ').title()
elif filter_name == 'length':
return len(value) if hasattr(value, '__len__') else 0
elif filter_name.startswith('join'):
# Extract separator from filter (e.g., "join(', ')")
match = re.search(r"join\(['\"]([^'\"]*)['\"]\)", filter_name)
if match and isinstance(value, list):
separator = match.group(1)
return separator.join(str(v) for v in value)
return str(value)
return value
def resolve_value(self, expr: str, context: Dict[str, Any]) -> Any:
"""Resolve a variable expression with optional filters"""
# Split expression and filters
parts = expr.strip().split('|')
var_expr = parts[0].strip()
filters = [f.strip() for f in parts[1:]]
# Resolve the base variable
value = context
for key in var_expr.split('.'):
key = key.strip()
if isinstance(value, dict):
value = value.get(key, '')
elif hasattr(value, key):
value = getattr(value, key)
else:
value = ''
break
# Apply filters
for filter_name in filters:
value = self.apply_filter(value, filter_name)
return value
def render(self, context: Dict[str, Any]) -> str:
"""Render template with context"""
result = self.template
# Handle nested loops with .items(): {% for key, value in dict.items() %}...{% endfor %}
items_pattern = r'{%\s*for\s+(\w+)\s*,\s*(\w+)\s+in\s+([\w.]+)\.items\(\)\s*%}(.*?){%\s*endfor\s*%}'
def replace_items_loop(match):
key_var = match.group(1)
value_var = match.group(2)
dict_name = match.group(3)
loop_body = match.group(4)
dict_obj = self.resolve_value(dict_name, context)
if not isinstance(dict_obj, dict):
return ""
output = []
for key, value in dict_obj.items():
loop_context = context.copy()
loop_context[key_var] = key
loop_context[value_var] = value
# Recursively render the loop body
template = SimpleTemplate(loop_body)
body_result = template.render(loop_context)
output.append(body_result)
return "".join(output)
result = re.sub(items_pattern, replace_items_loop, result, flags=re.DOTALL)
# Handle loops with .keys(): {% for key in dict.keys() %}...{% endfor %}
keys_pattern = r'{%\s*for\s+(\w+)\s+in\s+([\w.]+)\.keys\(\)\s*%}(.*?){%\s*endfor\s*%}'
def replace_keys_loop(match):
var_name = match.group(1)
dict_name = match.group(2)
loop_body = match.group(3)
dict_obj = self.resolve_value(dict_name, context)
if not isinstance(dict_obj, dict):
return ""
output = []
for key in dict_obj.keys():
loop_context = context.copy()
loop_context[var_name] = key
# Recursively render the loop body
template = SimpleTemplate(loop_body)
body_result = template.render(loop_context)
output.append(body_result)
return "".join(output)
result = re.sub(keys_pattern, replace_keys_loop, result, flags=re.DOTALL)
# Handle regular loops: {% for item in items %}...{% endfor %}
for_pattern = r'{%\s*for\s+(\w+)\s+in\s+([\w.]+)\s*%}(.*?){%\s*endfor\s*%}'
def replace_for(match):
var_name = match.group(1)
list_name = match.group(2)
loop_body = match.group(3)
items = self.resolve_value(list_name, context)
if not isinstance(items, (list, dict)):
return ""
# Handle both lists and dict values
if isinstance(items, dict):
items = list(items.values())
output = []
for item in items:
loop_context = context.copy()
loop_context[var_name] = item
# If item is a dict, also add its keys directly to context for easier access
if isinstance(item, dict):
for key, value in item.items():
loop_context[f"{var_name}.{key}"] = value
# Recursively render the loop body
template = SimpleTemplate(loop_body)
body_result = template.render(loop_context)
output.append(body_result)
return "".join(output)
result = re.sub(for_pattern, replace_for, result, flags=re.DOTALL)
# Handle conditionals with comparison: {% if var1 == var2 %}...{% endif %}
if_compare_pattern = r'{%\s*if\s+([\w.]+)\s*==\s*([\w.]+)\s*%}(.*?){%\s*endif\s*%}'
def replace_if_compare(match):
left_expr = match.group(1)
right_expr = match.group(2)
body = match.group(3)
left_val = self.resolve_value(left_expr, context)
right_val = self.resolve_value(right_expr, context)
if left_val == right_val:
template = SimpleTemplate(body)
return template.render(context)
return ""
result = re.sub(if_compare_pattern, replace_if_compare, result, flags=re.DOTALL)
# Handle conditionals with else: {% if condition %}...{% else %}...{% endif %}
if_else_pattern = r'{%\s*if\s+([\w.]+)\s*%}(.*?){%\s*else\s*%}(.*?){%\s*endif\s*%}'
def replace_if_else(match):
condition = match.group(1)
true_body = match.group(2)
false_body = match.group(3)
cond_val = self.resolve_value(condition, context)
if cond_val:
template = SimpleTemplate(true_body)
return template.render(context)
else:
template = SimpleTemplate(false_body)
return template.render(context)
result = re.sub(if_else_pattern, replace_if_else, result, flags=re.DOTALL)
# Handle simple conditionals: {% if condition %}...{% endif %}
if_pattern = r'{%\s*if\s+([\w.]+)\s*%}(.*?){%\s*endif\s*%}'
def replace_if(match):
condition = match.group(1)
body = match.group(2)
cond_val = self.resolve_value(condition, context)
if cond_val:
template = SimpleTemplate(body)
return template.render(context)
return ""
result = re.sub(if_pattern, replace_if, result, flags=re.DOTALL)
# Replace variables with filters: {{ variable|filter }}
var_pattern = r'{{\s*([\w.|()\'",\s]+)\s*}}'
def replace_var(match):
expr = match.group(1)
value = self.resolve_value(expr, context)
return str(value) if value is not None else ''
result = re.sub(var_pattern, replace_var, result)
# Clean up any remaining template syntax
result = re.sub(r'{%.*?%}', '', result)
result = re.sub(r'{{.*?}}', '', result)
return result
class DocGenerator:
"""Generates documentation from marketplace data"""
def __init__(
self,
marketplace_path: str = ".claude-plugin/marketplace.json",
templates_dir: str = "plugins/claude-plugin/skills/documentation-update/assets",
output_dir: str = "docs",
):
self.marketplace_path = Path(marketplace_path)
self.templates_dir = Path(templates_dir)
self.output_dir = Path(output_dir)
self.marketplace_data: Dict[str, Any] = {}
def load_marketplace(self) -> None:
"""Load marketplace.json"""
if not self.marketplace_path.exists():
raise FileNotFoundError(f"Marketplace not found: {self.marketplace_path}")
with open(self.marketplace_path, 'r') as f:
self.marketplace_data = json.load(f)
def extract_frontmatter(self, file_path: Path) -> Dict[str, str]:
"""Extract YAML frontmatter from a markdown file"""
if not file_path.exists():
return {}
try:
with open(file_path, 'r') as f:
content = f.read()
# Match frontmatter between --- delimiters
match = re.match(r'^---\s*\n(.*?)\n---\s*\n', content, re.DOTALL)
if not match:
return {}
frontmatter_text = match.group(1)
frontmatter = {}
# Simple YAML parsing (key: value)
for line in frontmatter_text.split('\n'):
if ':' in line:
key, value = line.split(':', 1)
frontmatter[key.strip()] = value.strip().strip('"\'')
return frontmatter
except Exception as e:
print(f"Warning: Could not parse frontmatter in {file_path}: {e}")
return {}
def build_context(self) -> Dict[str, Any]:
"""Build template context from marketplace data"""
context = {
"marketplace": self.marketplace_data,
"now": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"plugins_by_category": {},
"all_agents": [],
"all_skills": [],
"all_commands": [],
"stats": {
"total_plugins": 0,
"total_agents": 0,
"total_commands": 0,
"total_skills": 0,
},
}
if "plugins" not in self.marketplace_data:
return context
plugins = self.marketplace_data["plugins"]
context["stats"]["total_plugins"] = len(plugins)
# Organize plugins by category
for plugin in plugins:
category = plugin.get("category", "general")
if category not in context["plugins_by_category"]:
context["plugins_by_category"][category] = []
context["plugins_by_category"][category].append(plugin)
plugin_name = plugin.get("name", "")
plugin_dir = Path(f"plugins/{plugin_name}")
# Extract agent information
if "agents" in plugin:
for agent_path in plugin["agents"]:
agent_file = agent_path.replace("./agents/", "")
full_path = plugin_dir / agent_path.lstrip('./')
frontmatter = self.extract_frontmatter(full_path)
context["all_agents"].append({
"plugin": plugin_name,
"name": frontmatter.get("name", agent_file.replace(".md", "")),
"file": agent_file,
"description": frontmatter.get("description", ""),
"model": frontmatter.get("model", ""),
})
context["stats"]["total_agents"] += len(plugin["agents"])
# Extract command information
if "commands" in plugin:
for cmd_path in plugin["commands"]:
cmd_file = cmd_path.replace("./commands/", "")
full_path = plugin_dir / cmd_path.lstrip('./')
frontmatter = self.extract_frontmatter(full_path)
context["all_commands"].append({
"plugin": plugin_name,
"name": frontmatter.get("name", cmd_file.replace(".md", "")),
"file": cmd_file,
"description": frontmatter.get("description", ""),
})
context["stats"]["total_commands"] += len(plugin["commands"])
# Extract skill information
if "skills" in plugin:
for skill_path in plugin["skills"]:
skill_name = skill_path.replace("./skills/", "")
full_path = plugin_dir / skill_path.lstrip('./') / "SKILL.md"
frontmatter = self.extract_frontmatter(full_path)
context["all_skills"].append({
"plugin": plugin_name,
"name": frontmatter.get("name", skill_name),
"path": skill_name,
"description": frontmatter.get("description", ""),
})
context["stats"]["total_skills"] += len(plugin["skills"])
return context
def render_template(self, template_name: str, context: Dict[str, Any]) -> str:
"""Render a template with context"""
template_path = self.templates_dir / f"{template_name}.md.j2"
if not template_path.exists():
raise FileNotFoundError(f"Template not found: {template_path}")
with open(template_path, 'r') as f:
template_content = f.read()
if USE_JINJA2:
# Use real Jinja2 for full compatibility
template = Jinja2Template(template_content)
return template.render(**context)
else:
# Fallback to SimpleTemplate
template = SimpleTemplate(template_content)
return template.render(context)
def generate_all(self, dry_run: bool = False, specific_file: Optional[str] = None) -> None:
"""Generate all documentation files"""
self.load_marketplace()
context = self.build_context()
docs_to_generate = {
"agents": "agents.md",
"agent-skills": "agent-skills.md",
"plugins": "plugins.md",
"usage": "usage.md",
}
if specific_file:
if specific_file not in docs_to_generate:
raise ValueError(f"Unknown documentation file: {specific_file}")
docs_to_generate = {specific_file: docs_to_generate[specific_file]}
for template_name, output_file in docs_to_generate.items():
try:
print(f"Generating {output_file}...")
content = self.render_template(template_name, context)
if dry_run:
print(f"\n--- {output_file} ---")
print(content[:500] + "..." if len(content) > 500 else content)
print()
else:
output_path = self.output_dir / output_file
output_path.parent.mkdir(parents=True, exist_ok=True)
with open(output_path, 'w') as f:
f.write(content)
print(f"✓ Generated {output_path}")
except Exception as e:
print(f"❌ Error generating {output_file}: {e}")
def main():
"""Main entry point"""
parser = argparse.ArgumentParser(description="Generate documentation from marketplace")
parser.add_argument(
"--marketplace",
default=".claude-plugin/marketplace.json",
help="Path to marketplace.json",
)
parser.add_argument(
"--templates",
default="plugins/claude-plugin/skills/documentation-update/assets",
help="Path to templates directory",
)
parser.add_argument(
"--output",
default="docs",
help="Output directory for documentation",
)
parser.add_argument(
"--file",
choices=["agents", "agent-skills", "plugins", "usage"],
help="Generate specific file only",
)
parser.add_argument(
"--dry-run",
action="store_true",
help="Show output without writing files",
)
args = parser.parse_args()
try:
generator = DocGenerator(
marketplace_path=args.marketplace,
templates_dir=args.templates,
output_dir=args.output,
)
generator.generate_all(dry_run=args.dry_run, specific_file=args.file)
if not args.dry_run:
print("\n✓ Documentation generation complete")
except Exception as e:
print(f"❌ Error: {e}", file=sys.stderr)
sys.exit(1)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,357 @@
---
name: marketplace-update
description: Updates the .claude-plugin/marketplace.json file when plugins are added, modified, or removed. Use when creating or updating plugin entries in the marketplace catalog.
---
# Marketplace Update Skill
This skill provides functionality to update the `.claude-plugin/marketplace.json` file when plugins are added, modified, or removed from the marketplace.
## Purpose
Maintain the marketplace catalog by:
- Adding new plugin entries
- Updating existing plugin metadata
- Removing obsolete plugins
- Validating marketplace structure
- Ensuring consistency across the catalog
## When to Use
Use this skill when:
- A new plugin is created and needs to be registered
- An existing plugin's components change (agents, commands, skills added/removed)
- Plugin metadata needs updating (version, description, keywords, etc.)
- A plugin is being removed from the marketplace
- Validating marketplace.json structure
## Marketplace Structure
The marketplace.json file follows this schema:
```json
{
"name": "marketplace-name",
"owner": {
"name": "Owner Name",
"email": "email@example.com",
"url": "https://github.com/username"
},
"metadata": {
"description": "Marketplace description",
"version": "1.0.0"
},
"plugins": [
{
"name": "plugin-name",
"source": "./plugins/plugin-name",
"description": "Plugin description",
"version": "1.0.0",
"author": {
"name": "Author Name",
"url": "https://github.com/username"
},
"homepage": "https://github.com/username/repo",
"repository": "https://github.com/username/repo",
"license": "MIT",
"keywords": ["keyword1", "keyword2"],
"category": "category-name",
"strict": false,
"commands": ["./commands/command-name.md"],
"agents": ["./agents/agent-name.md"],
"skills": ["./skills/skill-name"]
}
]
}
```
## Operations
### Add Plugin
Add a new plugin entry to the marketplace:
```python
# Use the provided Python script
python marketplace_update.py add \
--name "plugin-name" \
--description "Plugin description" \
--version "1.0.0" \
--category "category-name" \
--agents "agent1.md,agent2.md" \
--commands "command1.md,command2.md" \
--skills "skill1,skill2"
```
**Required Fields:**
- `name` - Plugin name (hyphen-case)
- `description` - Brief plugin description
- `version` - Semantic version (e.g., "1.0.0")
**Optional Fields:**
- `category` - Plugin category (default: "general")
- `agents` - Comma-separated list of agent files
- `commands` - Comma-separated list of command files
- `skills` - Comma-separated list of skill directories
- `keywords` - Comma-separated list of keywords
- `license` - License type (default: "MIT")
- `strict` - Strict mode flag (default: false)
### Update Plugin
Update an existing plugin entry:
```python
python marketplace_update.py update \
--name "plugin-name" \
--description "Updated description" \
--version "1.1.0" \
--add-agent "new-agent.md" \
--remove-command "old-command.md"
```
**Update Operations:**
- `--description` - Update description
- `--version` - Update version
- `--category` - Update category
- `--keywords` - Update keywords (replaces all)
- `--add-agent` - Add agent file
- `--remove-agent` - Remove agent file
- `--add-command` - Add command file
- `--remove-command` - Remove command file
- `--add-skill` - Add skill directory
- `--remove-skill` - Remove skill directory
### Remove Plugin
Remove a plugin from the marketplace:
```python
python marketplace_update.py remove --name "plugin-name"
```
### Validate Marketplace
Validate the marketplace.json structure:
```python
python marketplace_update.py validate
```
This checks:
- JSON syntax validity
- Required fields presence
- File path existence
- Component reference validity
- Duplicate plugin names
## Python Script
The skill includes a Python script at `marketplace_update.py` that provides command-line interface for all operations.
### Usage from Claude Code
When invoked as a skill:
1. **Read Plugin Structure**
- Scan plugin directory for components
- Extract metadata from frontmatter
- Build component lists
2. **Execute Python Script**
- Call marketplace_update.py with appropriate arguments
- Pass plugin details
- Handle success/error responses
3. **Validate Result**
- Verify marketplace.json is valid
- Confirm plugin entry is correct
- Report success or errors
## Examples
### Example 1: Add New Plugin
```python
# Plugin: golang-development
# Components: 3 agents, 1 command, 4 skills
python marketplace_update.py add \
--name "golang-development" \
--description "Go language development tools" \
--version "1.0.0" \
--category "languages" \
--keywords "golang,go,development" \
--agents "golang-pro.md,gin-pro.md,charm-pro.md" \
--commands "golang-scaffold.md" \
--skills "async-golang-patterns,golang-testing-patterns,golang-packaging,golang-performance-optimization"
```
### Example 2: Update Plugin Version
```python
# Update version and add new agent
python marketplace_update.py update \
--name "golang-development" \
--version "1.1.0" \
--add-agent "gorm-pro.md"
```
### Example 3: Remove Plugin
```python
python marketplace_update.py remove --name "obsolete-plugin"
```
## Integration with Commands
The `/claude-plugin:create` and `/claude-plugin:update` commands should invoke this skill automatically:
### From /claude-plugin:create Command
After creating a new plugin:
```
1. Scan plugin directory for components
2. Extract metadata from agent/command frontmatter
3. Invoke marketplace-update skill:
- Operation: add
- Plugin name: [from user input]
- Components: [scanned from directory]
- Metadata: [extracted from frontmatter]
```
### From /claude-plugin:update Command
After updating a plugin:
```
1. Determine what changed (added/removed/modified)
2. Invoke marketplace-update skill:
- Operation: update
- Plugin name: [from user input]
- Changes: [specific updates]
```
## Error Handling
### Plugin Already Exists (Add)
```
Error: Plugin 'plugin-name' already exists in marketplace.
Suggestion: Use 'update' operation instead.
```
### Plugin Not Found (Update/Remove)
```
Error: Plugin 'plugin-name' not found in marketplace.
Suggestion: Use 'add' operation to create it.
```
### Invalid JSON
```
Error: marketplace.json contains invalid JSON.
Suggestion: Fix JSON syntax before proceeding.
```
### Component File Missing
```
Warning: Component file './agents/agent-name.md' not found.
Suggestion: Create the file or remove from plugin entry.
```
### Validation Failure
```
Error: Marketplace validation failed:
- Plugin 'plugin-a' missing required field 'description'
- Plugin 'plugin-b' references non-existent agent 'missing.md'
Suggestion: Fix errors and validate again.
```
## Best Practices
1. **Always Validate After Changes**
- Run validate after add/update/remove
- Fix any warnings or errors
- Ensure all referenced files exist
2. **Scan Plugin Directory**
- Don't manually list components
- Scan directory to detect agents/commands/skills
- Extract metadata from frontmatter
3. **Semantic Versioning**
- Patch: Bug fixes, documentation updates (1.0.0 → 1.0.1)
- Minor: New components, enhancements (1.0.0 → 1.1.0)
- Major: Breaking changes, removals (1.0.0 → 2.0.0)
4. **Consistent Metadata**
- Keep descriptions concise (< 100 chars)
- Use relevant keywords
- Maintain consistent author information
- Use appropriate categories
5. **Backup Before Changes**
- Create backup of marketplace.json
- Test changes in development first
- Validate before committing
## Categories
Common plugin categories:
- `languages` - Language-specific tools (Python, Go, Rust, etc.)
- `development` - General development tools
- `security` - Security scanning and analysis
- `testing` - Test generation and automation
- `operations` - DevOps and operations tools
- `infrastructure` - Cloud and infrastructure tools
- `documentation` - Documentation generation
- `architecture` - Architecture and design tools
- `workflow` - Workflow orchestration
- `general` - General purpose tools
## File Structure
```
plugins/claude-plugin/skills/marketplace-update/
├── SKILL.md # This file
├── marketplace_update.py # Python implementation
└── references/ # Optional examples
└── examples.md
```
## Requirements
- Python 3.8+
- No external dependencies (uses standard library only)
- Access to `.claude-plugin/marketplace.json`
- Read/write permissions on marketplace file
## Success Criteria
After running this skill:
- ✓ marketplace.json is valid JSON
- ✓ Plugin entry is correct and complete
- ✓ All referenced files exist
- ✓ No duplicate plugin names
- ✓ Required fields are present
- ✓ Validation passes without errors

View File

@@ -0,0 +1,406 @@
#!/usr/bin/env python3
"""
Marketplace Update Script
Updates the .claude-plugin/marketplace.json file when plugins are added,
modified, or removed.
"""
import json
import os
import sys
from pathlib import Path
from typing import Dict, List, Optional, Any
import argparse
class MarketplaceUpdater:
"""Handles marketplace.json updates"""
def __init__(self, marketplace_path: str = ".claude-plugin/marketplace.json"):
self.marketplace_path = Path(marketplace_path)
self.marketplace_data: Dict[str, Any] = {}
def load(self) -> None:
"""Load marketplace.json file"""
if not self.marketplace_path.exists():
raise FileNotFoundError(f"Marketplace file not found: {self.marketplace_path}")
try:
with open(self.marketplace_path, 'r') as f:
self.marketplace_data = json.load(f)
except json.JSONDecodeError as e:
raise ValueError(f"Invalid JSON in marketplace file: {e}")
def save(self) -> None:
"""Save marketplace.json file"""
with open(self.marketplace_path, 'w') as f:
json.dump(self.marketplace_data, f, indent=2)
f.write('\n') # Add trailing newline
def add_plugin(
self,
name: str,
description: str,
version: str,
category: str = "general",
agents: Optional[List[str]] = None,
commands: Optional[List[str]] = None,
skills: Optional[List[str]] = None,
keywords: Optional[List[str]] = None,
license: str = "MIT",
strict: bool = False,
author_name: Optional[str] = None,
author_url: Optional[str] = None,
) -> None:
"""Add a new plugin to the marketplace"""
self.load()
# Check if plugin already exists
if "plugins" not in self.marketplace_data:
self.marketplace_data["plugins"] = []
existing_plugin = self._find_plugin(name)
if existing_plugin:
raise ValueError(f"Plugin '{name}' already exists in marketplace")
# Build plugin entry
plugin_entry: Dict[str, Any] = {
"name": name,
"source": f"./plugins/{name}",
"description": description,
"version": version,
"category": category,
"license": license,
"strict": strict,
}
# Add author if provided, otherwise use marketplace owner
if author_name or author_url:
plugin_entry["author"] = {}
if author_name:
plugin_entry["author"]["name"] = author_name
if author_url:
plugin_entry["author"]["url"] = author_url
elif "owner" in self.marketplace_data:
plugin_entry["author"] = {
"name": self.marketplace_data["owner"].get("name", ""),
"url": self.marketplace_data["owner"].get("url", ""),
}
# Add homepage and repository from owner if available
if "owner" in self.marketplace_data and "url" in self.marketplace_data["owner"]:
base_url = self.marketplace_data["owner"]["url"]
# Extract repo name from URL if it's a GitHub URL
if "github.com" in base_url:
plugin_entry["homepage"] = base_url
plugin_entry["repository"] = base_url
# Add optional fields
if keywords:
plugin_entry["keywords"] = keywords
if agents:
plugin_entry["agents"] = [f"./agents/{agent}" for agent in agents]
if commands:
plugin_entry["commands"] = [f"./commands/{cmd}" for cmd in commands]
if skills:
plugin_entry["skills"] = [f"./skills/{skill}" for skill in skills]
# Add plugin to marketplace
self.marketplace_data["plugins"].append(plugin_entry)
self.save()
print(f"✓ Added plugin '{name}' to marketplace")
def update_plugin(
self,
name: str,
description: Optional[str] = None,
version: Optional[str] = None,
category: Optional[str] = None,
keywords: Optional[List[str]] = None,
add_agent: Optional[str] = None,
remove_agent: Optional[str] = None,
add_command: Optional[str] = None,
remove_command: Optional[str] = None,
add_skill: Optional[str] = None,
remove_skill: Optional[str] = None,
) -> None:
"""Update an existing plugin"""
self.load()
plugin = self._find_plugin(name)
if not plugin:
raise ValueError(f"Plugin '{name}' not found in marketplace")
# Update basic fields
if description:
plugin["description"] = description
if version:
plugin["version"] = version
if category:
plugin["category"] = category
if keywords:
plugin["keywords"] = keywords
# Update agents
if add_agent:
if "agents" not in plugin:
plugin["agents"] = []
agent_path = f"./agents/{add_agent}"
if agent_path not in plugin["agents"]:
plugin["agents"].append(agent_path)
if remove_agent:
if "agents" in plugin:
agent_path = f"./agents/{remove_agent}"
if agent_path in plugin["agents"]:
plugin["agents"].remove(agent_path)
# Update commands
if add_command:
if "commands" not in plugin:
plugin["commands"] = []
cmd_path = f"./commands/{add_command}"
if cmd_path not in plugin["commands"]:
plugin["commands"].append(cmd_path)
if remove_command:
if "commands" in plugin:
cmd_path = f"./commands/{remove_command}"
if cmd_path in plugin["commands"]:
plugin["commands"].remove(cmd_path)
# Update skills
if add_skill:
if "skills" not in plugin:
plugin["skills"] = []
skill_path = f"./skills/{add_skill}"
if skill_path not in plugin["skills"]:
plugin["skills"].append(skill_path)
if remove_skill:
if "skills" in plugin:
skill_path = f"./skills/{remove_skill}"
if skill_path in plugin["skills"]:
plugin["skills"].remove(skill_path)
self.save()
print(f"✓ Updated plugin '{name}' in marketplace")
def remove_plugin(self, name: str) -> None:
"""Remove a plugin from the marketplace"""
self.load()
plugin = self._find_plugin(name)
if not plugin:
raise ValueError(f"Plugin '{name}' not found in marketplace")
self.marketplace_data["plugins"].remove(plugin)
self.save()
print(f"✓ Removed plugin '{name}' from marketplace")
def validate(self) -> bool:
"""Validate marketplace structure"""
self.load()
errors = []
warnings = []
# Check required top-level fields
required_fields = ["name", "owner", "metadata", "plugins"]
for field in required_fields:
if field not in self.marketplace_data:
errors.append(f"Missing required field: {field}")
# Validate plugins
if "plugins" in self.marketplace_data:
plugin_names = set()
for i, plugin in enumerate(self.marketplace_data["plugins"]):
# Check required plugin fields
plugin_required = ["name", "source", "description", "version"]
for field in plugin_required:
if field not in plugin:
errors.append(f"Plugin {i}: Missing required field '{field}'")
# Check for duplicate names
if "name" in plugin:
if plugin["name"] in plugin_names:
errors.append(f"Duplicate plugin name: {plugin['name']}")
plugin_names.add(plugin["name"])
# Validate component file paths
plugin_dir = Path(f"plugins/{plugin['name']}")
if "agents" in plugin:
for agent in plugin["agents"]:
agent_path = plugin_dir / agent
if not agent_path.exists():
warnings.append(
f"Plugin '{plugin['name']}': Agent file not found: {agent_path}"
)
if "commands" in plugin:
for command in plugin["commands"]:
cmd_path = plugin_dir / command
if not cmd_path.exists():
warnings.append(
f"Plugin '{plugin['name']}': Command file not found: {cmd_path}"
)
if "skills" in plugin:
for skill in plugin["skills"]:
skill_path = plugin_dir / skill / "SKILL.md"
if not skill_path.exists():
warnings.append(
f"Plugin '{plugin['name']}': Skill file not found: {skill_path}"
)
# Report results
if errors:
print("❌ Validation failed with errors:")
for error in errors:
print(f" - {error}")
else:
print("✓ Validation passed with no errors")
if warnings:
print("\n⚠️ Warnings:")
for warning in warnings:
print(f" - {warning}")
return len(errors) == 0
def _find_plugin(self, name: str) -> Optional[Dict[str, Any]]:
"""Find a plugin by name"""
if "plugins" not in self.marketplace_data:
return None
for plugin in self.marketplace_data["plugins"]:
if plugin.get("name") == name:
return plugin
return None
def main():
"""Main entry point"""
parser = argparse.ArgumentParser(description="Update marketplace.json")
subparsers = parser.add_subparsers(dest="command", help="Command to execute")
# Add command
add_parser = subparsers.add_parser("add", help="Add a new plugin")
add_parser.add_argument("--name", required=True, help="Plugin name")
add_parser.add_argument("--description", required=True, help="Plugin description")
add_parser.add_argument("--version", required=True, help="Plugin version")
add_parser.add_argument("--category", default="general", help="Plugin category")
add_parser.add_argument("--agents", help="Comma-separated list of agent files")
add_parser.add_argument("--commands", help="Comma-separated list of command files")
add_parser.add_argument("--skills", help="Comma-separated list of skill directories")
add_parser.add_argument("--keywords", help="Comma-separated list of keywords")
add_parser.add_argument("--license", default="MIT", help="License type")
add_parser.add_argument("--strict", action="store_true", help="Enable strict mode")
add_parser.add_argument("--author-name", help="Author name")
add_parser.add_argument("--author-url", help="Author URL")
add_parser.add_argument(
"--marketplace",
default=".claude-plugin/marketplace.json",
help="Path to marketplace.json",
)
# Update command
update_parser = subparsers.add_parser("update", help="Update an existing plugin")
update_parser.add_argument("--name", required=True, help="Plugin name")
update_parser.add_argument("--description", help="Updated description")
update_parser.add_argument("--version", help="Updated version")
update_parser.add_argument("--category", help="Updated category")
update_parser.add_argument("--keywords", help="Updated keywords (comma-separated)")
update_parser.add_argument("--add-agent", help="Agent file to add")
update_parser.add_argument("--remove-agent", help="Agent file to remove")
update_parser.add_argument("--add-command", help="Command file to add")
update_parser.add_argument("--remove-command", help="Command file to remove")
update_parser.add_argument("--add-skill", help="Skill directory to add")
update_parser.add_argument("--remove-skill", help="Skill directory to remove")
update_parser.add_argument(
"--marketplace",
default=".claude-plugin/marketplace.json",
help="Path to marketplace.json",
)
# Remove command
remove_parser = subparsers.add_parser("remove", help="Remove a plugin")
remove_parser.add_argument("--name", required=True, help="Plugin name")
remove_parser.add_argument(
"--marketplace",
default=".claude-plugin/marketplace.json",
help="Path to marketplace.json",
)
# Validate command
validate_parser = subparsers.add_parser("validate", help="Validate marketplace.json")
validate_parser.add_argument(
"--marketplace",
default=".claude-plugin/marketplace.json",
help="Path to marketplace.json",
)
args = parser.parse_args()
if not args.command:
parser.print_help()
sys.exit(1)
try:
updater = MarketplaceUpdater(
getattr(args, "marketplace", ".claude-plugin/marketplace.json")
)
if args.command == "add":
updater.add_plugin(
name=args.name,
description=args.description,
version=args.version,
category=args.category,
agents=args.agents.split(",") if args.agents else None,
commands=args.commands.split(",") if args.commands else None,
skills=args.skills.split(",") if args.skills else None,
keywords=args.keywords.split(",") if args.keywords else None,
license=args.license,
strict=args.strict,
author_name=args.author_name,
author_url=args.author_url,
)
elif args.command == "update":
updater.update_plugin(
name=args.name,
description=args.description,
version=args.version,
category=args.category,
keywords=args.keywords.split(",") if args.keywords else None,
add_agent=args.add_agent,
remove_agent=args.remove_agent,
add_command=args.add_command,
remove_command=args.remove_command,
add_skill=args.add_skill,
remove_skill=args.remove_skill,
)
elif args.command == "remove":
updater.remove_plugin(name=args.name)
elif args.command == "validate":
if not updater.validate():
sys.exit(1)
except Exception as e:
print(f"❌ Error: {e}", file=sys.stderr)
sys.exit(1)
if __name__ == "__main__":
main()