Initial commit
This commit is contained in:
21
.claude-plugin/plugin.json
Normal file
21
.claude-plugin/plugin.json
Normal 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
3
README.md
Normal 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
345
agents/plugin-architect.md
Normal 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
275
commands/create.md
Normal 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
659
commands/documentation.md
Normal 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
430
commands/update.md
Normal 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
89
plugin.lock.json
Normal 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": []
|
||||
}
|
||||
}
|
||||
467
skills/documentation-update/SKILL.md
Normal file
467
skills/documentation-update/SKILL.md
Normal 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
|
||||
73
skills/documentation-update/assets/agent-skills.md.j2
Normal file
73
skills/documentation-update/assets/agent-skills.md.j2
Normal 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 }}*
|
||||
64
skills/documentation-update/assets/agents.md.j2
Normal file
64
skills/documentation-update/assets/agents.md.j2
Normal 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 }}*
|
||||
88
skills/documentation-update/assets/plugins.md.j2
Normal file
88
skills/documentation-update/assets/plugins.md.j2
Normal 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 }}*
|
||||
250
skills/documentation-update/assets/usage.md.j2
Normal file
250
skills/documentation-update/assets/usage.md.j2
Normal 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 }}*
|
||||
476
skills/documentation-update/doc_generator.py
Executable file
476
skills/documentation-update/doc_generator.py
Executable 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()
|
||||
357
skills/marketplace-update/SKILL.md
Normal file
357
skills/marketplace-update/SKILL.md
Normal 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
|
||||
406
skills/marketplace-update/marketplace_update.py
Executable file
406
skills/marketplace-update/marketplace_update.py
Executable 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()
|
||||
Reference in New Issue
Block a user