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