Initial commit
This commit is contained in:
58
skills/build-assistant/README.md
Normal file
58
skills/build-assistant/README.md
Normal file
@@ -0,0 +1,58 @@
|
||||
|
||||
## Build Scripts
|
||||
|
||||
The skill includes helper scripts for creating plugin and skill structures:
|
||||
|
||||
### create-plugin-structure.py
|
||||
Creates the mechanical directory structure for a new Claude Code plugin with manifest.
|
||||
|
||||
**Usage:**
|
||||
```bash
|
||||
python .claude/skills/build-assistant/scripts/create-plugin-structure.py <plugin-name>
|
||||
```
|
||||
|
||||
**Creates:**
|
||||
- `.claude-plugin/plugin.json` - Plugin manifest
|
||||
- `commands/`, `skills/`, `agents/`, `hooks/` directories
|
||||
- Basic README.md
|
||||
|
||||
### create-skill-structures.py
|
||||
Creates skill directory structures for existing plugins.
|
||||
|
||||
**Usage:**
|
||||
```bash
|
||||
python .claude/skills/build-assistant/scripts/create-skill-structures.py [--dry-run]
|
||||
```
|
||||
|
||||
**What it does:**
|
||||
- Scans marketplace plugins
|
||||
- Creates `skills/<skill-name>/` directories
|
||||
- Sets up proper structure for SKILL.md
|
||||
|
||||
### Validation Scripts
|
||||
|
||||
- `validate-agent.sh` - Validates agent frontmatter and structure
|
||||
- `validate-command.sh` - Validates slash command format
|
||||
- `validate-skill.sh` - Validates SKILL.md structure
|
||||
- `validate-plugin.sh` - Validates plugin manifest and directories
|
||||
- `test-build-system.sh` - Comprehensive build system tests
|
||||
|
||||
## Template Structure
|
||||
|
||||
All templates follow standardized patterns:
|
||||
|
||||
```
|
||||
templates/
|
||||
├── agents/
|
||||
│ ├── agent.md.template # Agent template
|
||||
│ └── agent-example.md # Example agent
|
||||
├── commands/
|
||||
│ ├── command.md.template # Command template
|
||||
│ └── command-example.md # Example command
|
||||
├── skills/
|
||||
│ ├── SKILL.md.template # Skill template
|
||||
│ └── skill-example/SKILL.md # Example skill
|
||||
└── plugins/
|
||||
├── plugin.json.template # Plugin manifest template
|
||||
└── example-plugin/ # Complete plugin example
|
||||
```
|
||||
121
skills/build-assistant/SKILL.md
Normal file
121
skills/build-assistant/SKILL.md
Normal file
@@ -0,0 +1,121 @@
|
||||
---
|
||||
name: Build-Assistant
|
||||
description: Build Claude Code framework components (agents, slash commands, skills, plugins) following standardized templates. Use when creating new agents, commands, skills, or plugins for the multiagent framework.
|
||||
allowed-tools: Read, Write, Bash
|
||||
---
|
||||
|
||||
# Build-Assistant
|
||||
|
||||
This skill provides templates, validation scripts, and documentation for building Claude Code framework components following the multiagent framework standards.
|
||||
|
||||
## Instructions
|
||||
|
||||
### When Creating a New Agent
|
||||
|
||||
1. Read the agent template: `templates/agents/agent.md.template`
|
||||
2. Read the agent example: `templates/agents/agent-example.md`
|
||||
3. Read documentation: `docs/claude-code-agents.md` (if available)
|
||||
4. Create agent file with:
|
||||
- Proper frontmatter (name, description, tools, model, color)
|
||||
- Clear process steps
|
||||
- Key rules and output format
|
||||
5. Validate using: `scripts/validate-agent.sh <agent-file>`
|
||||
|
||||
### When Creating a Slash Command
|
||||
|
||||
1. Read the command template: `templates/commands/command.md.template`
|
||||
2. Read the command example: `templates/commands/command-example.md`
|
||||
3. Read documentation: `docs/01-claude-code-slash-commands.md`
|
||||
4. Create command file with:
|
||||
- Frontmatter (description, argument-hint, allowed-tools)
|
||||
- Task invocation with proper subagent_type
|
||||
- Success criteria and notes
|
||||
5. Validate using: `scripts/validate-command.sh <command-file>`
|
||||
|
||||
### When Creating a Skill
|
||||
|
||||
1. Read the skill template: `templates/skills/SKILL.md.template`
|
||||
2. Read the skill example: `templates/skills/skill-example/SKILL.md`
|
||||
3. Read documentation: `docs/02-claude-code-skills.md`
|
||||
4. Read decision guide: `docs/04-skills-vs-commands.md`
|
||||
5. Create SKILL.md with:
|
||||
- Frontmatter with "Use when" trigger context
|
||||
- Step-by-step instructions
|
||||
- Concrete examples
|
||||
- Requirements
|
||||
6. Validate using: `scripts/validate-skill.sh <skill-directory>`
|
||||
|
||||
### When Creating a Plugin
|
||||
|
||||
1. Read the plugin template: `templates/plugins/plugin.json.template`
|
||||
2. Read the plugin example: `templates/plugins/example-plugin/`
|
||||
3. Read documentation: `docs/03-claude-code-plugins.md`
|
||||
4. Create plugin structure with:
|
||||
- `.claude-plugin/plugin.json` manifest
|
||||
- README.md with components list
|
||||
- commands/, skills/, agents/ as needed
|
||||
5. Validate using: `scripts/validate-plugin.sh <plugin-directory>`
|
||||
|
||||
### Choosing Between Skills and Commands
|
||||
|
||||
Consult `docs/04-skills-vs-commands.md` to decide:
|
||||
- **Use Skill** when: Claude should discover it automatically, complex capability, multiple supporting files
|
||||
- **Use Command** when: User explicitly triggers it, simple orchestration, workflow shortcut
|
||||
|
||||
## Available Resources
|
||||
|
||||
### Templates
|
||||
|
||||
**Agents:**
|
||||
- `templates/agents/agent.md.template` - Standard agent template with frontmatter
|
||||
- `templates/agents/agent-example.md` - Complete working example
|
||||
|
||||
**Commands:**
|
||||
- `templates/commands/command.md.template` - Standard slash command template
|
||||
- `templates/commands/command-example.md` - Complete working example
|
||||
|
||||
**Skills:**
|
||||
- `templates/skills/SKILL.md.template` - Standard skill template
|
||||
- `templates/skills/skill-example/SKILL.md` - Git commit helper example
|
||||
- `templates/skills/README.md` - Skills template documentation
|
||||
|
||||
**Plugins:**
|
||||
- `templates/plugins/plugin.json.template` - Plugin manifest template
|
||||
- `templates/plugins/example-plugin/` - Complete plugin example with commands and skills
|
||||
|
||||
### Validation Scripts
|
||||
|
||||
- `scripts/validate-agent.sh` - Validates agent frontmatter and structure
|
||||
- `scripts/validate-command.sh` - Validates command frontmatter and structure
|
||||
- `scripts/validate-skill.sh` - Validates SKILL.md frontmatter and "Use when" context
|
||||
- `scripts/validate-plugin.sh` - Validates plugin manifest and structure
|
||||
- `scripts/test-build-system.sh` - Comprehensive build system test suite
|
||||
|
||||
### Documentation
|
||||
|
||||
- `docs/01-claude-code-slash-commands.md` - Slash command reference
|
||||
- `docs/02-claude-code-skills.md` - Skills reference with frontmatter fields
|
||||
- `docs/03-claude-code-plugins.md` - Plugin architecture and structure
|
||||
- `docs/04-skills-vs-commands.md` - Decision guide for choosing component type
|
||||
|
||||
## Requirements
|
||||
|
||||
- Templates must exist in `templates/` directory
|
||||
- Validation scripts must be executable
|
||||
- Documentation files should be available in `docs/`
|
||||
- Follow Claude Code standards for frontmatter
|
||||
- Include "Use when" context in skill descriptions
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Always validate** - Run validation scripts after creation
|
||||
2. **Follow templates** - Use provided templates as starting point
|
||||
3. **Read examples** - Study working examples before creating new components
|
||||
4. **Check documentation** - Consult docs for standards and patterns
|
||||
5. **Test thoroughly** - Use test-build-system.sh for comprehensive testing
|
||||
|
||||
---
|
||||
|
||||
**Generated from**: multiagent-build plugin build-assistant skill
|
||||
**Purpose**: Standardize framework component creation across multiagent ecosystem
|
||||
**Load when**: Creating agents, commands, skills, or plugins
|
||||
328
skills/build-assistant/examples.md
Normal file
328
skills/build-assistant/examples.md
Normal file
@@ -0,0 +1,328 @@
|
||||
# Build-Assistant - Examples
|
||||
|
||||
## Complete Workflow Examples
|
||||
|
||||
### Example 1: Building a New Agent from Scratch
|
||||
|
||||
**Scenario**: Create an agent that analyzes code complexity
|
||||
|
||||
**Steps**:
|
||||
|
||||
1. **Read the template**
|
||||
```bash
|
||||
Read: templates/agents/agent.md.template
|
||||
```
|
||||
|
||||
2. **Study the example**
|
||||
```bash
|
||||
Read: templates/agents/agent-example.md
|
||||
```
|
||||
|
||||
3. **Create the agent file**
|
||||
```markdown
|
||||
---
|
||||
name: complexity-analyzer
|
||||
description: Analyzes code complexity and suggests improvements
|
||||
tools: Read, Grep, Bash
|
||||
model: claude-sonnet-4-5-20250929
|
||||
color: purple
|
||||
---
|
||||
|
||||
You are a code complexity analyzer...
|
||||
|
||||
## Your Process
|
||||
|
||||
### Step 1: Scan Codebase
|
||||
...
|
||||
```
|
||||
|
||||
4. **Validate the agent**
|
||||
```bash
|
||||
scripts/validate-agent.sh agents/complexity-analyzer.md
|
||||
# ✅ Agent validation passed
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Example 2: Creating a Slash Command
|
||||
|
||||
**Scenario**: Create a command to run complexity analysis
|
||||
|
||||
**Steps**:
|
||||
|
||||
1. **Read the documentation**
|
||||
```bash
|
||||
Read: docs/01-claude-code-slash-commands.md
|
||||
```
|
||||
|
||||
2. **Read the template**
|
||||
```bash
|
||||
Read: templates/commands/command.md.template
|
||||
```
|
||||
|
||||
3. **Create the command**
|
||||
```markdown
|
||||
---
|
||||
description: Analyze code complexity and generate report
|
||||
argument-hint: [target-directory]
|
||||
---
|
||||
|
||||
User input: $ARGUMENTS
|
||||
|
||||
Task
|
||||
```
|
||||
|
||||
4. **Validate the command**
|
||||
```bash
|
||||
scripts/validate-command.sh commands/analyze-complexity.md
|
||||
# ✅ Command validation passed
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Example 3: Building a Skill with Supporting Files
|
||||
|
||||
**Scenario**: Create a skill for database design
|
||||
|
||||
**Steps**:
|
||||
|
||||
1. **Decide it should be a skill**
|
||||
```bash
|
||||
Read: docs/04-skills-vs-commands.md
|
||||
# Decision: Skill (automatic discovery, complex capability)
|
||||
```
|
||||
|
||||
2. **Create directory structure**
|
||||
```bash
|
||||
mkdir -p skills/database-designer/templates
|
||||
mkdir -p skills/database-designer/scripts
|
||||
```
|
||||
|
||||
3. **Read the template**
|
||||
```bash
|
||||
Read: templates/skills/SKILL.md.template
|
||||
```
|
||||
|
||||
4. **Create SKILL.md**
|
||||
```markdown
|
||||
---
|
||||
name: Database Designer
|
||||
description: Design database schemas with normalization and optimization. Use when designing databases, creating schemas, or working with ERDs.
|
||||
allowed-tools: Read, Write, Bash
|
||||
---
|
||||
|
||||
# Database Designer
|
||||
|
||||
## Instructions
|
||||
|
||||
1. Analyze requirements to identify entities
|
||||
2. Define relationships and cardinality
|
||||
3. Apply normalization (1NF through 3NF)
|
||||
4. Generate SQL schema files
|
||||
5. Create migration scripts
|
||||
|
||||
## Available Resources
|
||||
|
||||
- templates/schema.sql - SQL schema template
|
||||
- templates/migration.sql - Migration template
|
||||
- scripts/generate-erd.py - ERD diagram generator
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
5. **Add supporting files**
|
||||
```bash
|
||||
# Create template
|
||||
Write: skills/database-designer/templates/schema.sql
|
||||
|
||||
# Create script
|
||||
Write: skills/database-designer/scripts/generate-erd.py
|
||||
```
|
||||
|
||||
6. **Validate the skill**
|
||||
```bash
|
||||
scripts/validate-skill.sh skills/database-designer/
|
||||
# ✅ Skill validation passed
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Example 4: Building a Complete Plugin
|
||||
|
||||
**Scenario**: Create a testing plugin with commands, agents, and skills
|
||||
|
||||
**Steps**:
|
||||
|
||||
1. **Read plugin documentation**
|
||||
```bash
|
||||
Read: docs/03-claude-code-plugins.md
|
||||
```
|
||||
|
||||
2. **Study the example**
|
||||
```bash
|
||||
Read: templates/plugins/example-plugin/
|
||||
```
|
||||
|
||||
3. **Create plugin structure**
|
||||
```bash
|
||||
mkdir -p multiagent-testing/.claude-plugin
|
||||
mkdir -p multiagent-testing/{commands,agents,skills,docs}
|
||||
```
|
||||
|
||||
4. **Create manifest**
|
||||
```json
|
||||
{
|
||||
"name": "multiagent-testing"
|
||||
"version": "1.0.0"
|
||||
"description": "Comprehensive testing tools for multiagent projects"
|
||||
"components": {
|
||||
"commands": 3
|
||||
"agents": 2
|
||||
"skills": 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
5. **Add commands**
|
||||
```bash
|
||||
# /testing:unit
|
||||
Write: multiagent-testing/commands/unit.md
|
||||
|
||||
# /testing:integration
|
||||
Write: multiagent-testing/commands/integration.md
|
||||
|
||||
# /testing:e2e
|
||||
Write: multiagent-testing/commands/e2e.md
|
||||
```
|
||||
|
||||
6. **Add agents**
|
||||
```bash
|
||||
# test-generator agent
|
||||
Write: multiagent-testing/agents/test-generator.md
|
||||
|
||||
# test-runner agent
|
||||
Write: multiagent-testing/agents/test-runner.md
|
||||
```
|
||||
|
||||
7. **Add skill**
|
||||
```bash
|
||||
# testing-assistant skill
|
||||
mkdir -p multiagent-testing/skills/testing-assistant
|
||||
Write: multiagent-testing/skills/testing-assistant/SKILL.md
|
||||
```
|
||||
|
||||
8. **Create README**
|
||||
```markdown
|
||||
# multiagent-testing
|
||||
|
||||
Comprehensive testing tools for multiagent projects.
|
||||
|
||||
## Components
|
||||
|
||||
- **Commands**: 3 slash commands
|
||||
- **Agents**: 2 specialized agents
|
||||
- **Skills**: 1 testing skill
|
||||
|
||||
## Commands
|
||||
|
||||
- `/testing:unit` - Run unit tests
|
||||
- `/testing:integration` - Run integration tests
|
||||
- `/testing:e2e` - Run end-to-end tests
|
||||
```
|
||||
|
||||
9. **Validate the plugin**
|
||||
```bash
|
||||
scripts/validate-plugin.sh multiagent-testing/
|
||||
# ✅ Plugin validation passed
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Example 5: Deciding Between Skill and Command
|
||||
|
||||
**Scenario 1**: Git commit helper
|
||||
|
||||
**Analysis**:
|
||||
```markdown
|
||||
Question: Should user explicitly trigger it?
|
||||
- NO - User might just ask "help me write a commit"
|
||||
|
||||
Question: Should Claude discover automatically?
|
||||
- YES - When user mentions "commit" or "git commit"
|
||||
|
||||
Decision: SKILL
|
||||
- Create skill with "Use when writing commit messages"
|
||||
- Claude activates when context matches
|
||||
```
|
||||
|
||||
**Scenario 2**: Deployment workflow
|
||||
|
||||
**Analysis**:
|
||||
```markdown
|
||||
Question: Should user explicitly trigger it?
|
||||
- YES - Deployment is critical, needs explicit control
|
||||
|
||||
Question: Is it a sequential workflow?
|
||||
- YES - Multiple steps that user controls
|
||||
|
||||
Decision: COMMAND
|
||||
- Create /deploy command
|
||||
- User explicitly invokes for safety
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Example 6: Using Validation Scripts
|
||||
|
||||
**Running Individual Validations**:
|
||||
|
||||
```bash
|
||||
# Validate an agent
|
||||
scripts/validate-agent.sh agents/my-agent.md
|
||||
# ✅ Agent validation passed
|
||||
|
||||
# Validate a command
|
||||
scripts/validate-command.sh commands/my-command.md
|
||||
# ✅ Command validation passed
|
||||
|
||||
# Validate a skill
|
||||
scripts/validate-skill.sh skills/my-skill/
|
||||
# ⚠️ WARNING: Description should include 'Use when' trigger context
|
||||
# (Fix required)
|
||||
|
||||
# Validate a plugin
|
||||
scripts/validate-plugin.sh plugins/my-plugin/
|
||||
# ❌ ERROR: Missing .claude-plugin/plugin.json
|
||||
# (Fix required)
|
||||
```
|
||||
|
||||
**Running Comprehensive Tests**:
|
||||
|
||||
```bash
|
||||
# Test entire build system
|
||||
scripts/test-build-system.sh
|
||||
# Running comprehensive build system tests...
|
||||
# ✅ All validations passed
|
||||
# ✅ All templates exist
|
||||
# ✅ All scripts executable
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference: Build Workflows
|
||||
|
||||
### Agent Workflow
|
||||
1. Read template → 2. Study example → 3. Create agent → 4. Validate
|
||||
|
||||
### Command Workflow
|
||||
1. Read docs → 2. Read template → 3. Create command → 4. Validate
|
||||
|
||||
### Skill Workflow
|
||||
1. Decide vs command → 2. Read template → 3. Create skill → 4. Add resources → 5. Validate
|
||||
|
||||
### Plugin Workflow
|
||||
1. Read docs → 2. Study example → 3. Create structure → 4. Add components → 5. Create README → 6. Validate
|
||||
|
||||
---
|
||||
|
||||
**Use these examples as templates when creating your own components!**
|
||||
200
skills/build-assistant/reference.md
Normal file
200
skills/build-assistant/reference.md
Normal file
@@ -0,0 +1,200 @@
|
||||
# Build-Assistant - Reference
|
||||
|
||||
## Template Variables
|
||||
|
||||
### Agent Template Variables
|
||||
- `{{AGENT_NAME}}` - Kebab-case agent identifier
|
||||
- `{{DESCRIPTION}}` - Brief description of agent purpose
|
||||
- `{{TOOLS}}` - Comma-separated list of allowed tools
|
||||
- `{{MODEL}}` - Model identifier (e.g., claude-sonnet-4-5-20250929)
|
||||
- `{{COLOR}}` - Agent color for UI (blue, green, purple, etc.)
|
||||
|
||||
### Command Template Variables
|
||||
- `{{COMMAND_NAME}}` - Command name without slash prefix
|
||||
- `{{DESCRIPTION}}` - Brief description of command purpose
|
||||
- `{{ARGUMENT_HINT}}` - Syntax hint for arguments
|
||||
- `{{ALLOWED_TOOLS}}` - Comma-separated list of allowed tools
|
||||
- `{{SUBAGENT_TYPE}}` - Type of subagent to invoke
|
||||
|
||||
### Skill Template Variables
|
||||
- `{{SKILL_NAME}}` - Display name of skill
|
||||
- `{{DESCRIPTION}}` - What skill does + "Use when" trigger
|
||||
- `{{ALLOWED_TOOLS}}` - Optional tools restriction
|
||||
- `{{TRIGGER_CONTEXT}}` - Keywords that trigger skill
|
||||
- `{{STEP_BY_STEP_INSTRUCTIONS}}` - Detailed usage guide
|
||||
- `{{CONCRETE_EXAMPLES}}` - Real-world usage scenarios
|
||||
- `{{REQUIREMENTS}}` - Prerequisites or dependencies
|
||||
|
||||
### Plugin Template Variables
|
||||
- `{{PLUGIN_NAME}}` - Plugin identifier (kebab-case)
|
||||
- `{{DISPLAY_NAME}}` - Human-readable plugin name
|
||||
- `{{VERSION}}` - Semantic version (e.g., 1.0.0)
|
||||
- `{{DESCRIPTION}}` - Plugin purpose and capabilities
|
||||
- `{{COMMANDS_COUNT}}` - Number of slash commands
|
||||
- `{{AGENTS_COUNT}}` - Number of agents
|
||||
- `{{SKILLS_COUNT}}` - Number of skills
|
||||
|
||||
## File Paths
|
||||
|
||||
### Template Locations
|
||||
- Agents: `~/.claude/marketplaces/multiagent-dev/plugins/multiagent-build/skills/build-assistant/templates/agents/`
|
||||
- Commands: `~/.claude/marketplaces/multiagent-dev/plugins/multiagent-build/skills/build-assistant/templates/commands/`
|
||||
- Skills: `~/.claude/marketplaces/multiagent-dev/plugins/multiagent-build/skills/build-assistant/templates/skills/`
|
||||
- Plugins: `~/.claude/marketplaces/multiagent-dev/plugins/multiagent-build/skills/build-assistant/templates/plugins/`
|
||||
|
||||
### Script Locations
|
||||
- Validation: `~/.claude/marketplaces/multiagent-dev/plugins/multiagent-build/skills/build-assistant/scripts/`
|
||||
|
||||
### Documentation Locations
|
||||
- Build docs: `~/.claude/marketplaces/multiagent-dev/plugins/multiagent-build/docs/`
|
||||
|
||||
## Validation Requirements
|
||||
|
||||
### Agent Validation
|
||||
- Must have frontmatter with: name, description, tools, model, color
|
||||
- Description must be clear and concise
|
||||
- Tools must be comma-separated list
|
||||
- Model must be valid Claude model identifier
|
||||
- Color must be valid color name
|
||||
|
||||
### Command Validation
|
||||
- Must have frontmatter with: description, argument-hint
|
||||
- Must invoke Task tool with subagent_type
|
||||
- Must include success criteria
|
||||
- Argument hint must show expected syntax
|
||||
|
||||
### Skill Validation
|
||||
- Must have SKILL.md file
|
||||
- Must have frontmatter with: name, description
|
||||
- Description must include "Use when" trigger context
|
||||
- Must have Instructions section
|
||||
- Should have Examples section
|
||||
|
||||
### Plugin Validation
|
||||
- Must have `.claude-plugin/plugin.json` manifest
|
||||
- Manifest must have: name, version, description
|
||||
- Must have README.md
|
||||
- Must have at least one component (command/agent/skill)
|
||||
- Component counts must match actual components
|
||||
|
||||
## Component Scopes
|
||||
|
||||
### Personal Scope
|
||||
- Location: `$HOME/.claude/`
|
||||
- Usage: User-specific components
|
||||
- Not shared across projects
|
||||
- Ideal for personal workflows
|
||||
|
||||
### Project Scope
|
||||
- Location: `./.claude/`
|
||||
- Usage: Project-specific components
|
||||
- Shared via git repository
|
||||
- Ideal for team workflows
|
||||
|
||||
### Plugin Scope
|
||||
- Location: `$HOME/.claude/marketplaces/{marketplace}/{plugin}/`
|
||||
- Usage: Reusable components
|
||||
- Distributed via marketplace
|
||||
- Ideal for framework extensions
|
||||
|
||||
## Agent Specifications
|
||||
|
||||
### Required Frontmatter Fields
|
||||
```yaml
|
||||
name: agent-identifier
|
||||
description: Brief purpose description
|
||||
tools: Read, Write, Bash
|
||||
model: claude-sonnet-4-5-20250929
|
||||
color: blue
|
||||
```
|
||||
|
||||
### Optional Frontmatter Fields
|
||||
```yaml
|
||||
project: true # Project-scoped agent
|
||||
```
|
||||
|
||||
## Command Specifications
|
||||
|
||||
### Required Frontmatter Fields
|
||||
```yaml
|
||||
description: Brief command description
|
||||
argument-hint: [required-arg] [optional-arg]
|
||||
```
|
||||
|
||||
### Optional Frontmatter Fields
|
||||
```yaml
|
||||
allowed-tools: Read(*), Write(*), Bash(*) # Tool permissions
|
||||
```
|
||||
|
||||
## Skill Specifications
|
||||
|
||||
### Required Frontmatter Fields
|
||||
```yaml
|
||||
name: Skill Display Name
|
||||
description: What it does. Use when trigger context.
|
||||
```
|
||||
|
||||
### Optional Frontmatter Fields
|
||||
```yaml
|
||||
allowed-tools: Read, Write, Bash # Restrict tools when active
|
||||
```
|
||||
|
||||
## Plugin Manifest Schema
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "plugin-identifier"
|
||||
"version": "1.0.0"
|
||||
"description": "Plugin purpose and capabilities"
|
||||
"components": {
|
||||
"commands": 0
|
||||
"agents": 0
|
||||
"skills": 0
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Naming Conventions
|
||||
- Agents: kebab-case (e.g., `skill-builder`)
|
||||
- Commands: kebab-case without slash (e.g., `build-skill`)
|
||||
- Skills: Title Case (e.g., `Build Assistant`)
|
||||
- Plugins: kebab-case (e.g., `multiagent-build`)
|
||||
|
||||
### Description Writing
|
||||
- Start with action verb
|
||||
- Keep under 100 characters
|
||||
- Include "Use when" for skills
|
||||
- Mention key capabilities
|
||||
- Avoid technical jargon
|
||||
|
||||
### File Organization
|
||||
```
|
||||
enterprise-plugin/
|
||||
├── .claude-plugin/ # Metadata directory
|
||||
│ └── plugin.json # Required: plugin manifest
|
||||
├── commands/ # Default command location
|
||||
│ ├── status.md
|
||||
│ └── logs.md
|
||||
├── agents/ # Default agent location
|
||||
│ ├── security-reviewer.md
|
||||
│ ├── performance-tester.md
|
||||
│ └── compliance-checker.md
|
||||
├── skills/ # Agent Skills
|
||||
│ ├── code-reviewer/
|
||||
│ │ └── SKILL.md
|
||||
│ └── pdf-processor/
|
||||
│ ├── SKILL.md
|
||||
│ └── scripts/
|
||||
├── hooks/ # Hook configurations
|
||||
│ ├── hooks.json # Main hook config
|
||||
│ └── security-hooks.json # Additional hooks
|
||||
├── .mcp.json # MCP server definitions
|
||||
├── scripts/ # Hook and utility scripts
|
||||
│ ├── security-scan.sh
|
||||
│ ├── format-code.py
|
||||
│ └── deploy.js
|
||||
├── LICENSE # License file
|
||||
└── CHANGELOG.md # Version history
|
||||
```
|
||||
203
skills/build-assistant/scripts/add-skill-instructions.sh
Executable file
203
skills/build-assistant/scripts/add-skill-instructions.sh
Executable file
@@ -0,0 +1,203 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Script to add skill availability instructions to all agents and commands
|
||||
# Usage: bash add-skill-instructions.sh (can be run from anywhere)
|
||||
|
||||
set -e
|
||||
|
||||
# Find marketplace root by looking for plugins/ directory
|
||||
find_marketplace_root() {
|
||||
local current_dir="$PWD"
|
||||
|
||||
# Check if we're already in marketplace root
|
||||
if [ -d "$current_dir/plugins" ] && [ -d "$current_dir/scripts" ]; then
|
||||
echo "$current_dir"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Check if script is in scripts/ subdirectory
|
||||
local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
local parent_dir="$(dirname "$script_dir")"
|
||||
if [ -d "$parent_dir/plugins" ] && [ -d "$parent_dir/scripts" ]; then
|
||||
echo "$parent_dir"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Search upwards for marketplace root
|
||||
while [ "$current_dir" != "/" ]; do
|
||||
if [ -d "$current_dir/plugins" ] && [ -d "$current_dir/scripts" ] && [ -f "$current_dir/.claude-plugin/marketplace.json" ]; then
|
||||
echo "$current_dir"
|
||||
return 0
|
||||
fi
|
||||
current_dir="$(dirname "$current_dir")"
|
||||
done
|
||||
|
||||
echo "ERROR: Could not find ai-dev-marketplace root directory" >&2
|
||||
echo "Please run this script from within the marketplace directory" >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
MARKETPLACE_DIR=$(find_marketplace_root)
|
||||
if [ $? -ne 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd "$MARKETPLACE_DIR"
|
||||
echo "📍 Working in: $MARKETPLACE_DIR"
|
||||
echo ""
|
||||
|
||||
echo "🔍 Adding skill availability instructions to agents and commands..."
|
||||
echo ""
|
||||
|
||||
# Counters
|
||||
agents_updated=0
|
||||
commands_updated=0
|
||||
agents_skipped=0
|
||||
commands_skipped=0
|
||||
|
||||
# Function to get skills for a plugin
|
||||
get_plugin_skills() {
|
||||
local plugin_path="$1"
|
||||
local skills_dir="$plugin_path/skills"
|
||||
|
||||
if [ -d "$skills_dir" ]; then
|
||||
# List all skill directories
|
||||
ls "$skills_dir" 2>/dev/null | sort
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to add skills section to a file
|
||||
add_skills_section() {
|
||||
local file="$1"
|
||||
local plugin_name="$2"
|
||||
local plugin_path="plugins/$plugin_name"
|
||||
|
||||
# Check if file already has skill instructions
|
||||
if grep -q "## Available Skills" "$file"; then
|
||||
return 1 # Skip
|
||||
fi
|
||||
|
||||
# Get skills for this plugin
|
||||
local skills=$(get_plugin_skills "$plugin_path")
|
||||
local skill_count=$(echo "$skills" | grep -v "^$" | wc -l)
|
||||
|
||||
if [ "$skill_count" -eq 0 ]; then
|
||||
return 1 # No skills, skip
|
||||
fi
|
||||
|
||||
# Build skill list
|
||||
local skill_list=""
|
||||
while IFS= read -r skill; do
|
||||
if [ -n "$skill" ]; then
|
||||
# Read skill description from SKILL.md if available
|
||||
local skill_file="$plugin_path/skills/$skill/SKILL.md"
|
||||
if [ -f "$skill_file" ]; then
|
||||
local description=$(grep "^description:" "$skill_file" | sed 's/description: //')
|
||||
skill_list="${skill_list}- **$skill**: $description
|
||||
"
|
||||
else
|
||||
skill_list="${skill_list}- **$skill**
|
||||
"
|
||||
fi
|
||||
fi
|
||||
done <<< "$skills"
|
||||
|
||||
# Create skills section
|
||||
local skills_section="## Available Skills
|
||||
|
||||
This $(basename $(dirname "$file")) has access to the following skills from the $plugin_name plugin:
|
||||
|
||||
$skill_list
|
||||
**To use a skill:**
|
||||
\`\`\`
|
||||
!{skill skill-name}
|
||||
\`\`\`
|
||||
|
||||
Use skills when you need:
|
||||
- Domain-specific templates and examples
|
||||
- Validation scripts and automation
|
||||
- Best practices and patterns
|
||||
- Configuration generators
|
||||
|
||||
Skills provide pre-built resources to accelerate your work.
|
||||
|
||||
---
|
||||
|
||||
"
|
||||
|
||||
# Find insertion point (after security section, before main content)
|
||||
# Look for the first ## that's not "Security"
|
||||
local line_num=$(grep -n "^## " "$file" | grep -v "## Security" | grep -v "## Available Skills" | head -1 | cut -d: -f1)
|
||||
|
||||
if [ -z "$line_num" ]; then
|
||||
# No section found, add after frontmatter and security
|
||||
line_num=$(grep -n "^---$" "$file" | tail -1 | cut -d: -f1)
|
||||
line_num=$((line_num + 1))
|
||||
|
||||
# Skip past security section
|
||||
local security_end=$(tail -n +$line_num "$file" | grep -n "^---$" | head -1 | cut -d: -f1)
|
||||
if [ -n "$security_end" ]; then
|
||||
line_num=$((line_num + security_end))
|
||||
fi
|
||||
fi
|
||||
|
||||
# Insert skills section
|
||||
if [ -n "$line_num" ]; then
|
||||
# Insert at line_num
|
||||
echo "$skills_section" | cat - <(tail -n +$line_num "$file") > "$file.tmp"
|
||||
head -n $((line_num - 1)) "$file" >> "$file.tmp.header"
|
||||
cat "$file.tmp.header" "$file.tmp" > "$file"
|
||||
rm "$file.tmp" "$file.tmp.header"
|
||||
return 0
|
||||
else
|
||||
# Couldn't find insertion point, append at end
|
||||
echo "" >> "$file"
|
||||
echo "$skills_section" >> "$file"
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
# Process all agent files
|
||||
echo "📝 Processing agents..."
|
||||
for plugin_dir in plugins/*/; do
|
||||
plugin_name=$(basename "$plugin_dir")
|
||||
|
||||
for agent_file in "$plugin_dir"agents/*.md; do
|
||||
if [[ -f "$agent_file" ]]; then
|
||||
if add_skills_section "$agent_file" "$plugin_name"; then
|
||||
echo " ✅ Updated: $agent_file"
|
||||
agents_updated=$((agents_updated + 1))
|
||||
else
|
||||
agents_skipped=$((agents_skipped + 1))
|
||||
fi
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "📝 Processing commands..."
|
||||
for plugin_dir in plugins/*/; do
|
||||
plugin_name=$(basename "$plugin_dir")
|
||||
|
||||
for command_file in "$plugin_dir"commands/*.md; do
|
||||
if [[ -f "$command_file" ]]; then
|
||||
if add_skills_section "$command_file" "$plugin_name"; then
|
||||
echo " ✅ Updated: $command_file"
|
||||
commands_updated=$((commands_updated + 1))
|
||||
else
|
||||
commands_skipped=$((commands_skipped + 1))
|
||||
fi
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "✨ Summary:"
|
||||
echo " Agents updated: $agents_updated"
|
||||
echo " Agents skipped (no skills or already has section): $agents_skipped"
|
||||
echo " Commands updated: $commands_updated"
|
||||
echo " Commands skipped (no skills or already has section): $commands_skipped"
|
||||
echo ""
|
||||
echo "Total updated: $((agents_updated + commands_updated))"
|
||||
echo ""
|
||||
echo "✅ Done! Run 'git diff' to review changes."
|
||||
105
skills/build-assistant/scripts/add-skill-tool.sh
Executable file
105
skills/build-assistant/scripts/add-skill-tool.sh
Executable file
@@ -0,0 +1,105 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Script to add Skill tool to all agents and commands that are missing it
|
||||
# Usage: bash add-skill-tool.sh (can be run from anywhere)
|
||||
|
||||
set -e
|
||||
|
||||
# Find marketplace root by looking for plugins/ directory
|
||||
find_marketplace_root() {
|
||||
local current_dir="$PWD"
|
||||
|
||||
# Check if we're already in marketplace root
|
||||
if [ -d "$current_dir/plugins" ] && [ -d "$current_dir/scripts" ]; then
|
||||
echo "$current_dir"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Check if script is in scripts/ subdirectory
|
||||
local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
local parent_dir="$(dirname "$script_dir")"
|
||||
if [ -d "$parent_dir/plugins" ] && [ -d "$parent_dir/scripts" ]; then
|
||||
echo "$parent_dir"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Search upwards for marketplace root
|
||||
while [ "$current_dir" != "/" ]; do
|
||||
if [ -d "$current_dir/plugins" ] && [ -d "$current_dir/scripts" ] && [ -f "$current_dir/.claude-plugin/marketplace.json" ]; then
|
||||
echo "$current_dir"
|
||||
return 0
|
||||
fi
|
||||
current_dir="$(dirname "$current_dir")"
|
||||
done
|
||||
|
||||
echo "ERROR: Could not find ai-dev-marketplace root directory" >&2
|
||||
echo "Please run this script from within the marketplace directory" >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
MARKETPLACE_DIR=$(find_marketplace_root)
|
||||
if [ $? -ne 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd "$MARKETPLACE_DIR"
|
||||
echo "📍 Working in: $MARKETPLACE_DIR"
|
||||
echo ""
|
||||
|
||||
echo "🔍 Adding Skill tool to agents and commands..."
|
||||
echo ""
|
||||
|
||||
# Counters
|
||||
agents_updated=0
|
||||
commands_updated=0
|
||||
agents_skipped=0
|
||||
commands_skipped=0
|
||||
|
||||
# Process all agent files
|
||||
echo "📝 Processing agents..."
|
||||
for agent_file in plugins/*/agents/*.md; do
|
||||
if [[ -f "$agent_file" ]]; then
|
||||
# Check if file has tools: line
|
||||
if grep -q "^tools:" "$agent_file"; then
|
||||
# Check if Skill is already present
|
||||
if grep -q "^tools:.*Skill" "$agent_file"; then
|
||||
agents_skipped=$((agents_skipped + 1))
|
||||
else
|
||||
# Add Skill to the tools line
|
||||
sed -i 's/^tools: \(.*\)$/tools: \1, Skill/' "$agent_file"
|
||||
echo " ✅ Updated: $agent_file"
|
||||
agents_updated=$((agents_updated + 1))
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "📝 Processing commands..."
|
||||
for command_file in plugins/*/commands/*.md; do
|
||||
if [[ -f "$command_file" ]]; then
|
||||
# Check if file has allowed-tools: line
|
||||
if grep -q "^allowed-tools:" "$command_file"; then
|
||||
# Check if Skill is already present
|
||||
if grep -q "^allowed-tools:.*Skill" "$command_file"; then
|
||||
commands_skipped=$((commands_skipped + 1))
|
||||
else
|
||||
# Add Skill to the allowed-tools line
|
||||
sed -i 's/^allowed-tools: \(.*\)$/allowed-tools: \1, Skill/' "$command_file"
|
||||
echo " ✅ Updated: $command_file"
|
||||
commands_updated=$((commands_updated + 1))
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "✨ Summary:"
|
||||
echo " Agents updated: $agents_updated"
|
||||
echo " Agents skipped (already have Skill): $agents_skipped"
|
||||
echo " Commands updated: $commands_updated"
|
||||
echo " Commands skipped (already have Skill): $commands_skipped"
|
||||
echo ""
|
||||
echo "Total updated: $((agents_updated + commands_updated))"
|
||||
echo ""
|
||||
echo "✅ Done! Run 'git diff' to review changes."
|
||||
466
skills/build-assistant/scripts/create-plugin-structure.py
Executable file
466
skills/build-assistant/scripts/create-plugin-structure.py
Executable file
@@ -0,0 +1,466 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Create New Plugin with Enterprise Structure
|
||||
|
||||
Creates a complete plugin scaffold following enterprise standards:
|
||||
- .claude-plugin/plugin.json
|
||||
- .mcp.json placeholder
|
||||
- hooks/hooks.json
|
||||
- LICENSE (MIT)
|
||||
- CHANGELOG.md
|
||||
- commands/
|
||||
- agents/
|
||||
- skills/{skill-name}/
|
||||
├── SKILL.md
|
||||
├── reference.md
|
||||
├── examples.md
|
||||
├── scripts/
|
||||
└── templates/
|
||||
|
||||
Usage:
|
||||
python create-plugin-structure.py <plugin-name> [--skill <skill-name>]
|
||||
|
||||
Examples:
|
||||
python create-plugin-structure.py multiagent-analytics --skill analytics-assistant
|
||||
python create-plugin-structure.py multiagent-testing --skill test-runner
|
||||
"""
|
||||
|
||||
import sys
|
||||
import json
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
|
||||
MARKETPLACE_DIR = Path.home() / ".claude/marketplaces/multiagent-dev/plugins"
|
||||
|
||||
# Templates
|
||||
LICENSE_TEMPLATE = """MIT License
|
||||
|
||||
Copyright (c) {year} Multiagent Framework
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
"""
|
||||
|
||||
CHANGELOG_TEMPLATE = """# Changelog
|
||||
|
||||
All notable changes to this plugin will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Planned
|
||||
- Initial plugin implementation
|
||||
- Core features and commands
|
||||
- Documentation
|
||||
|
||||
## [1.0.0] - {date}
|
||||
|
||||
### Added
|
||||
- Plugin structure created
|
||||
- Enterprise directory layout
|
||||
- Skill scaffolding for {skill_name}
|
||||
"""
|
||||
|
||||
PLUGIN_JSON_TEMPLATE = {
|
||||
"name": "{plugin_name}",
|
||||
"version": "1.0.0",
|
||||
"description": "{description}",
|
||||
"author": {
|
||||
"name": "Multiagent Framework",
|
||||
"email": "noreply@multiagent.dev"
|
||||
},
|
||||
"license": "MIT",
|
||||
"keywords": ["{subsystem}", "multiagent", "automation"],
|
||||
"components": {
|
||||
"commands": 0,
|
||||
"agents": 0,
|
||||
"skills": 1
|
||||
}
|
||||
}
|
||||
|
||||
MCP_JSON_TEMPLATE = {
|
||||
"mcpServers": {},
|
||||
"notes": "MCP server configurations for this plugin. Add servers as needed."
|
||||
}
|
||||
|
||||
HOOKS_JSON_TEMPLATE = {
|
||||
"hooks": {},
|
||||
"notes": "Event hooks for this plugin. Configure hook triggers and scripts as needed."
|
||||
}
|
||||
|
||||
SKILL_MD_TEMPLATE = """---
|
||||
name: {skill_display_name}
|
||||
description: {skill_description}
|
||||
allowed-tools: Read, Write, Bash
|
||||
---
|
||||
|
||||
# {skill_display_name}
|
||||
|
||||
## Instructions
|
||||
|
||||
TODO: Add detailed instructions for this skill.
|
||||
|
||||
### Features
|
||||
|
||||
1. Feature 1
|
||||
2. Feature 2
|
||||
3. Feature 3
|
||||
|
||||
### Trigger Patterns
|
||||
|
||||
This skill is automatically invoked when:
|
||||
- Pattern 1
|
||||
- Pattern 2
|
||||
- Pattern 3
|
||||
|
||||
## Examples
|
||||
|
||||
### Example 1: Basic Usage
|
||||
|
||||
TODO: Add example showing basic usage
|
||||
|
||||
```bash
|
||||
# Example command or code
|
||||
```
|
||||
|
||||
### Example 2: Advanced Usage
|
||||
|
||||
TODO: Add example showing advanced features
|
||||
|
||||
```bash
|
||||
# Example command or code
|
||||
```
|
||||
"""
|
||||
|
||||
REFERENCE_MD_TEMPLATE = """# {skill_display_name} - Reference
|
||||
|
||||
## API Reference
|
||||
|
||||
### Trigger Patterns
|
||||
|
||||
- Pattern 1: Description
|
||||
- Pattern 2: Description
|
||||
- Pattern 3: Description
|
||||
|
||||
### Input Requirements
|
||||
|
||||
- Input 1: Description and format
|
||||
- Input 2: Description and format
|
||||
|
||||
### Output Format
|
||||
|
||||
- Output 1: Description
|
||||
- Output 2: Description
|
||||
|
||||
## Configuration
|
||||
|
||||
### Environment Variables
|
||||
|
||||
```bash
|
||||
# VARIABLE_NAME=value # Description
|
||||
```
|
||||
|
||||
### Settings
|
||||
|
||||
TODO: Document configurable settings
|
||||
|
||||
## Advanced Usage
|
||||
|
||||
### Performance Considerations
|
||||
|
||||
TODO: Add performance notes
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Issue 1
|
||||
**Problem:** Description
|
||||
**Solution:** How to fix
|
||||
"""
|
||||
|
||||
EXAMPLES_MD_TEMPLATE = """# {skill_display_name} - Examples
|
||||
|
||||
## Example 1: Basic Use Case
|
||||
|
||||
TODO: Add first example
|
||||
|
||||
```bash
|
||||
# Example code
|
||||
```
|
||||
|
||||
**Expected Output:**
|
||||
```
|
||||
Expected result
|
||||
```
|
||||
|
||||
## Example 2: Advanced Use Case
|
||||
|
||||
TODO: Add second example
|
||||
|
||||
```bash
|
||||
# Example code
|
||||
```
|
||||
|
||||
**Expected Output:**
|
||||
```
|
||||
Expected result
|
||||
```
|
||||
|
||||
## Example 3: Real-World Scenario
|
||||
|
||||
TODO: Add real-world example
|
||||
|
||||
```bash
|
||||
# Example code
|
||||
```
|
||||
|
||||
**Expected Output:**
|
||||
```
|
||||
Expected result
|
||||
```
|
||||
"""
|
||||
|
||||
README_TEMPLATE = """# {plugin_name}
|
||||
|
||||
{description}
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
/plugin install {plugin_name}@multiagent-dev
|
||||
```
|
||||
|
||||
## Components
|
||||
|
||||
- **Commands**: 0 slash commands
|
||||
- **Agents**: 0 specialized agents
|
||||
- **Skills**: 1 skill
|
||||
|
||||
## Skills
|
||||
|
||||
### {skill_display_name}
|
||||
|
||||
{skill_description}
|
||||
|
||||
See `skills/{skill_slug}/SKILL.md` for details.
|
||||
|
||||
## Development
|
||||
|
||||
This plugin follows the multiagent enterprise plugin structure.
|
||||
|
||||
### Directory Layout
|
||||
|
||||
```
|
||||
{plugin_name}/
|
||||
├── .claude-plugin/
|
||||
│ └── plugin.json
|
||||
├── .mcp.json
|
||||
├── hooks/
|
||||
│ └── hooks.json
|
||||
├── LICENSE
|
||||
├── CHANGELOG.md
|
||||
├── README.md
|
||||
├── commands/ # Slash commands
|
||||
├── agents/ # Specialized agents
|
||||
└── skills/ # Auto-discovered skills
|
||||
└── {skill_slug}/
|
||||
├── SKILL.md
|
||||
├── reference.md
|
||||
├── examples.md
|
||||
├── scripts/
|
||||
└── templates/
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT License - see LICENSE file for details
|
||||
"""
|
||||
|
||||
|
||||
def create_plugin_structure(plugin_name: str, skill_name: str = None):
|
||||
"""Create complete enterprise plugin structure."""
|
||||
|
||||
# Extract subsystem name
|
||||
subsystem = plugin_name.replace("multiagent-", "")
|
||||
|
||||
# Default skill name if not provided
|
||||
if not skill_name:
|
||||
skill_name = f"{subsystem}-assistant"
|
||||
|
||||
skill_slug = skill_name.lower().replace(" ", "-")
|
||||
skill_display_name = skill_name.replace("-", " ").title()
|
||||
|
||||
plugin_dir = MARKETPLACE_DIR / plugin_name
|
||||
|
||||
if plugin_dir.exists():
|
||||
print(f"❌ Plugin directory already exists: {plugin_dir}")
|
||||
print(f" Please remove it first or choose a different name.")
|
||||
return False
|
||||
|
||||
print("=" * 70)
|
||||
print(f"Creating Plugin: {plugin_name}")
|
||||
print("=" * 70)
|
||||
print(f"Skill: {skill_display_name} ({skill_slug})")
|
||||
print(f"Location: {plugin_dir}\n")
|
||||
|
||||
# Create directory structure
|
||||
print("Creating directory structure...")
|
||||
|
||||
dirs_to_create = [
|
||||
plugin_dir / ".claude-plugin",
|
||||
plugin_dir / "hooks",
|
||||
plugin_dir / "commands",
|
||||
plugin_dir / "agents",
|
||||
plugin_dir / "skills" / skill_slug / "scripts",
|
||||
plugin_dir / "skills" / skill_slug / "templates",
|
||||
]
|
||||
|
||||
for dir_path in dirs_to_create:
|
||||
dir_path.mkdir(parents=True, exist_ok=True)
|
||||
print(f" ✓ Created: {dir_path.relative_to(plugin_dir)}/")
|
||||
|
||||
# Create plugin.json
|
||||
print("\nCreating plugin.json...")
|
||||
plugin_json = PLUGIN_JSON_TEMPLATE.copy()
|
||||
plugin_json["name"] = plugin_name
|
||||
plugin_json["description"] = f"{subsystem.title()} functionality for multiagent framework"
|
||||
plugin_json["keywords"] = [subsystem, "multiagent", "automation"]
|
||||
|
||||
plugin_json_path = plugin_dir / ".claude-plugin" / "plugin.json"
|
||||
with open(plugin_json_path, 'w') as f:
|
||||
json.dump(plugin_json, f, indent=2)
|
||||
print(f" ✓ Created: .claude-plugin/plugin.json")
|
||||
|
||||
# Create .mcp.json
|
||||
print("\nCreating .mcp.json...")
|
||||
mcp_json_path = plugin_dir / ".mcp.json"
|
||||
with open(mcp_json_path, 'w') as f:
|
||||
json.dump(MCP_JSON_TEMPLATE, f, indent=2)
|
||||
print(f" ✓ Created: .mcp.json")
|
||||
|
||||
# Create hooks.json
|
||||
print("\nCreating hooks/hooks.json...")
|
||||
hooks_json_path = plugin_dir / "hooks" / "hooks.json"
|
||||
with open(hooks_json_path, 'w') as f:
|
||||
json.dump(HOOKS_JSON_TEMPLATE, f, indent=2)
|
||||
print(f" ✓ Created: hooks/hooks.json")
|
||||
|
||||
# Create LICENSE
|
||||
print("\nCreating LICENSE...")
|
||||
license_path = plugin_dir / "LICENSE"
|
||||
license_content = LICENSE_TEMPLATE.format(year=datetime.now().year)
|
||||
license_path.write_text(license_content)
|
||||
print(f" ✓ Created: LICENSE")
|
||||
|
||||
# Create CHANGELOG.md
|
||||
print("\nCreating CHANGELOG.md...")
|
||||
changelog_path = plugin_dir / "CHANGELOG.md"
|
||||
changelog_content = CHANGELOG_TEMPLATE.format(
|
||||
date=datetime.now().strftime("%Y-%m-%d"),
|
||||
skill_name=skill_display_name
|
||||
)
|
||||
changelog_path.write_text(changelog_content)
|
||||
print(f" ✓ Created: CHANGELOG.md")
|
||||
|
||||
# Create README.md
|
||||
print("\nCreating README.md...")
|
||||
readme_path = plugin_dir / "README.md"
|
||||
readme_content = README_TEMPLATE.format(
|
||||
plugin_name=plugin_name,
|
||||
description=f"{subsystem.title()} functionality for multiagent framework",
|
||||
skill_display_name=skill_display_name,
|
||||
skill_description=f"Provides {subsystem} capabilities",
|
||||
skill_slug=skill_slug
|
||||
)
|
||||
readme_path.write_text(readme_content)
|
||||
print(f" ✓ Created: README.md")
|
||||
|
||||
# Create skill files
|
||||
skill_dir = plugin_dir / "skills" / skill_slug
|
||||
|
||||
print(f"\nCreating skill documentation for '{skill_display_name}'...")
|
||||
|
||||
# SKILL.md
|
||||
skill_md_path = skill_dir / "SKILL.md"
|
||||
skill_md_content = SKILL_MD_TEMPLATE.format(
|
||||
skill_display_name=skill_display_name,
|
||||
skill_description=f"Provides {subsystem} capabilities for the multiagent framework"
|
||||
)
|
||||
skill_md_path.write_text(skill_md_content)
|
||||
print(f" ✓ Created: skills/{skill_slug}/SKILL.md")
|
||||
|
||||
# reference.md
|
||||
reference_md_path = skill_dir / "reference.md"
|
||||
reference_content = REFERENCE_MD_TEMPLATE.format(
|
||||
skill_display_name=skill_display_name
|
||||
)
|
||||
reference_md_path.write_text(reference_content)
|
||||
print(f" ✓ Created: skills/{skill_slug}/reference.md")
|
||||
|
||||
# examples.md
|
||||
examples_md_path = skill_dir / "examples.md"
|
||||
examples_content = EXAMPLES_MD_TEMPLATE.format(
|
||||
skill_display_name=skill_display_name
|
||||
)
|
||||
examples_md_path.write_text(examples_content)
|
||||
print(f" ✓ Created: skills/{skill_slug}/examples.md")
|
||||
|
||||
# Create .gitkeep files
|
||||
(skill_dir / "scripts" / ".gitkeep").touch()
|
||||
(skill_dir / "templates" / ".gitkeep").touch()
|
||||
(plugin_dir / "commands" / ".gitkeep").touch()
|
||||
(plugin_dir / "agents" / ".gitkeep").touch()
|
||||
|
||||
print("\n" + "=" * 70)
|
||||
print("SUCCESS: Plugin Structure Created!")
|
||||
print("=" * 70)
|
||||
|
||||
print(f"\nLocation: {plugin_dir}")
|
||||
print(f"\nNext Steps:")
|
||||
print(f" 1. Edit skills/{skill_slug}/SKILL.md with actual skill instructions")
|
||||
print(f" 2. Add commands to commands/ directory")
|
||||
print(f" 3. Add agents to agents/ directory")
|
||||
print(f" 4. Add scripts to skills/{skill_slug}/scripts/")
|
||||
print(f" 5. Add templates to skills/{skill_slug}/templates/")
|
||||
print(f" 6. Update README.md with actual documentation")
|
||||
print(f" 7. Test with: /plugin install {plugin_name}@multiagent-dev")
|
||||
print()
|
||||
|
||||
return True
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) < 2:
|
||||
print("Usage: python create-plugin-structure.py <plugin-name> [--skill <skill-name>]")
|
||||
print("\nExamples:")
|
||||
print(" python create-plugin-structure.py multiagent-analytics")
|
||||
print(" python create-plugin-structure.py multiagent-testing --skill test-runner")
|
||||
sys.exit(1)
|
||||
|
||||
plugin_name = sys.argv[1]
|
||||
skill_name = None
|
||||
|
||||
# Parse optional --skill argument
|
||||
if "--skill" in sys.argv:
|
||||
skill_idx = sys.argv.index("--skill")
|
||||
if skill_idx + 1 < len(sys.argv):
|
||||
skill_name = sys.argv[skill_idx + 1]
|
||||
|
||||
success = create_plugin_structure(plugin_name, skill_name)
|
||||
sys.exit(0 if success else 1)
|
||||
168
skills/build-assistant/scripts/create-skill-structures.py
Executable file
168
skills/build-assistant/scripts/create-skill-structures.py
Executable file
@@ -0,0 +1,168 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Create Skill Directory Structures for Existing Plugins
|
||||
|
||||
Mechanically creates the directory structure for skills in plugins
|
||||
that don't have them yet. Agent will fill in content later.
|
||||
|
||||
Usage:
|
||||
python create-skill-structures.py [--dry-run]
|
||||
"""
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
|
||||
MARKETPLACE_DIR = Path.home() / ".claude/marketplaces/multiagent-dev/plugins"
|
||||
|
||||
# Mapping: plugin-name → skill-name
|
||||
PLUGIN_SKILLS = {
|
||||
"multiagent-ai-infrastructure": "ai-infrastructure-assistant",
|
||||
"multiagent-backend": "backend-developer",
|
||||
"multiagent-build": "build-assistant",
|
||||
"multiagent-compliance": "compliance-advisor",
|
||||
"multiagent-core": "core-initializer",
|
||||
"multiagent-cto": "architecture-reviewer",
|
||||
"multiagent-deployment": "deployment-assistant",
|
||||
"multiagent-docs": "documentation-writer",
|
||||
"multiagent-enhancement": "enhancement-manager",
|
||||
"multiagent-frontend": "frontend-developer",
|
||||
"multiagent-github": "github-integration",
|
||||
"multiagent-idea": "idea-tracker",
|
||||
"multiagent-implementation": "implementation-orchestrator",
|
||||
"multiagent-iterate": "iteration-manager",
|
||||
"multiagent-mcp": "mcp-manager",
|
||||
"multiagent-notes": "notes-tracker",
|
||||
"multiagent-observability": "observability-monitor",
|
||||
"multiagent-performance": "performance-optimizer",
|
||||
"multiagent-profile": "developer-profile",
|
||||
"multiagent-refactoring": "refactoring-analyzer",
|
||||
"multiagent-reliability": "reliability-engineer",
|
||||
"multiagent-security": "security-advisor",
|
||||
"multiagent-supervisor": "supervisor-coordinator",
|
||||
"multiagent-validation": "validation-checker",
|
||||
"multiagent-version": "version-manager",
|
||||
}
|
||||
|
||||
|
||||
def create_skill_structure(plugin_name: str, skill_name: str, dry_run: bool = False):
|
||||
"""Create mechanical skill directory structure."""
|
||||
|
||||
plugin_dir = MARKETPLACE_DIR / plugin_name
|
||||
skill_slug = skill_name.lower().replace(" ", "-")
|
||||
skill_dir = plugin_dir / "skills" / skill_slug
|
||||
|
||||
# Check if plugin exists
|
||||
if not plugin_dir.exists():
|
||||
print(f" WARNING: Plugin directory not found: {plugin_dir}")
|
||||
return False
|
||||
|
||||
# Check if skill already exists
|
||||
if (skill_dir / "SKILL.md").exists():
|
||||
print(f" SKIP: Skill already exists: {skill_slug}")
|
||||
return False
|
||||
|
||||
print(f"\n[{plugin_name}]")
|
||||
print(f" Creating skill: {skill_slug}")
|
||||
|
||||
if dry_run:
|
||||
print(f" [DRY RUN] Would create:")
|
||||
print(f" - {skill_dir}/")
|
||||
print(f" - {skill_dir}/scripts/")
|
||||
print(f" - {skill_dir}/templates/")
|
||||
print(f" - {skill_dir}/SKILL.md (placeholder)")
|
||||
print(f" - {skill_dir}/reference.md (placeholder)")
|
||||
print(f" - {skill_dir}/examples.md (placeholder)")
|
||||
return True
|
||||
|
||||
# Create directories
|
||||
skill_dir.mkdir(parents=True, exist_ok=True)
|
||||
(skill_dir / "scripts").mkdir(exist_ok=True)
|
||||
(skill_dir / "templates").mkdir(exist_ok=True)
|
||||
|
||||
print(f" OK: Created directories")
|
||||
|
||||
# Create placeholder files (agent will fill these)
|
||||
skill_md = skill_dir / "SKILL.md"
|
||||
skill_md.write_text(f"""---
|
||||
name: {skill_name.title()}
|
||||
description: TODO - Agent will fill this
|
||||
allowed-tools: Read, Write, Bash
|
||||
---
|
||||
|
||||
# {skill_name.title()}
|
||||
|
||||
TODO: Agent will generate content using skill-builder
|
||||
""")
|
||||
|
||||
reference_md = skill_dir / "reference.md"
|
||||
reference_md.write_text(f"""# {skill_name.title()} - Reference
|
||||
|
||||
TODO: Agent will generate API reference
|
||||
""")
|
||||
|
||||
examples_md = skill_dir / "examples.md"
|
||||
examples_md.write_text(f"""# {skill_name.title()} - Examples
|
||||
|
||||
TODO: Agent will generate examples
|
||||
""")
|
||||
|
||||
# Create .gitkeep in empty dirs
|
||||
(skill_dir / "scripts" / ".gitkeep").touch()
|
||||
(skill_dir / "templates" / ".gitkeep").touch()
|
||||
|
||||
print(f" OK: Created placeholder files")
|
||||
print(f" Location: {skill_dir}")
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def main():
|
||||
"""Create skill structures for all plugins."""
|
||||
|
||||
dry_run = "--dry-run" in sys.argv
|
||||
|
||||
print("=" * 70)
|
||||
print("Creating Skill Structures for Existing Plugins")
|
||||
print("=" * 70)
|
||||
|
||||
if dry_run:
|
||||
print("\n⚠️ DRY RUN MODE - No changes will be made\n")
|
||||
|
||||
print(f"\nMarketplace: {MARKETPLACE_DIR}")
|
||||
print(f"Plugins to process: {len(PLUGIN_SKILLS)}\n")
|
||||
|
||||
created = 0
|
||||
skipped = 0
|
||||
errors = 0
|
||||
|
||||
for plugin_name, skill_name in PLUGIN_SKILLS.items():
|
||||
try:
|
||||
result = create_skill_structure(plugin_name, skill_name, dry_run)
|
||||
if result:
|
||||
created += 1
|
||||
else:
|
||||
skipped += 1
|
||||
except Exception as e:
|
||||
print(f" ERROR: {e}")
|
||||
errors += 1
|
||||
|
||||
print("\n" + "=" * 70)
|
||||
print("Summary")
|
||||
print("=" * 70)
|
||||
print(f"Created: {created}")
|
||||
print(f"Skipped: {skipped}")
|
||||
print(f"Errors: {errors}")
|
||||
print()
|
||||
|
||||
if dry_run:
|
||||
print("Run without --dry-run to create structures")
|
||||
else:
|
||||
print("Next step: Run headless skill generation to fill content")
|
||||
print(" ./scripts/plugins/marketplace/fill-skill-content.sh")
|
||||
|
||||
return 0 if errors == 0 else 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
44
skills/build-assistant/scripts/find-hardcoded-paths.sh
Executable file
44
skills/build-assistant/scripts/find-hardcoded-paths.sh
Executable file
@@ -0,0 +1,44 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Find hardcoded paths in plugin files
|
||||
# Usage: bash find-hardcoded-paths.sh [directory]
|
||||
|
||||
DIR="${1:-$HOME/.claude/plugins/marketplaces/domain-plugin-builder/plugins/domain-plugin-builder}"
|
||||
|
||||
echo "Scanning for hardcoded paths in: $DIR"
|
||||
echo "================================================"
|
||||
echo ""
|
||||
|
||||
# Find markdown files with hardcoded paths (excluding URLs)
|
||||
echo "## Hardcoded paths in markdown files:"
|
||||
echo ""
|
||||
|
||||
# Look for absolute paths that aren't URLs
|
||||
grep -rn \
|
||||
--include="*.md" \
|
||||
-E '(~/.claude/|/home/[^/]+/|\.claude/plugins/marketplaces/|plugins/[^/]+/)' \
|
||||
"$DIR" \
|
||||
| grep -v 'http://' \
|
||||
| grep -v 'https://' \
|
||||
| grep -v 'bash ~/.claude/plugins/marketplaces/domain-plugin-builder/plugins/domain-plugin-builder/skills/build-assistant/scripts/' \
|
||||
| grep -v '# ' \
|
||||
| grep -v 'CRITICAL: Script Paths Must Be Absolute' \
|
||||
| grep -v 'Example:' \
|
||||
| grep -v '```'
|
||||
|
||||
echo ""
|
||||
echo "================================================"
|
||||
echo ""
|
||||
echo "## What should be fixed:"
|
||||
echo ""
|
||||
echo "For documentation references in agents/commands/skills:"
|
||||
echo " ❌ ~/.claude/plugins/.../docs/frameworks/claude/dans-composition-pattern.md"
|
||||
echo " ✅ @dans-composition-pattern.md"
|
||||
echo ""
|
||||
echo "For bash validation scripts (these SHOULD stay absolute):"
|
||||
echo " ✅ bash ~/.claude/plugins/marketplaces/domain-plugin-builder/plugins/domain-plugin-builder/skills/build-assistant/scripts/validate-agent.sh"
|
||||
echo ""
|
||||
echo "For @ references in prompts:"
|
||||
echo " ✅ @agent-color-decision.md"
|
||||
echo " ✅ @docs/frameworks/claude/dans-composition-pattern.md"
|
||||
echo ""
|
||||
66
skills/build-assistant/scripts/fix-argument-hints.sh
Executable file
66
skills/build-assistant/scripts/fix-argument-hints.sh
Executable file
@@ -0,0 +1,66 @@
|
||||
#!/bin/bash
|
||||
|
||||
# fix-argument-hints.sh
|
||||
# Fixes argument hint formatting issues found by validate-argument-hints.sh
|
||||
|
||||
PLUGIN_DIR="${1:-.}"
|
||||
FIXES_APPLIED=0
|
||||
|
||||
echo "=== Fixing Argument Hints ==="
|
||||
echo ""
|
||||
|
||||
if [ ! -d "$PLUGIN_DIR" ]; then
|
||||
echo "❌ ERROR: Directory not found: $PLUGIN_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Find all command files
|
||||
COMMAND_FILES=$(find "$PLUGIN_DIR" -type f -path "*/commands/*.md" 2>/dev/null)
|
||||
|
||||
if [ -z "$COMMAND_FILES" ]; then
|
||||
echo "⚠️ No command files found in $PLUGIN_DIR"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Scanning and fixing command files..."
|
||||
echo ""
|
||||
|
||||
while IFS= read -r file; do
|
||||
# Check if argument-hint is missing
|
||||
if ! grep -q "^argument-hint:" "$file"; then
|
||||
echo "📝 Adding missing argument-hint to: $file"
|
||||
# Add after description line
|
||||
sed -i '/^description:/a argument-hint: none' "$file"
|
||||
((FIXES_APPLIED++))
|
||||
fi
|
||||
|
||||
# Fix improper format (quoted strings without brackets)
|
||||
HINT=$(sed -n '/^---$/,/^---$/p' "$file" | grep "^argument-hint:" | sed 's/argument-hint: *//')
|
||||
|
||||
# Check if it's a quoted string like "Spec directory (e.g., 002-system-context-we)"
|
||||
if echo "$HINT" | grep -qE '^".*\(e\.g\.'; then
|
||||
echo "🔧 Fixing format in: $file"
|
||||
# Extract the main part before (e.g.,
|
||||
MAIN_PART=$(echo "$HINT" | sed 's/".*(\(e\.g\.,.*\))".*/<\1>/' | sed 's/Spec directory/<spec-directory>/')
|
||||
sed -i "s|^argument-hint:.*|argument-hint: <spec-directory>|" "$file"
|
||||
((FIXES_APPLIED++))
|
||||
fi
|
||||
|
||||
# Fix legacy subsystem references
|
||||
if grep -q "^argument-hint:.*subsystem" "$file"; then
|
||||
echo "🔄 Replacing 'subsystem' with 'plugin' in: $file"
|
||||
sed -i 's/argument-hint:.*subsystem/argument-hint: <plugin-name>/' "$file"
|
||||
((FIXES_APPLIED++))
|
||||
fi
|
||||
|
||||
done <<< "$COMMAND_FILES"
|
||||
|
||||
echo ""
|
||||
echo "=== Summary ==="
|
||||
if [ $FIXES_APPLIED -eq 0 ]; then
|
||||
echo "✅ No fixes needed"
|
||||
exit 0
|
||||
else
|
||||
echo "✅ Applied $FIXES_APPLIED fix(es)"
|
||||
exit 0
|
||||
fi
|
||||
70
skills/build-assistant/scripts/fix-hardcoded-doc-refs.sh
Executable file
70
skills/build-assistant/scripts/fix-hardcoded-doc-refs.sh
Executable file
@@ -0,0 +1,70 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Fix hardcoded documentation references to use @ symbol
|
||||
# Usage: bash fix-hardcoded-doc-refs.sh <marketplace-directory>
|
||||
|
||||
MARKETPLACE_DIR="${1:-$(pwd)}"
|
||||
|
||||
echo "Fixing hardcoded documentation references in: $MARKETPLACE_DIR"
|
||||
echo "========================================================"
|
||||
|
||||
# Counter
|
||||
FIXED=0
|
||||
|
||||
# Find all markdown files
|
||||
find "$MARKETPLACE_DIR" -type f -name "*.md" | while read -r FILE; do
|
||||
# Skip CLAUDE.md script path examples (those should stay absolute)
|
||||
if [[ "$FILE" == *"/CLAUDE.md" ]]; then
|
||||
# Only fix @ references in CLAUDE.md, not bash script paths
|
||||
if grep -q "@plugins/domain-plugin-builder/" "$FILE" 2>/dev/null; then
|
||||
echo "Fixing @ references in: $FILE"
|
||||
|
||||
# Fix template references
|
||||
sed -i 's|@plugins/domain-plugin-builder/skills/build-assistant/templates/commands/template-command-patterns.md|@template-command-patterns.md|g' "$FILE"
|
||||
sed -i 's|@plugins/domain-plugin-builder/skills/build-assistant/templates/agents/agent-with-phased-webfetch.md|@agent-with-phased-webfetch.md|g' "$FILE"
|
||||
|
||||
# Fix framework doc references
|
||||
sed -i 's|@plugins/domain-plugin-builder/docs/frameworks/claude/component-decision-framework.md|@component-decision-framework.md|g' "$FILE"
|
||||
sed -i 's|@plugins/domain-plugin-builder/docs/sdks/|@|g' "$FILE"
|
||||
|
||||
((FIXED++))
|
||||
fi
|
||||
continue
|
||||
fi
|
||||
|
||||
# For all other files, fix @ references
|
||||
if grep -q "@plugins/" "$FILE" 2>/dev/null; then
|
||||
echo "Fixing: $FILE"
|
||||
|
||||
# Template references
|
||||
sed -i 's|@plugins/domain-plugin-builder/skills/build-assistant/templates/commands/template-command-patterns.md|@template-command-patterns.md|g' "$FILE"
|
||||
sed -i 's|@plugins/domain-plugin-builder/skills/build-assistant/templates/agents/agent-with-phased-webfetch.md|@agent-with-phased-webfetch.md|g' "$FILE"
|
||||
|
||||
# Framework docs
|
||||
sed -i 's|@plugins/domain-plugin-builder/docs/frameworks/claude/component-decision-framework.md|@component-decision-framework.md|g' "$FILE"
|
||||
sed -i 's|@plugins/domain-plugin-builder/docs/frameworks/claude/dans-composition-pattern.md|@dans-composition-pattern.md|g' "$FILE"
|
||||
sed -i 's|@plugins/domain-plugin-builder/docs/frameworks/claude/agent-skills-architecture.md|@agent-skills-architecture.md|g' "$FILE"
|
||||
|
||||
# SDK docs (simplified)
|
||||
sed -i 's|@plugins/domain-plugin-builder/docs/sdks/claude-agent-sdk-documentation.md|@claude-agent-sdk-documentation.md|g' "$FILE"
|
||||
sed -i 's|@plugins/domain-plugin-builder/docs/sdks/\([^/]*\)|@\1|g' "$FILE"
|
||||
|
||||
# Plugin-specific docs (keep relative @plugins/PLUGIN_NAME/docs/)
|
||||
# These are OK and should stay as-is for cross-plugin references
|
||||
|
||||
((FIXED++))
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "========================================================"
|
||||
echo "✅ Fixed $FIXED files"
|
||||
echo ""
|
||||
echo "Files with @ references should now use short names:"
|
||||
echo " @template-command-patterns.md"
|
||||
echo " @component-decision-framework.md"
|
||||
echo " @dans-composition-pattern.md"
|
||||
echo ""
|
||||
echo "Cross-plugin references stay as:"
|
||||
echo " @plugins/PLUGIN_NAME/docs/file.md"
|
||||
echo ""
|
||||
105
skills/build-assistant/scripts/fix-hardcoded-paths.sh
Executable file
105
skills/build-assistant/scripts/fix-hardcoded-paths.sh
Executable file
@@ -0,0 +1,105 @@
|
||||
#!/usr/bin/env bash
|
||||
# Script: fix-hardcoded-paths.sh
|
||||
# Purpose: Fix hardcoded multiagent-core paths to use simple project-relative paths
|
||||
# Usage: ./fix-hardcoded-paths.sh [--dry-run]
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
DRY_RUN=false
|
||||
if [[ "${1:-}" == "--dry-run" ]]; then
|
||||
DRY_RUN=true
|
||||
echo "DRY RUN MODE - No files will be changed"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
PLUGINS_DIR="$HOME/.claude/marketplaces/multiagent-dev/plugins"
|
||||
|
||||
echo "=== Fixing Hardcoded Paths in Plugins ==="
|
||||
echo ""
|
||||
|
||||
# Complex path pattern that needs replacement
|
||||
COMPLEX_CONFIG_PATH='$([ -f "$([ -d "$HOME/.claude/marketplaces/multiagent-dev/plugins/*/skills/*/config" ] && echo "$HOME/.claude/marketplaces/multiagent-dev/plugins/*/skills/*/config" || find "$HOME/.claude/marketplaces/multiagent-dev/plugins/multiagent-config" -type d -path "*/skills/*" -name "config" 2>/dev/null | head -1).json" ] && echo "$([ -d "$HOME/.claude/marketplaces/multiagent-dev/plugins/*/skills/*/config" ] && echo "$HOME/.claude/marketplaces/multiagent-dev/plugins/*/skills/*/config" || find "$HOME/.claude/marketplaces/multiagent-dev/plugins/multiagent-config" -type d -path "*/skills/*" -name "config" 2>/dev/null | head -1).json" || find "$HOME/.claude/marketplaces/multiagent-dev/plugins/multiagent-core/skills/*" -name "config.json" -type f 2>/dev/null | head -1)'
|
||||
|
||||
SIMPLE_CONFIG_PATH='.multiagent/config.json'
|
||||
|
||||
# Count before
|
||||
COMPLEX_PATHS_BEFORE=$(grep -r "multiagent-core/skills" "$PLUGINS_DIR"/*/commands/*.md "$PLUGINS_DIR"/*/agents/*.md 2>/dev/null | wc -l)
|
||||
|
||||
echo "Before:"
|
||||
echo " - Complex multiagent-core paths: $COMPLEX_PATHS_BEFORE"
|
||||
echo ""
|
||||
|
||||
if $DRY_RUN; then
|
||||
echo "[DRY RUN] Would perform these replacements:"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
FIXED_FILES=0
|
||||
|
||||
# Fix all agent and command files
|
||||
for file in "$PLUGINS_DIR"/*/agents/*.md "$PLUGINS_DIR"/*/commands/*.md; do
|
||||
[ -f "$file" ] || continue
|
||||
|
||||
# Check if file has hardcoded multiagent-core references
|
||||
if grep -q "multiagent-core" "$file" 2>/dev/null; then
|
||||
if $DRY_RUN; then
|
||||
echo "[DRY RUN] Would fix: $file"
|
||||
grep -n "multiagent-core" "$file" | head -3
|
||||
echo ""
|
||||
else
|
||||
# Create backup
|
||||
cp "$file" "$file.backup"
|
||||
|
||||
# Replace all complex config paths with simple .multiagent/config.json
|
||||
sed -i 's|\$HOME/\.\(claude\|multiagent\)/[^"]*config\.json|.multiagent/config.json|g' "$file"
|
||||
sed -i 's|\$(find[^)]*multiagent-core[^)]*)|.multiagent/config.json|g' "$file"
|
||||
sed -i 's|\$(find[^)]*multiagent-config[^)]*)|.multiagent/config.json|g' "$file"
|
||||
|
||||
# Fix script references
|
||||
sed -i 's|\$HOME/\.\(claude\|multiagent\)/[^"]*\.sh|.multiagent/scripts/\$(basename \$0)|g' "$file"
|
||||
sed -i 's|\$(find[^)]*multiagent-core[^)]*\.sh[^)]*)|.multiagent/scripts/\$(basename \$0)|g' "$file"
|
||||
|
||||
# Fix template references
|
||||
sed -i 's|\$HOME/\.\(claude\|multiagent\)/[^"]*templates|.multiagent/templates|g' "$file"
|
||||
sed -i 's|\$(find[^)]*multiagent-core[^)]*templates[^)]*)|.multiagent/templates|g' "$file"
|
||||
|
||||
# Fix specific worktree reference
|
||||
sed -i 's|../multiagent-core-worktrees/|../PROJECT-worktrees/|g' "$file"
|
||||
|
||||
# Fix validation reference
|
||||
sed -i 's|--plugin multiagent-core|--plugin \$(basename \$(git rev-parse --show-toplevel))|g' "$file"
|
||||
|
||||
echo "✓ Fixed: $file"
|
||||
((FIXED_FILES++))
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
|
||||
if $DRY_RUN; then
|
||||
echo "[DRY RUN] Would fix $FIXED_FILES files"
|
||||
else
|
||||
echo "✓ Fixed $FIXED_FILES files"
|
||||
|
||||
# Count after
|
||||
COMPLEX_PATHS_AFTER=$(grep -r "multiagent-core" "$PLUGINS_DIR"/*/commands/*.md "$PLUGINS_DIR"/*/agents/*.md 2>/dev/null | wc -l || echo 0)
|
||||
|
||||
echo ""
|
||||
echo "After:"
|
||||
echo " - Complex multiagent-core paths: $COMPLEX_PATHS_AFTER (was $COMPLEX_PATHS_BEFORE)"
|
||||
echo ""
|
||||
|
||||
if [ "$COMPLEX_PATHS_AFTER" -eq 0 ]; then
|
||||
echo "🎉 All hardcoded paths fixed!"
|
||||
else
|
||||
echo "⚠️ Some references remain - may need manual review"
|
||||
echo ""
|
||||
echo "Remaining issues:"
|
||||
grep -rn "multiagent-core" "$PLUGINS_DIR"/*/commands/*.md "$PLUGINS_DIR"/*/agents/*.md 2>/dev/null | head -5
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Backups saved with .backup extension"
|
||||
echo "To restore: find $PLUGINS_DIR -name '*.backup' -exec bash -c 'mv \"\$0\" \"\${0%.backup}\"' {} \\;"
|
||||
fi
|
||||
79
skills/build-assistant/scripts/fix-script-issues.sh
Executable file
79
skills/build-assistant/scripts/fix-script-issues.sh
Executable file
@@ -0,0 +1,79 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Fix script issues across marketplaces:
|
||||
# 1. Make all .sh scripts executable
|
||||
# 2. Verify script references use absolute paths (they should!)
|
||||
# Usage: bash fix-script-issues.sh <marketplace-directory>
|
||||
|
||||
MARKETPLACE_DIR="${1:-$(pwd)}"
|
||||
|
||||
echo "Fixing script issues in: $MARKETPLACE_DIR"
|
||||
echo "========================================================"
|
||||
echo ""
|
||||
|
||||
# Counter
|
||||
FIXED_PERMS=0
|
||||
WRONG_REFS=0
|
||||
|
||||
echo "## Phase 1: Making all .sh scripts executable"
|
||||
echo ""
|
||||
|
||||
# Find all .sh files and make them executable
|
||||
find "$MARKETPLACE_DIR" -type f -name "*.sh" | while read -r SCRIPT; do
|
||||
if [ ! -x "$SCRIPT" ]; then
|
||||
echo "Making executable: $SCRIPT"
|
||||
chmod +x "$SCRIPT"
|
||||
((FIXED_PERMS++))
|
||||
fi
|
||||
done
|
||||
|
||||
echo "✅ Fixed permissions on $FIXED_PERMS scripts"
|
||||
echo ""
|
||||
|
||||
echo "## Phase 2: Checking script references in markdown files"
|
||||
echo ""
|
||||
|
||||
# Find markdown files with script references that DON'T use absolute paths
|
||||
find "$MARKETPLACE_DIR" -type f -name "*.md" -exec grep -l '!{bash .*\.sh' {} \; | while read -r FILE; do
|
||||
# Check for relative script paths (bad)
|
||||
if grep -q '!{bash plugins/.*\.sh' "$FILE" 2>/dev/null; then
|
||||
echo "⚠️ Found RELATIVE script path in: $FILE"
|
||||
grep -n '!{bash plugins/.*\.sh' "$FILE"
|
||||
((WRONG_REFS++))
|
||||
fi
|
||||
|
||||
# Check for $HOME variable usage (bad - should be ~)
|
||||
if grep -q '!{bash \$HOME/.claude/.*\.sh' "$FILE" 2>/dev/null; then
|
||||
echo "⚠️ Found \$HOME instead of ~ in: $FILE"
|
||||
grep -n '!{bash \$HOME/.claude/.*\.sh' "$FILE"
|
||||
((WRONG_REFS++))
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "========================================================"
|
||||
echo "✅ Made $FIXED_PERMS scripts executable"
|
||||
echo ""
|
||||
|
||||
if [ $WRONG_REFS -gt 0 ]; then
|
||||
echo "⚠️ Found $WRONG_REFS files with incorrect script references"
|
||||
echo ""
|
||||
echo "Script references should use ABSOLUTE paths:"
|
||||
echo " ✅ !{bash ~/.claude/plugins/marketplaces/domain-plugin-builder/plugins/domain-plugin-builder/skills/build-assistant/scripts/validate-agent.sh}"
|
||||
echo " ❌ !{bash plugins/domain-plugin-builder/skills/build-assistant/scripts/validate-agent.sh}"
|
||||
echo " ❌ !{bash \$HOME/.claude/plugins/...}"
|
||||
echo ""
|
||||
echo "Why: Scripts must be callable from ANY working directory"
|
||||
else
|
||||
echo "✅ All script references use absolute paths correctly"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "## Summary"
|
||||
echo ""
|
||||
echo "Executable scripts:"
|
||||
find "$MARKETPLACE_DIR" -type f -name "*.sh" -executable | wc -l
|
||||
echo ""
|
||||
echo "Non-executable scripts:"
|
||||
find "$MARKETPLACE_DIR" -type f -name "*.sh" ! -executable | wc -l
|
||||
echo ""
|
||||
99
skills/build-assistant/scripts/fix-tool-formatting.sh
Executable file
99
skills/build-assistant/scripts/fix-tool-formatting.sh
Executable file
@@ -0,0 +1,99 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Fix tool formatting across all plugins
|
||||
# Converts ALL formats to horizontal comma-separated without quotes
|
||||
# Removes incorrect MCP wildcards and brackets
|
||||
|
||||
# Portable: Use argument or current directory (works from any location)
|
||||
MARKETPLACE_ROOT="${1:-$(pwd)}"
|
||||
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "🔧 Fixing Tool Formatting"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
|
||||
fix_all_tool_formats() {
|
||||
local file="$1"
|
||||
|
||||
python3 - "$file" << 'PYTHON'
|
||||
import sys
|
||||
import re
|
||||
|
||||
file_path = sys.argv[1]
|
||||
|
||||
with open(file_path, 'r') as f:
|
||||
content = f.read()
|
||||
|
||||
original = content
|
||||
|
||||
# Fix 1: Convert JSON array format to comma-separated
|
||||
# tools: ["Bash", "Read", "Write"] -> tools: Bash, Read, Write
|
||||
pattern1 = r'(tools|allowed-tools):\s*\[(.*?)\]'
|
||||
def fix_json_array(match):
|
||||
prefix = match.group(1)
|
||||
tools_str = match.group(2)
|
||||
# Extract tool names from quoted strings
|
||||
tools = re.findall(r'"([^"]+)"', tools_str)
|
||||
return f'{prefix}: {", ".join(tools)}'
|
||||
|
||||
content = re.sub(pattern1, fix_json_array, content, flags=re.DOTALL)
|
||||
|
||||
# Fix 2: Convert vertical lists to horizontal
|
||||
# tools:\n - Bash\n - Read -> tools: Bash, Read
|
||||
pattern2 = r'(tools|allowed-tools):\n((?: - [^\n]+\n)+)'
|
||||
def fix_vertical(match):
|
||||
prefix = match.group(1)
|
||||
tools_section = match.group(2)
|
||||
tools = re.findall(r' - ([^\n]+)', tools_section)
|
||||
return f'{prefix}: {", ".join(tools)}\n'
|
||||
|
||||
content = re.sub(pattern2, fix_vertical, content)
|
||||
|
||||
# Fix 3: Remove (*) from all tools EXCEPT Bash with restrictions
|
||||
# Task(*) -> Task, but keep Bash(git add:*)
|
||||
content = re.sub(r'\b(Task|Read|Write|Edit|Grep|Glob|WebFetch|AskUserQuestion|TodoWrite|SlashCommand)\(\*\)', r'\1', content)
|
||||
|
||||
# Fix 4: Remove wildcards from MCP tools
|
||||
# mcp__server__* -> mcp__server
|
||||
# Task(mcp__*) -> mcp__servername (placeholder)
|
||||
content = re.sub(r'mcp__([^_,)\s]+)__\*', r'mcp__\1', content)
|
||||
content = re.sub(r'Task\(mcp__\*\)', r'mcp__servername', content)
|
||||
|
||||
# Fix 5: Remove brackets from mcp tools (except those with specific tool names)
|
||||
# mcp__server(*) -> mcp__server
|
||||
content = re.sub(r'(mcp__[a-z0-9_]+)\(\*\)', r'\1', content)
|
||||
|
||||
if content != original:
|
||||
with open(file_path, 'w') as f:
|
||||
f.write(content)
|
||||
print(f"✅ Fixed: {file_path}")
|
||||
return True
|
||||
return False
|
||||
PYTHON
|
||||
}
|
||||
|
||||
# Process all agent files
|
||||
echo ""
|
||||
echo "📋 Fixing Agent Files..."
|
||||
find "$MARKETPLACE_ROOT/plugins" -name "*.md" -path "*/agents/*" | while read -r file; do
|
||||
fix_all_tool_formats "$file"
|
||||
done
|
||||
|
||||
# Process all command files
|
||||
echo ""
|
||||
echo "📋 Fixing Command Files..."
|
||||
find "$MARKETPLACE_ROOT/plugins" -name "*.md" -path "*/commands/*" | while read -r file; do
|
||||
fix_all_tool_formats "$file"
|
||||
done
|
||||
|
||||
# Process template files
|
||||
echo ""
|
||||
echo "📋 Fixing Template Files..."
|
||||
find "$MARKETPLACE_ROOT/plugins/domain-plugin-builder/skills/build-assistant/templates" -name "*.md" 2>/dev/null | while read -r file; do
|
||||
fix_all_tool_formats "$file"
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "✅ Tool Formatting Fixed!"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
59
skills/build-assistant/scripts/install-plugin-locally.sh
Executable file
59
skills/build-assistant/scripts/install-plugin-locally.sh
Executable file
@@ -0,0 +1,59 @@
|
||||
#!/usr/bin/env bash
|
||||
# Script: install-plugin-locally.sh
|
||||
# Purpose: Install plugin to local Claude marketplace for testing
|
||||
# Usage: ./install-plugin-locally.sh <plugin-directory>
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
PLUGIN_DIR="${1:?Usage: $0 <plugin-directory>}"
|
||||
MARKETPLACE_DIR="$HOME/.claude/plugins/marketplaces/ai-dev-marketplace"
|
||||
|
||||
echo "[INFO] Installing plugin to local marketplace"
|
||||
|
||||
# Check plugin directory exists
|
||||
if [[ ! -d "$PLUGIN_DIR" ]]; then
|
||||
echo "❌ ERROR: Plugin directory not found: $PLUGIN_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get plugin name
|
||||
PLUGIN_NAME=$(basename "$PLUGIN_DIR")
|
||||
|
||||
# Check if marketplace exists
|
||||
if [[ ! -d "$MARKETPLACE_DIR" ]]; then
|
||||
echo "❌ ERROR: Marketplace not found at $MARKETPLACE_DIR"
|
||||
echo "[INFO] Run: /plugin marketplace add ai-dev-marketplace"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if we're in the development directory
|
||||
DEV_MARKETPLACE="/home/vanman2025/Projects/ai-dev-marketplace"
|
||||
CURRENT_DIR=$(pwd)
|
||||
if [[ "$CURRENT_DIR" == "$DEV_MARKETPLACE" ]]; then
|
||||
echo "[INFO] Running from development directory"
|
||||
else
|
||||
echo "⚠️ WARNING: Not in development directory"
|
||||
echo "[INFO] Expected: $DEV_MARKETPLACE"
|
||||
echo "[INFO] Current: $CURRENT_DIR"
|
||||
fi
|
||||
|
||||
# Copy plugin to marketplace
|
||||
echo "[INFO] Copying plugin to marketplace..."
|
||||
cp -r "$PLUGIN_DIR" "$MARKETPLACE_DIR/plugins/"
|
||||
|
||||
# Update marketplace.json
|
||||
echo "[INFO] Updating marketplace.json..."
|
||||
cp .claude-plugin/marketplace.json "$MARKETPLACE_DIR/.claude-plugin/marketplace.json"
|
||||
|
||||
echo "✅ Plugin installed to local marketplace"
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "📦 NEXT STEP: Install Plugin"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
echo " /plugin install $PLUGIN_NAME@ai-dev-marketplace"
|
||||
echo ""
|
||||
echo " Verify: /$PLUGIN_NAME:init (or any command from the plugin)"
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
exit 0
|
||||
54
skills/build-assistant/scripts/list-agents.sh
Executable file
54
skills/build-assistant/scripts/list-agents.sh
Executable file
@@ -0,0 +1,54 @@
|
||||
#!/bin/bash
|
||||
|
||||
# List all available agents across plugins and global directory
|
||||
# Searches: plugins/*/agents/*.md and ~/.claude/agents/*.md
|
||||
|
||||
# Portable: Use current directory or argument (works from any location)
|
||||
MARKETPLACE_DIR="${1:-$(pwd)}"
|
||||
GLOBAL_AGENTS_DIR="$HOME/.claude/agents"
|
||||
|
||||
echo "=== Available Agents ==="
|
||||
echo ""
|
||||
|
||||
# Track total count
|
||||
TOTAL=0
|
||||
|
||||
# Function to extract agent info from frontmatter
|
||||
extract_agent_info() {
|
||||
local file="$1"
|
||||
local location="$2"
|
||||
|
||||
# Extract name and description from frontmatter
|
||||
local name=$(grep -m1 "^name:" "$file" | cut -d: -f2- | sed 's/^[[:space:]]*//' | sed 's/[[:space:]]*$//')
|
||||
local desc=$(grep -m1 "^description:" "$file" | cut -d: -f2- | sed 's/^[[:space:]]*//' | sed 's/[[:space:]]*$//')
|
||||
|
||||
if [ -n "$name" ]; then
|
||||
echo " - $name"
|
||||
[ -n "$desc" ] && echo " $desc"
|
||||
echo " Location: $location"
|
||||
echo ""
|
||||
((TOTAL++))
|
||||
fi
|
||||
}
|
||||
|
||||
# Find all plugin agents
|
||||
echo "Plugin Agents:"
|
||||
while IFS= read -r agent_file; do
|
||||
plugin_name=$(echo "$agent_file" | sed -E 's|.*/plugins/([^/]+)/agents/.*|\1|')
|
||||
extract_agent_info "$agent_file" "$plugin_name plugin"
|
||||
done < <(find "$MARKETPLACE_DIR/plugins" -type f -path "*/agents/*.md" 2>/dev/null | sort)
|
||||
|
||||
# Find global agents
|
||||
if [ -d "$GLOBAL_AGENTS_DIR" ]; then
|
||||
echo "Global Agents:"
|
||||
while IFS= read -r agent_file; do
|
||||
extract_agent_info "$agent_file" "global"
|
||||
done < <(find "$GLOBAL_AGENTS_DIR" -type f -name "*.md" 2>/dev/null | sort)
|
||||
fi
|
||||
|
||||
echo "---"
|
||||
echo "Total: $TOTAL agents available"
|
||||
echo ""
|
||||
echo "Built-in agents (always available):"
|
||||
echo " - general-purpose: Multi-step tasks and complex questions"
|
||||
echo " - Explore: Fast codebase exploration and search"
|
||||
74
skills/build-assistant/scripts/register-commands-in-settings.sh
Executable file
74
skills/build-assistant/scripts/register-commands-in-settings.sh
Executable file
@@ -0,0 +1,74 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Register plugin commands in .claude/settings.local.json
|
||||
# Usage: ./register-commands-in-settings.sh <plugin-name>
|
||||
|
||||
set -e
|
||||
|
||||
PLUGIN_NAME=$1
|
||||
SETTINGS_FILE="$HOME/.claude/settings.local.json"
|
||||
|
||||
if [ -z "$PLUGIN_NAME" ]; then
|
||||
echo "Usage: $0 <plugin-name>"
|
||||
echo "Example: $0 elevenlabs"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -d "plugins/$PLUGIN_NAME" ]; then
|
||||
echo "ERROR: Plugin directory plugins/$PLUGIN_NAME does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$SETTINGS_FILE" ]; then
|
||||
echo "ERROR: Settings file $SETTINGS_FILE does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "[INFO] Registering commands for plugin: $PLUGIN_NAME"
|
||||
|
||||
# Get list of commands
|
||||
COMMANDS=$(ls plugins/$PLUGIN_NAME/commands/*.md 2>/dev/null | sed 's|plugins/||; s|/commands/|:|; s|.md||' || true)
|
||||
|
||||
if [ -z "$COMMANDS" ]; then
|
||||
echo "[WARN] No commands found for plugin $PLUGIN_NAME"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "[INFO] Found commands:"
|
||||
echo "$COMMANDS"
|
||||
|
||||
# Check if wildcard already registered
|
||||
if grep -q "\"SlashCommand(/$PLUGIN_NAME:\*)\"" "$SETTINGS_FILE"; then
|
||||
echo "[INFO] Commands already registered for $PLUGIN_NAME"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "[INFO] Adding commands to $SETTINGS_FILE"
|
||||
|
||||
# Create temp file with commands to add
|
||||
TEMP_COMMANDS=$(mktemp)
|
||||
echo " \"SlashCommand(/$PLUGIN_NAME:*)\"," > "$TEMP_COMMANDS"
|
||||
while IFS= read -r cmd; do
|
||||
echo " \"SlashCommand(/$cmd)\"," >> "$TEMP_COMMANDS"
|
||||
done <<< "$COMMANDS"
|
||||
|
||||
# Find the line before "Bash" and insert commands there
|
||||
LINE_NUM=$(grep -n '"Bash"' "$SETTINGS_FILE" | head -1 | cut -d: -f1)
|
||||
|
||||
if [ -z "$LINE_NUM" ]; then
|
||||
echo "ERROR: Could not find 'Bash' entry in $SETTINGS_FILE"
|
||||
rm "$TEMP_COMMANDS"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Insert before Bash line
|
||||
head -n $((LINE_NUM - 1)) "$SETTINGS_FILE" > "${SETTINGS_FILE}.tmp"
|
||||
cat "$TEMP_COMMANDS" >> "${SETTINGS_FILE}.tmp"
|
||||
tail -n +$LINE_NUM "$SETTINGS_FILE" >> "${SETTINGS_FILE}.tmp"
|
||||
|
||||
# Replace original file
|
||||
mv "${SETTINGS_FILE}.tmp" "$SETTINGS_FILE"
|
||||
rm "$TEMP_COMMANDS"
|
||||
|
||||
echo "[SUCCESS] Commands registered for $PLUGIN_NAME"
|
||||
echo "[INFO] Added $(echo "$COMMANDS" | wc -l) commands plus wildcard"
|
||||
95
skills/build-assistant/scripts/register-skills-in-settings.sh
Executable file
95
skills/build-assistant/scripts/register-skills-in-settings.sh
Executable file
@@ -0,0 +1,95 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Register plugin skills in ~/.claude/settings.json
|
||||
# Usage: ./register-skills-in-settings.sh <plugin-name>
|
||||
|
||||
set -e
|
||||
|
||||
PLUGIN_NAME=$1
|
||||
SETTINGS_FILE="$HOME/.claude/settings.json"
|
||||
|
||||
if [ -z "$PLUGIN_NAME" ]; then
|
||||
echo "Usage: $0 <plugin-name>"
|
||||
echo "Example: $0 domain-plugin-builder"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -d "plugins/$PLUGIN_NAME" ]; then
|
||||
echo "ERROR: Plugin directory plugins/$PLUGIN_NAME does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$SETTINGS_FILE" ]; then
|
||||
echo "ERROR: Settings file $SETTINGS_FILE does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "[INFO] Registering skills for plugin: $PLUGIN_NAME"
|
||||
|
||||
# Get list of skills (directories in skills/)
|
||||
SKILL_DIRS=$(find plugins/$PLUGIN_NAME/skills -maxdepth 1 -mindepth 1 -type d 2>/dev/null || true)
|
||||
|
||||
if [ -z "$SKILL_DIRS" ]; then
|
||||
echo "[WARN] No skills found for plugin $PLUGIN_NAME"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "[INFO] Found skills:"
|
||||
for SKILL_DIR in $SKILL_DIRS; do
|
||||
SKILL_NAME=$(basename "$SKILL_DIR")
|
||||
echo " - $SKILL_NAME"
|
||||
done
|
||||
|
||||
# Check each skill and add if not already registered
|
||||
for SKILL_DIR in $SKILL_DIRS; do
|
||||
SKILL_NAME=$(basename "$SKILL_DIR")
|
||||
SKILL_ENTRY="Skill($PLUGIN_NAME:$SKILL_NAME)"
|
||||
|
||||
# Check if this skill is already registered
|
||||
if grep -q "\"$SKILL_ENTRY\"" "$SETTINGS_FILE"; then
|
||||
echo "[INFO] Skill already registered: $SKILL_NAME"
|
||||
continue
|
||||
fi
|
||||
|
||||
echo "[INFO] Adding skill to settings.json: $SKILL_NAME"
|
||||
|
||||
# Find the last Skill() entry and add after it
|
||||
# Use Python for JSON manipulation to ensure valid JSON
|
||||
python3 << EOF
|
||||
import json
|
||||
|
||||
with open('$SETTINGS_FILE', 'r') as f:
|
||||
settings = json.load(f)
|
||||
|
||||
# Add skill to permissions.allow
|
||||
if 'permissions' not in settings:
|
||||
settings['permissions'] = {}
|
||||
if 'allow' not in settings['permissions']:
|
||||
settings['permissions']['allow'] = []
|
||||
|
||||
skill_entry = '$SKILL_ENTRY'
|
||||
if skill_entry not in settings['permissions']['allow']:
|
||||
# Find position after last Skill() entry
|
||||
last_skill_index = -1
|
||||
for i, entry in enumerate(settings['permissions']['allow']):
|
||||
if isinstance(entry, str) and entry.startswith('Skill('):
|
||||
last_skill_index = i
|
||||
|
||||
if last_skill_index >= 0:
|
||||
# Insert after last skill
|
||||
settings['permissions']['allow'].insert(last_skill_index + 1, skill_entry)
|
||||
else:
|
||||
# No skills yet, add at end
|
||||
settings['permissions']['allow'].append(skill_entry)
|
||||
|
||||
with open('$SETTINGS_FILE', 'w') as f:
|
||||
json.dump(settings, f, indent=2)
|
||||
|
||||
print(f"[SUCCESS] Added {skill_entry} to settings.json")
|
||||
else:
|
||||
print(f"[INFO] Skill already registered: {skill_entry}")
|
||||
EOF
|
||||
|
||||
done
|
||||
|
||||
echo "[SUCCESS] Skill registration complete for plugin: $PLUGIN_NAME"
|
||||
99
skills/build-assistant/scripts/sync-marketplace.sh
Executable file
99
skills/build-assistant/scripts/sync-marketplace.sh
Executable file
@@ -0,0 +1,99 @@
|
||||
#!/usr/bin/env bash
|
||||
# Script: sync-marketplace.sh
|
||||
# Purpose: Sync all plugins to marketplace.json registry
|
||||
# Usage: ./sync-marketplace.sh
|
||||
# This ensures marketplace.json is up-to-date with all plugins
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Find script location and navigate to marketplace root
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
MARKETPLACE_ROOT="$(cd "$SCRIPT_DIR/../../../../.." && pwd)"
|
||||
|
||||
cd "$MARKETPLACE_ROOT"
|
||||
|
||||
MARKETPLACE_FILE=".claude-plugin/marketplace.json"
|
||||
BACKUP_FILE=".claude-plugin/marketplace.json.backup"
|
||||
|
||||
echo "[INFO] Syncing plugins to marketplace.json in: $MARKETPLACE_ROOT"
|
||||
|
||||
# Find all plugins with plugin.json
|
||||
PLUGINS=()
|
||||
PLUGIN_JSON_FILES=$(find plugins -path "*/.claude-plugin/plugin.json" -type f | sort)
|
||||
|
||||
for plugin_json in $PLUGIN_JSON_FILES; do
|
||||
PLUGIN_DIR=$(dirname "$(dirname "$plugin_json")")
|
||||
PLUGIN_NAME=$(basename "$PLUGIN_DIR")
|
||||
|
||||
# Read plugin.json data
|
||||
DESCRIPTION=$(python3 -c "import json; print(json.load(open('$plugin_json'))['description'])" 2>/dev/null || echo "No description")
|
||||
VERSION=$(python3 -c "import json; print(json.load(open('$plugin_json'))['version'])" 2>/dev/null || echo "1.0.0")
|
||||
|
||||
# Extract author if exists
|
||||
AUTHOR_NAME=$(python3 -c "import json; d=json.load(open('$plugin_json')); print(d.get('author', {}).get('name', 'vanman2024'))" 2>/dev/null || echo "vanman2024")
|
||||
AUTHOR_EMAIL=$(python3 -c "import json; d=json.load(open('$plugin_json')); print(d.get('author', {}).get('email', 'noreply@ai-dev-marketplace.dev'))" 2>/dev/null || echo "noreply@ai-dev-marketplace.dev")
|
||||
|
||||
# Extract keywords if exists
|
||||
KEYWORDS=$(python3 -c "import json; d=json.load(open('$plugin_json')); print(','.join(['\"' + k + '\"' for k in d.get('keywords', [])]))" 2>/dev/null || echo "")
|
||||
|
||||
# Build plugin entry
|
||||
PLUGIN_ENTRY=$(cat <<EOF
|
||||
{
|
||||
"name": "$PLUGIN_NAME",
|
||||
"description": "$DESCRIPTION",
|
||||
"version": "$VERSION",
|
||||
"author": {
|
||||
"name": "$AUTHOR_NAME",
|
||||
"email": "$AUTHOR_EMAIL"
|
||||
},
|
||||
"source": "./plugins/$PLUGIN_NAME",
|
||||
"category": "development",
|
||||
"keywords": [$KEYWORDS]
|
||||
}
|
||||
EOF
|
||||
)
|
||||
|
||||
PLUGINS+=("$PLUGIN_ENTRY")
|
||||
done
|
||||
|
||||
# Build marketplace.json
|
||||
PLUGIN_COUNT=${#PLUGINS[@]}
|
||||
PLUGINS_JSON=""
|
||||
|
||||
for i in "${!PLUGINS[@]}"; do
|
||||
PLUGINS_JSON+="${PLUGINS[$i]}"
|
||||
if [[ $i -lt $((PLUGIN_COUNT - 1)) ]]; then
|
||||
PLUGINS_JSON+=","
|
||||
fi
|
||||
done
|
||||
|
||||
# Write marketplace.json
|
||||
cat > "$MARKETPLACE_FILE" <<EOF
|
||||
{
|
||||
"name": "ai-dev-marketplace",
|
||||
"version": "1.0.0",
|
||||
"description": "AI Development Marketplace - Master repository for tech-specific plugins (SDKs, frameworks, platforms)",
|
||||
"owner": {
|
||||
"name": "AI Development Team",
|
||||
"email": "noreply@ai-dev-marketplace.dev"
|
||||
},
|
||||
"plugins": [
|
||||
$PLUGINS_JSON
|
||||
]
|
||||
}
|
||||
EOF
|
||||
|
||||
# Format JSON
|
||||
python3 -m json.tool "$MARKETPLACE_FILE" > "${MARKETPLACE_FILE}.tmp" && mv "${MARKETPLACE_FILE}.tmp" "$MARKETPLACE_FILE"
|
||||
|
||||
echo "✅ Updated marketplace.json with $PLUGIN_COUNT plugins"
|
||||
|
||||
# Show summary
|
||||
echo ""
|
||||
echo "Registered plugins in marketplace:"
|
||||
for plugin_json in $PLUGIN_JSON_FILES; do
|
||||
PLUGIN_DIR=$(dirname "$(dirname "$plugin_json")")
|
||||
PLUGIN_NAME=$(basename "$PLUGIN_DIR")
|
||||
VERSION=$(python3 -c "import json; print(json.load(open('$plugin_json'))['version'])" 2>/dev/null || echo "1.0.0")
|
||||
echo " - $PLUGIN_NAME (v$VERSION)"
|
||||
done
|
||||
93
skills/build-assistant/scripts/sync-settings-permissions.sh
Executable file
93
skills/build-assistant/scripts/sync-settings-permissions.sh
Executable file
@@ -0,0 +1,93 @@
|
||||
#!/usr/bin/env bash
|
||||
# Script: sync-settings-permissions.sh
|
||||
# Purpose: Automatically sync all plugin commands to .claude/settings.local.json
|
||||
# Usage: ./sync-settings-permissions.sh
|
||||
# This ensures all commands are registered and can be invoked
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Find script location and navigate to marketplace root
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
MARKETPLACE_ROOT="$(cd "$SCRIPT_DIR/../../../../.." && pwd)"
|
||||
|
||||
cd "$MARKETPLACE_ROOT"
|
||||
|
||||
SETTINGS_FILE="$HOME/.claude/settings.local.json"
|
||||
BACKUP_FILE="$HOME/.claude/settings.local.json.backup"
|
||||
|
||||
echo "[INFO] Syncing plugin commands to settings.local.json from: $MARKETPLACE_ROOT"
|
||||
|
||||
# Find all plugins
|
||||
PLUGINS=$(find plugins -mindepth 1 -maxdepth 1 -type d | sort)
|
||||
|
||||
# Build command list
|
||||
COMMANDS=()
|
||||
|
||||
for plugin in $PLUGINS; do
|
||||
PLUGIN_NAME=$(basename "$plugin")
|
||||
|
||||
# Check if plugin has commands
|
||||
if [[ -d "$plugin/commands" ]]; then
|
||||
# Add wildcard permission for the plugin
|
||||
COMMANDS+=(" \"SlashCommand(/$PLUGIN_NAME:*)\"")
|
||||
|
||||
# Find all command files
|
||||
COMMAND_FILES=$(find "$plugin/commands" -name "*.md" -type f | sort)
|
||||
|
||||
for cmd_file in $COMMAND_FILES; do
|
||||
CMD_NAME=$(basename "$cmd_file" .md)
|
||||
COMMANDS+=(" \"SlashCommand(/$PLUGIN_NAME:$CMD_NAME)\"")
|
||||
done
|
||||
fi
|
||||
done
|
||||
|
||||
# Add base tools
|
||||
BASE_TOOLS=(
|
||||
"Bash"
|
||||
"Write"
|
||||
"Read"
|
||||
"Edit"
|
||||
"WebFetch"
|
||||
"WebSearch"
|
||||
"AskUserQuestion"
|
||||
"Glob"
|
||||
"Grep"
|
||||
"Task"
|
||||
"Skill"
|
||||
)
|
||||
|
||||
for tool in "${BASE_TOOLS[@]}"; do
|
||||
COMMANDS+=(" \"$tool\"")
|
||||
done
|
||||
|
||||
# Build JSON
|
||||
cat > "$SETTINGS_FILE" <<EOF
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
$(IFS=$',\n'; echo "${COMMANDS[*]}")
|
||||
]
|
||||
},
|
||||
"enableAllProjectMcpServers": true,
|
||||
"enabledMcpjsonServers": [
|
||||
"filesystem",
|
||||
"playwright",
|
||||
"context7",
|
||||
"postman"
|
||||
]
|
||||
}
|
||||
EOF
|
||||
|
||||
echo "✅ Updated settings.local.json with $(echo "${COMMANDS[@]}" | wc -w) permissions"
|
||||
echo "[INFO] All plugin commands are now registered"
|
||||
|
||||
# Show summary
|
||||
echo ""
|
||||
echo "Registered plugins:"
|
||||
for plugin in $PLUGINS; do
|
||||
PLUGIN_NAME=$(basename "$plugin")
|
||||
CMD_COUNT=$(find "$plugin/commands" -name "*.md" -type f 2>/dev/null | wc -l || echo "0")
|
||||
if [[ $CMD_COUNT -gt 0 ]]; then
|
||||
echo " - $PLUGIN_NAME ($CMD_COUNT commands)"
|
||||
fi
|
||||
done
|
||||
78
skills/build-assistant/scripts/sync-to-local-marketplace.sh
Executable file
78
skills/build-assistant/scripts/sync-to-local-marketplace.sh
Executable file
@@ -0,0 +1,78 @@
|
||||
#!/usr/bin/env bash
|
||||
# Script: sync-to-local-marketplace.sh
|
||||
# Purpose: Automatically sync development directory to installed marketplace
|
||||
# Usage: ./sync-to-local-marketplace.sh [plugin-name]
|
||||
# Called by: git pre-commit hook (automatic) or manually
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
DEV_DIR="/home/vanman2025/Projects/ai-dev-marketplace"
|
||||
MARKETPLACE_DIR="$HOME/.claude/plugins/marketplaces/ai-dev-marketplace"
|
||||
|
||||
# Check if marketplace exists
|
||||
if [[ ! -d "$MARKETPLACE_DIR" ]]; then
|
||||
echo "[INFO] Marketplace not installed at $MARKETPLACE_DIR"
|
||||
echo "[INFO] Run: /plugin marketplace add vanman2024/ai-dev-marketplace"
|
||||
exit 0 # Not an error - just not installed
|
||||
fi
|
||||
|
||||
# Check if marketplace is a git repo
|
||||
if [[ ! -d "$MARKETPLACE_DIR/.git" ]]; then
|
||||
echo "⚠️ WARNING: Marketplace is not a git repository"
|
||||
echo "[INFO] Expected git clone, found regular directory"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd "$DEV_DIR"
|
||||
|
||||
# If plugin name provided, sync only that plugin
|
||||
if [[ -n "${1:-}" ]]; then
|
||||
PLUGIN_NAME="$1"
|
||||
echo "[INFO] Syncing plugin: $PLUGIN_NAME"
|
||||
|
||||
if [[ ! -d "plugins/$PLUGIN_NAME" ]]; then
|
||||
echo "❌ ERROR: Plugin not found: plugins/$PLUGIN_NAME"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Copy plugin directory
|
||||
rsync -av --delete "plugins/$PLUGIN_NAME/" "$MARKETPLACE_DIR/plugins/$PLUGIN_NAME/"
|
||||
echo "✅ Synced plugin: $PLUGIN_NAME"
|
||||
else
|
||||
# Sync entire repository
|
||||
echo "[INFO] Syncing entire marketplace..."
|
||||
|
||||
# Sync all plugins
|
||||
rsync -av --delete plugins/ "$MARKETPLACE_DIR/plugins/"
|
||||
|
||||
# Sync marketplace.json
|
||||
rsync -av .claude-plugin/marketplace.json "$MARKETPLACE_DIR/.claude-plugin/marketplace.json"
|
||||
|
||||
# Sync other important files
|
||||
rsync -av README.md "$MARKETPLACE_DIR/README.md"
|
||||
|
||||
echo "✅ Synced all plugins and marketplace metadata"
|
||||
fi
|
||||
|
||||
# Show what was synced
|
||||
cd "$MARKETPLACE_DIR"
|
||||
git status --short || true
|
||||
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "📦 LOCAL MARKETPLACE SYNCED"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
echo "Changes are immediately available to Claude Code!"
|
||||
echo ""
|
||||
echo "To sync these changes to GitHub:"
|
||||
echo " 1. cd $DEV_DIR"
|
||||
echo " 2. git add -A && git commit -m 'feat: ...'"
|
||||
echo " 3. git push origin master"
|
||||
echo ""
|
||||
echo "To pull GitHub changes to local marketplace:"
|
||||
echo " /plugin marketplace update ai-dev-marketplace"
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
|
||||
exit 0
|
||||
163
skills/build-assistant/scripts/test-build-system.sh
Executable file
163
skills/build-assistant/scripts/test-build-system.sh
Executable file
@@ -0,0 +1,163 @@
|
||||
#!/usr/bin/env bash
|
||||
# Script: test-build-system.sh
|
||||
# Purpose: Automated testing for domain-plugin-builder infrastructure
|
||||
# Usage: ./test-build-system.sh [--quick|--full]
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PLUGIN_DIR="$HOME/.claude/plugins/marketplaces/domain-plugin-builder/plugins/domain-plugin-builder"
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
PASSED=0
|
||||
FAILED=0
|
||||
SKIPPED=0
|
||||
|
||||
echo "================================================"
|
||||
echo "Domain Plugin Builder Testing Suite"
|
||||
echo "================================================"
|
||||
echo ""
|
||||
echo "Testing: $PLUGIN_DIR"
|
||||
echo ""
|
||||
|
||||
# Test functions
|
||||
test_file_exists() {
|
||||
local file=$1
|
||||
if [ -f "$file" ]; then
|
||||
echo -e "${GREEN}✓${NC} $file"
|
||||
PASSED=$((PASSED + 1))
|
||||
return 0
|
||||
else
|
||||
echo -e "${RED}✗${NC} $file (missing)"
|
||||
FAILED=$((FAILED + 1))
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
test_dir_exists() {
|
||||
local dir=$1
|
||||
if [ -d "$dir" ]; then
|
||||
echo -e "${GREEN}✓${NC} $dir/"
|
||||
PASSED=$((PASSED + 1))
|
||||
return 0
|
||||
else
|
||||
echo -e "${RED}✗${NC} $dir/ (missing)"
|
||||
FAILED=$((FAILED + 1))
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
test_executable() {
|
||||
local file=$1
|
||||
if [ -x "$file" ]; then
|
||||
echo -e "${GREEN}✓${NC} $file (executable)"
|
||||
PASSED=$((PASSED + 1))
|
||||
return 0
|
||||
else
|
||||
echo -e "${RED}✗${NC} $file (not executable)"
|
||||
FAILED=$((FAILED + 1))
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Test 1: Core Directory Structure
|
||||
echo "[1/8] Testing Core Directory Structure..."
|
||||
test_dir_exists "$PLUGIN_DIR/commands"
|
||||
test_dir_exists "$PLUGIN_DIR/agents"
|
||||
test_dir_exists "$PLUGIN_DIR/skills"
|
||||
test_dir_exists "$PLUGIN_DIR/docs"
|
||||
test_dir_exists "$PLUGIN_DIR/skills/build-assistant/scripts"
|
||||
test_dir_exists "$PLUGIN_DIR/skills/build-assistant/templates"
|
||||
echo ""
|
||||
|
||||
# Test 2: Commands
|
||||
echo "[2/8] Testing Commands..."
|
||||
test_file_exists "$PLUGIN_DIR/commands/plugin-create.md"
|
||||
test_file_exists "$PLUGIN_DIR/commands/build-plugin.md"
|
||||
test_file_exists "$PLUGIN_DIR/commands/agents-create.md"
|
||||
test_file_exists "$PLUGIN_DIR/commands/slash-commands-create.md"
|
||||
test_file_exists "$PLUGIN_DIR/commands/skills-create.md"
|
||||
test_file_exists "$PLUGIN_DIR/commands/hooks-create.md"
|
||||
test_file_exists "$PLUGIN_DIR/commands/validate.md"
|
||||
echo ""
|
||||
|
||||
# Test 3: Agents
|
||||
echo "[3/8] Testing Agents..."
|
||||
test_file_exists "$PLUGIN_DIR/agents/agents-builder.md"
|
||||
test_file_exists "$PLUGIN_DIR/agents/slash-commands-builder.md"
|
||||
test_file_exists "$PLUGIN_DIR/agents/skills-builder.md"
|
||||
test_file_exists "$PLUGIN_DIR/agents/hooks-builder.md"
|
||||
test_file_exists "$PLUGIN_DIR/agents/plugin-validator.md"
|
||||
echo ""
|
||||
|
||||
# Test 4: Skills
|
||||
echo "[4/8] Testing Skills..."
|
||||
test_dir_exists "$PLUGIN_DIR/skills/build-assistant"
|
||||
test_file_exists "$PLUGIN_DIR/skills/build-assistant/SKILL.md"
|
||||
test_file_exists "$PLUGIN_DIR/skills/build-assistant/reference.md"
|
||||
test_file_exists "$PLUGIN_DIR/skills/build-assistant/examples.md"
|
||||
echo ""
|
||||
|
||||
# Test 5: Templates
|
||||
echo "[5/8] Testing Templates..."
|
||||
test_dir_exists "$PLUGIN_DIR/skills/build-assistant/templates/agents"
|
||||
test_dir_exists "$PLUGIN_DIR/skills/build-assistant/templates/commands"
|
||||
test_dir_exists "$PLUGIN_DIR/skills/build-assistant/templates/skills"
|
||||
test_file_exists "$PLUGIN_DIR/skills/build-assistant/templates/agents/agent-with-phased-webfetch.md"
|
||||
test_file_exists "$PLUGIN_DIR/skills/build-assistant/templates/commands/template-command-patterns.md"
|
||||
test_file_exists "$PLUGIN_DIR/skills/build-assistant/templates/skills/SKILL.md.template"
|
||||
echo ""
|
||||
|
||||
# Test 6: Documentation
|
||||
echo "[6/8] Testing Documentation..."
|
||||
test_file_exists "$PLUGIN_DIR/README.md"
|
||||
test_file_exists "$PLUGIN_DIR/CLAUDE.md"
|
||||
test_dir_exists "$PLUGIN_DIR/docs/frameworks/claude"
|
||||
test_dir_exists "$PLUGIN_DIR/docs/frameworks/claude/agents"
|
||||
test_dir_exists "$PLUGIN_DIR/docs/frameworks/claude/plugins"
|
||||
test_dir_exists "$PLUGIN_DIR/docs/frameworks/claude/reference"
|
||||
test_file_exists "$PLUGIN_DIR/docs/frameworks/claude/agents/agent-color-decision.md"
|
||||
test_file_exists "$PLUGIN_DIR/docs/frameworks/claude/agents/agent-color-standard.md"
|
||||
test_file_exists "$PLUGIN_DIR/docs/frameworks/claude/reference/component-decision-framework.md"
|
||||
test_file_exists "$PLUGIN_DIR/docs/frameworks/claude/reference/dans-composition-pattern.md"
|
||||
echo ""
|
||||
|
||||
# Test 7: Validation Scripts
|
||||
echo "[7/8] Testing Validation Scripts..."
|
||||
test_executable "$PLUGIN_DIR/skills/build-assistant/scripts/validate-agent.sh"
|
||||
test_executable "$PLUGIN_DIR/skills/build-assistant/scripts/validate-command.sh"
|
||||
test_executable "$PLUGIN_DIR/skills/build-assistant/scripts/validate-skill.sh"
|
||||
test_executable "$PLUGIN_DIR/skills/build-assistant/scripts/validate-plugin.sh"
|
||||
test_executable "$PLUGIN_DIR/skills/build-assistant/scripts/validate-all.sh"
|
||||
test_executable "$PLUGIN_DIR/skills/build-assistant/scripts/sync-marketplace.sh"
|
||||
test_executable "$PLUGIN_DIR/skills/build-assistant/scripts/register-commands-in-settings.sh"
|
||||
test_executable "$PLUGIN_DIR/skills/build-assistant/scripts/register-skills-in-settings.sh"
|
||||
echo ""
|
||||
|
||||
# Test 8: Configuration Files
|
||||
echo "[8/8] Testing Configuration Files..."
|
||||
test_file_exists "$PLUGIN_DIR/.claude-plugin/plugin.json"
|
||||
test_file_exists "$HOME/.claude/plugins/marketplaces/domain-plugin-builder/docs/security/SECURITY-RULES.md"
|
||||
echo ""
|
||||
|
||||
# Summary
|
||||
echo "================================================"
|
||||
echo "Test Summary"
|
||||
echo "================================================"
|
||||
echo -e "${GREEN}Passed:${NC} $PASSED"
|
||||
echo -e "${RED}Failed:${NC} $FAILED"
|
||||
echo -e "${YELLOW}Skipped:${NC} $SKIPPED"
|
||||
echo ""
|
||||
|
||||
if [ $FAILED -eq 0 ]; then
|
||||
echo -e "${GREEN}✓ All tests passed!${NC}"
|
||||
exit 0
|
||||
else
|
||||
echo -e "${RED}✗ Some tests failed${NC}"
|
||||
exit 1
|
||||
fi
|
||||
88
skills/build-assistant/scripts/validate-agent-references.sh
Executable file
88
skills/build-assistant/scripts/validate-agent-references.sh
Executable file
@@ -0,0 +1,88 @@
|
||||
#!/bin/bash
|
||||
# Validate that all agent references in commands exist
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PLUGIN_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)"
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "Usage: $0 <plugin-path>"
|
||||
echo "Example: $0 plugins/domain-plugin-builder"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PLUGIN_PATH="$1"
|
||||
|
||||
if [ ! -d "$PLUGIN_PATH" ]; then
|
||||
echo "❌ Error: Plugin directory not found: $PLUGIN_PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "🔍 Validating agent references in: $PLUGIN_PATH"
|
||||
echo ""
|
||||
|
||||
# Extract all agent references from commands
|
||||
AGENT_REFS=$(grep -rh 'subagent_type="[^"]*"' "$PLUGIN_PATH/commands/" 2>/dev/null | \
|
||||
grep -o 'subagent_type="[^"]*"' | \
|
||||
sed 's/subagent_type="//; s/"$//' | \
|
||||
sed 's/.*://' | \
|
||||
sort -u)
|
||||
|
||||
if [ -z "$AGENT_REFS" ]; then
|
||||
echo "✅ No agent references found in commands"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
TOTAL=0
|
||||
VALID=0
|
||||
INVALID=0
|
||||
MISSING_AGENTS=()
|
||||
|
||||
echo "📋 Checking agent references..."
|
||||
echo ""
|
||||
|
||||
for agent in $AGENT_REFS; do
|
||||
TOTAL=$((TOTAL + 1))
|
||||
AGENT_FILE="$PLUGIN_PATH/agents/${agent}.md"
|
||||
|
||||
if [ -f "$AGENT_FILE" ]; then
|
||||
echo " ✅ $agent"
|
||||
VALID=$((VALID + 1))
|
||||
else
|
||||
echo " ❌ $agent (MISSING: $AGENT_FILE)"
|
||||
INVALID=$((INVALID + 1))
|
||||
MISSING_AGENTS+=("$agent")
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "📊 Summary:"
|
||||
echo " Total agent references: $TOTAL"
|
||||
echo " Valid: $VALID"
|
||||
echo " Invalid: $INVALID"
|
||||
echo ""
|
||||
|
||||
if [ $INVALID -gt 0 ]; then
|
||||
echo "❌ VALIDATION FAILED"
|
||||
echo ""
|
||||
echo "Commands reference non-existent agents:"
|
||||
for agent in "${MISSING_AGENTS[@]}"; do
|
||||
echo " - $agent (referenced in commands but agents/$agent.md doesn't exist)"
|
||||
done
|
||||
echo ""
|
||||
echo "🔧 FIX THIS BY:"
|
||||
echo " 1. Check which commands reference these agents:"
|
||||
echo " grep -r 'subagent_type=\".*:$agent\"' $PLUGIN_PATH/commands/"
|
||||
echo ""
|
||||
echo " 2. Update commands to use ACTUAL agent names from agents/ directory:"
|
||||
echo " ls $PLUGIN_PATH/agents/"
|
||||
echo ""
|
||||
echo " 3. Fix the subagent_type in commands to match real agent filenames"
|
||||
echo ""
|
||||
echo "❌ DO NOT create new agents to match wrong command references!"
|
||||
echo "✅ FIX the commands to use correct existing agent names!"
|
||||
exit 1
|
||||
else
|
||||
echo "✅ ALL AGENT REFERENCES VALID"
|
||||
exit 0
|
||||
fi
|
||||
68
skills/build-assistant/scripts/validate-agent.sh
Executable file
68
skills/build-assistant/scripts/validate-agent.sh
Executable file
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env bash
|
||||
# Script: validate-agent.sh
|
||||
# Purpose: Validate agent file compliance with framework standards
|
||||
# Subsystem: build-system
|
||||
# Called by: /build:agent command after generation
|
||||
# Outputs: Validation report to stdout
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
AGENT_FILE="${1:?Usage: $0 <agent-file>}"
|
||||
|
||||
echo "[INFO] Validating agent file: $AGENT_FILE"
|
||||
|
||||
# Check file exists
|
||||
if [[ ! -f "$AGENT_FILE" ]]; then
|
||||
echo "❌ ERROR: File not found: $AGENT_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check frontmatter exists
|
||||
if ! grep -q "^---$" "$AGENT_FILE"; then
|
||||
echo "❌ ERROR: Missing frontmatter"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check required frontmatter fields
|
||||
REQUIRED_FIELDS=("name:" "description:" "model:")
|
||||
for field in "${REQUIRED_FIELDS[@]}"; do
|
||||
if ! grep -q "^$field" "$AGENT_FILE"; then
|
||||
echo "❌ ERROR: Missing required field: $field"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# Warn if tools field is present (agents should inherit tools)
|
||||
if grep -q "^tools:" "$AGENT_FILE"; then
|
||||
echo "⚠️ WARNING: tools field found - agents should inherit tools from parent, not specify them"
|
||||
fi
|
||||
|
||||
# Check for incorrect MCP server naming (common mistake: mcp__supabase instead of mcp__plugin_supabase_supabase)
|
||||
INVALID_MCP_NAMES=("mcp__supabase" "mcp__shadcn" "mcp__nextjs" "mcp__vercel-ai")
|
||||
for invalid_name in "${INVALID_MCP_NAMES[@]}"; do
|
||||
if grep -q "\`$invalid_name\`" "$AGENT_FILE" 2>/dev/null; then
|
||||
echo "❌ ERROR: Found $invalid_name - plugin-specific MCP servers must use full name:"
|
||||
echo " - Use: mcp__plugin_supabase_supabase (not mcp__supabase)"
|
||||
echo " - Use: mcp__plugin_*_shadcn (not mcp__shadcn)"
|
||||
echo " Generic MCP servers are fine: mcp__github, mcp__filesystem, mcp__docker, mcp__fetch, etc."
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# Check Step 0 exists (optional - only for validator agents)
|
||||
if ! grep -q "### Step 0: Load Required Context" "$AGENT_FILE"; then
|
||||
echo "⚠️ WARNING: Missing Step 0: Load Required Context section (only required for validator agents)"
|
||||
fi
|
||||
|
||||
# Check for @ symbol references
|
||||
if ! grep -q 'Read("' "$AGENT_FILE"; then
|
||||
echo "⚠️ WARNING: No Read() calls found - agent may not load context"
|
||||
fi
|
||||
|
||||
# Check Success Criteria exists (optional - only for validator agents)
|
||||
if ! grep -q "## Success Criteria" "$AGENT_FILE"; then
|
||||
echo "⚠️ WARNING: Missing Success Criteria section (only required for validator agents)"
|
||||
fi
|
||||
|
||||
echo "✅ Agent validation passed"
|
||||
exit 0
|
||||
157
skills/build-assistant/scripts/validate-all.sh
Executable file
157
skills/build-assistant/scripts/validate-all.sh
Executable file
@@ -0,0 +1,157 @@
|
||||
#!/usr/bin/env bash
|
||||
# validate-all.sh - Master validation script for entire plugin
|
||||
# Usage: validate-all.sh <plugin-directory>
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
PLUGIN_DIR="${1:?Plugin directory required}"
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Counters
|
||||
TOTAL_COMMANDS=0
|
||||
PASSED_COMMANDS=0
|
||||
TOTAL_AGENTS=0
|
||||
PASSED_AGENTS=0
|
||||
TOTAL_SKILLS=0
|
||||
PASSED_SKILLS=0
|
||||
|
||||
echo "========================================="
|
||||
echo " Plugin Validation: $(basename "$PLUGIN_DIR")"
|
||||
echo "========================================="
|
||||
echo ""
|
||||
|
||||
# Validate plugin structure
|
||||
echo "[1/4] Validating plugin structure..."
|
||||
if bash "$SCRIPT_DIR/validate-plugin.sh" "$PLUGIN_DIR"; then
|
||||
echo -e "${GREEN}✅ Plugin structure valid${NC}"
|
||||
else
|
||||
echo -e "${RED}❌ Plugin structure invalid${NC}"
|
||||
exit 1
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Validate all commands
|
||||
echo "[2/4] Validating commands..."
|
||||
if [ -d "$PLUGIN_DIR/commands" ]; then
|
||||
for cmd in "$PLUGIN_DIR/commands"/*.md; do
|
||||
if [ -f "$cmd" ]; then
|
||||
TOTAL_COMMANDS=$((TOTAL_COMMANDS + 1))
|
||||
CMD_NAME=$(basename "$cmd")
|
||||
|
||||
if bash "$SCRIPT_DIR/validate-command.sh" "$cmd" > /dev/null 2>&1; then
|
||||
PASSED_COMMANDS=$((PASSED_COMMANDS + 1))
|
||||
echo -e " ${GREEN}✅${NC} $CMD_NAME"
|
||||
else
|
||||
echo -e " ${RED}❌${NC} $CMD_NAME"
|
||||
# Show errors for failed commands
|
||||
bash "$SCRIPT_DIR/validate-command.sh" "$cmd" 2>&1 | grep -E "ERROR|WARNING" || true
|
||||
fi
|
||||
fi
|
||||
done
|
||||
else
|
||||
echo -e "${YELLOW}⚠ No commands directory found${NC}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Commands: $PASSED_COMMANDS/$TOTAL_COMMANDS passed"
|
||||
echo ""
|
||||
|
||||
# Validate all agents
|
||||
echo "[3/4] Validating agents..."
|
||||
if [ -d "$PLUGIN_DIR/agents" ]; then
|
||||
for agent in "$PLUGIN_DIR/agents"/*.md; do
|
||||
if [ -f "$agent" ]; then
|
||||
TOTAL_AGENTS=$((TOTAL_AGENTS + 1))
|
||||
AGENT_NAME=$(basename "$agent")
|
||||
|
||||
if bash "$SCRIPT_DIR/validate-agent.sh" "$agent" > /dev/null 2>&1; then
|
||||
PASSED_AGENTS=$((PASSED_AGENTS + 1))
|
||||
echo -e " ${GREEN}✅${NC} $AGENT_NAME"
|
||||
else
|
||||
echo -e " ${RED}❌${NC} $AGENT_NAME"
|
||||
# Show errors for failed agents
|
||||
bash "$SCRIPT_DIR/validate-agent.sh" "$agent" 2>&1 | grep -E "ERROR|WARNING" || true
|
||||
fi
|
||||
fi
|
||||
done
|
||||
else
|
||||
echo -e "${YELLOW}⚠ No agents directory found${NC}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Agents: $PASSED_AGENTS/$TOTAL_AGENTS passed"
|
||||
echo ""
|
||||
|
||||
# Validate all skills
|
||||
echo "[4/5] Validating skills..."
|
||||
if [ -d "$PLUGIN_DIR/skills" ]; then
|
||||
for skill_dir in "$PLUGIN_DIR/skills"/*/; do
|
||||
if [ -d "$skill_dir" ]; then
|
||||
TOTAL_SKILLS=$((TOTAL_SKILLS + 1))
|
||||
SKILL_NAME=$(basename "$skill_dir")
|
||||
|
||||
if bash "$SCRIPT_DIR/validate-skill.sh" "$skill_dir" > /dev/null 2>&1; then
|
||||
PASSED_SKILLS=$((PASSED_SKILLS + 1))
|
||||
echo -e " ${GREEN}✅${NC} $SKILL_NAME"
|
||||
else
|
||||
echo -e " ${RED}❌${NC} $SKILL_NAME"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $TOTAL_SKILLS -eq 0 ]; then
|
||||
echo -e "${YELLOW}⚠ Skills directory empty${NC}"
|
||||
fi
|
||||
else
|
||||
echo -e "${YELLOW}⚠ No skills directory found${NC}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
if [ $TOTAL_SKILLS -gt 0 ]; then
|
||||
echo "Skills: $PASSED_SKILLS/$TOTAL_SKILLS passed"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Validate plugin completeness (templates, examples, scripts)
|
||||
echo "[5/5] Validating plugin completeness..."
|
||||
if bash "$SCRIPT_DIR/validate-plugin-completeness.sh" "$PLUGIN_DIR"; then
|
||||
echo -e "${GREEN}✅ Plugin completeness check passed${NC}"
|
||||
else
|
||||
echo -e "${RED}❌ Plugin completeness check failed${NC}"
|
||||
echo "Some skills may be missing templates, examples, or scripts."
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Summary
|
||||
echo "========================================="
|
||||
echo " Validation Summary"
|
||||
echo "========================================="
|
||||
echo ""
|
||||
echo "Commands: $PASSED_COMMANDS/$TOTAL_COMMANDS"
|
||||
echo "Agents: $PASSED_AGENTS/$TOTAL_AGENTS"
|
||||
if [ $TOTAL_SKILLS -gt 0 ]; then
|
||||
echo "Skills: $PASSED_SKILLS/$TOTAL_SKILLS"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Calculate total
|
||||
TOTAL=$((TOTAL_COMMANDS + TOTAL_AGENTS + TOTAL_SKILLS))
|
||||
PASSED=$((PASSED_COMMANDS + PASSED_AGENTS + PASSED_SKILLS))
|
||||
|
||||
if [ $PASSED -eq $TOTAL ]; then
|
||||
echo -e "${GREEN}✅ ALL VALIDATIONS PASSED ($PASSED/$TOTAL)${NC}"
|
||||
echo ""
|
||||
exit 0
|
||||
else
|
||||
FAILED=$((TOTAL - PASSED))
|
||||
echo -e "${RED}❌ VALIDATION FAILED: $FAILED failures out of $TOTAL total${NC}"
|
||||
echo ""
|
||||
echo "Fix the failed validations and run again."
|
||||
exit 1
|
||||
fi
|
||||
109
skills/build-assistant/scripts/validate-and-sync-all.sh
Executable file
109
skills/build-assistant/scripts/validate-and-sync-all.sh
Executable file
@@ -0,0 +1,109 @@
|
||||
#!/usr/bin/env bash
|
||||
# Script: validate-and-sync-all.sh
|
||||
# Purpose: Complete validation and synchronization of all plugins
|
||||
# Usage: ./validate-and-sync-all.sh
|
||||
# This is the MASTER script that ensures everything is in sync
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
echo "========================================="
|
||||
echo " Plugin System Validation & Sync"
|
||||
echo "========================================="
|
||||
echo ""
|
||||
|
||||
# Step 1: Validate all individual plugins
|
||||
echo "[STEP 1/4] Validating individual plugins..."
|
||||
echo ""
|
||||
|
||||
PLUGINS=$(find plugins -mindepth 1 -maxdepth 1 -type d -name "*" ! -name ".*" | sort)
|
||||
PLUGIN_COUNT=0
|
||||
VALID_COUNT=0
|
||||
INVALID_COUNT=0
|
||||
|
||||
for plugin in $PLUGINS; do
|
||||
((PLUGIN_COUNT++))
|
||||
PLUGIN_NAME=$(basename "$plugin")
|
||||
|
||||
# Check if has .claude-plugin directory (skip if not a valid plugin)
|
||||
if [[ ! -d "$plugin/.claude-plugin" ]]; then
|
||||
echo " ⏭️ Skipping $PLUGIN_NAME (not a Claude Code plugin)"
|
||||
continue
|
||||
fi
|
||||
|
||||
echo " Validating: $PLUGIN_NAME"
|
||||
if bash "$SCRIPT_DIR/validate-plugin.sh" "$plugin" 2>&1 | grep -q "✅"; then
|
||||
((VALID_COUNT++))
|
||||
else
|
||||
((INVALID_COUNT++))
|
||||
echo " ❌ Validation failed for $PLUGIN_NAME"
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo " Plugins found: $PLUGIN_COUNT"
|
||||
echo " Valid: $VALID_COUNT"
|
||||
echo " Invalid: $INVALID_COUNT"
|
||||
echo ""
|
||||
|
||||
# Step 2: Sync all commands to settings.local.json
|
||||
echo "[STEP 2/4] Syncing commands to settings.local.json..."
|
||||
echo ""
|
||||
|
||||
bash "$SCRIPT_DIR/sync-settings-permissions.sh"
|
||||
|
||||
echo ""
|
||||
|
||||
# Step 3: Sync all plugins to marketplace.json
|
||||
echo "[STEP 3/4] Syncing plugins to marketplace.json..."
|
||||
echo ""
|
||||
|
||||
bash "$SCRIPT_DIR/sync-marketplace.sh"
|
||||
|
||||
echo ""
|
||||
|
||||
# Step 4: Final validation
|
||||
echo "[STEP 4/4] Final validation checks..."
|
||||
echo ""
|
||||
|
||||
# Check settings.local.json is valid JSON
|
||||
if python3 -m json.tool "$HOME/.claude/settings.local.json" > /dev/null 2>&1; then
|
||||
echo " ✅ settings.local.json is valid JSON"
|
||||
else
|
||||
echo " ❌ settings.local.json is INVALID JSON"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check marketplace.json is valid JSON
|
||||
if python3 -m json.tool .claude-plugin/marketplace.json > /dev/null 2>&1; then
|
||||
echo " ✅ marketplace.json is valid JSON"
|
||||
else
|
||||
echo " ❌ marketplace.json is INVALID JSON"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Count registrations
|
||||
SETTINGS_PERMISSIONS=$(grep -c "SlashCommand" "$HOME/.claude/settings.local.json" || echo "0")
|
||||
MARKETPLACE_PLUGINS=$(python3 -c "import json; print(len(json.load(open('.claude-plugin/marketplace.json'))['plugins']))" 2>/dev/null || echo "0")
|
||||
|
||||
echo " ✅ $SETTINGS_PERMISSIONS slash commands registered in settings"
|
||||
echo " ✅ $MARKETPLACE_PLUGINS plugins registered in marketplace"
|
||||
|
||||
echo ""
|
||||
echo "========================================="
|
||||
echo " ✅ All validations passed!"
|
||||
echo "========================================="
|
||||
echo ""
|
||||
echo "Summary:"
|
||||
echo " - Plugins validated: $VALID_COUNT/$PLUGIN_COUNT"
|
||||
echo " - Commands registered: $SETTINGS_PERMISSIONS"
|
||||
echo " - Marketplace entries: $MARKETPLACE_PLUGINS"
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo " 1. Test a command: /fastmcp:new-server my-test"
|
||||
echo " 2. Commit changes: git add .claude/ .claude-plugin/"
|
||||
echo " 3. Review docs: cat SETTINGS-SYNC-GUIDE.md"
|
||||
echo ""
|
||||
|
||||
exit 0
|
||||
105
skills/build-assistant/scripts/validate-argument-hints.sh
Executable file
105
skills/build-assistant/scripts/validate-argument-hints.sh
Executable file
@@ -0,0 +1,105 @@
|
||||
#!/bin/bash
|
||||
|
||||
# validate-argument-hints.sh
|
||||
# Validates command argument-hint frontmatter for proper formatting
|
||||
|
||||
PLUGIN_DIR="${1:-.}"
|
||||
ISSUES_FOUND=0
|
||||
|
||||
echo "=== Validating Command Argument Hints ==="
|
||||
echo ""
|
||||
|
||||
# Check if directory exists
|
||||
if [ ! -d "$PLUGIN_DIR" ]; then
|
||||
echo "❌ ERROR: Directory not found: $PLUGIN_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Find all command files
|
||||
COMMAND_FILES=$(find "$PLUGIN_DIR" -type f -path "*/commands/*.md" 2>/dev/null)
|
||||
|
||||
if [ -z "$COMMAND_FILES" ]; then
|
||||
echo "⚠️ No command files found in $PLUGIN_DIR"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Scanning command files..."
|
||||
echo ""
|
||||
|
||||
while IFS= read -r file; do
|
||||
# Extract argument-hint from frontmatter
|
||||
HINT=$(sed -n '/^---$/,/^---$/p' "$file" | grep "^argument-hint:" | sed 's/argument-hint: *//')
|
||||
|
||||
if [ -z "$HINT" ]; then
|
||||
echo "⚠️ MISSING argument-hint: $file"
|
||||
((ISSUES_FOUND++))
|
||||
continue
|
||||
fi
|
||||
|
||||
# Check for old "subsystem" terminology
|
||||
if echo "$HINT" | grep -qi "subsystem"; then
|
||||
echo "❌ LEGACY TERM 'subsystem': $file"
|
||||
echo " Current: $HINT"
|
||||
echo " Should use: <plugin-name>, <spec-directory>, or specific argument"
|
||||
echo ""
|
||||
((ISSUES_FOUND++))
|
||||
fi
|
||||
|
||||
# Check for proper formatting patterns
|
||||
# Valid patterns: <required>, [optional], <arg1> <arg2>, [--flag]
|
||||
|
||||
# Check if using proper brackets
|
||||
if ! echo "$HINT" | grep -qE '(<[^>]+>|\[.*\]|--[a-z-]+)'; then
|
||||
# If no brackets at all and not empty
|
||||
if [ "$HINT" != "none" ] && [ "$HINT" != "" ]; then
|
||||
echo "⚠️ IMPROPER FORMAT (missing brackets): $file"
|
||||
echo " Current: $HINT"
|
||||
echo " Should use: <required-arg> or [optional-arg] or [--flag]"
|
||||
echo ""
|
||||
((ISSUES_FOUND++))
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check for common bad patterns
|
||||
if echo "$HINT" | grep -qE '\$[0-9]|\$ARGUMENTS|multiagent_core'; then
|
||||
echo "❌ CONTAINS VARIABLES/LEGACY: $file"
|
||||
echo " Current: $HINT"
|
||||
echo " Should be: Plain text description, not variable references"
|
||||
echo ""
|
||||
((ISSUES_FOUND++))
|
||||
fi
|
||||
|
||||
# Check for overly generic hints
|
||||
if [ "$HINT" = "<args>" ] || [ "$HINT" = "[args]" ] || [ "$HINT" = "args" ]; then
|
||||
echo "⚠️ TOO GENERIC: $file"
|
||||
echo " Current: $HINT"
|
||||
echo " Should be: Specific argument names (e.g., <spec-directory> [--type=TYPE])"
|
||||
echo ""
|
||||
((ISSUES_FOUND++))
|
||||
fi
|
||||
|
||||
done <<< "$COMMAND_FILES"
|
||||
|
||||
echo ""
|
||||
echo "=== Summary ==="
|
||||
if [ $ISSUES_FOUND -eq 0 ]; then
|
||||
echo "✅ All argument hints are properly formatted"
|
||||
exit 0
|
||||
else
|
||||
echo "❌ Found $ISSUES_FOUND issue(s) with argument hints"
|
||||
echo ""
|
||||
echo "Valid formats:"
|
||||
echo " <required-arg> - Required argument"
|
||||
echo " [optional-arg] - Optional argument"
|
||||
echo " <arg1> <arg2> - Multiple arguments"
|
||||
echo " [--flag] - Optional flag"
|
||||
echo " <spec> [--type=TYPE] - Mixed required/optional"
|
||||
echo " none - No arguments"
|
||||
echo ""
|
||||
echo "Bad patterns:"
|
||||
echo " ❌ subsystem - Use 'plugin-name' or 'spec-directory'"
|
||||
echo " ❌ \$1, \$ARGUMENTS - No variable references"
|
||||
echo " ❌ args - Too generic, be specific"
|
||||
echo " ❌ No brackets - Must use <> or [] or --"
|
||||
exit 1
|
||||
fi
|
||||
148
skills/build-assistant/scripts/validate-command.sh
Executable file
148
skills/build-assistant/scripts/validate-command.sh
Executable file
@@ -0,0 +1,148 @@
|
||||
#!/usr/bin/env bash
|
||||
# Script: validate-command.sh
|
||||
# Purpose: Validate slash command file compliance with framework standards
|
||||
# Subsystem: build-system
|
||||
# Called by: framework-slash-command after generation
|
||||
# Outputs: Validation report to stdout
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
COMMAND_FILE="${1:?Usage: $0 <command-file>}"
|
||||
EXIT_CODE=0
|
||||
|
||||
echo "[INFO] Validating command file: $COMMAND_FILE"
|
||||
echo ""
|
||||
|
||||
# Check file exists
|
||||
if [[ ! -f "$COMMAND_FILE" ]]; then
|
||||
echo "❌ ERROR: File not found: $COMMAND_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check frontmatter exists
|
||||
if ! grep -q "^---$" "$COMMAND_FILE"; then
|
||||
echo "❌ ERROR: Missing frontmatter"
|
||||
EXIT_CODE=1
|
||||
fi
|
||||
|
||||
# Check required frontmatter fields
|
||||
REQUIRED_FIELDS=("allowed-tools:" "description:")
|
||||
for field in "${REQUIRED_FIELDS[@]}"; do
|
||||
if ! grep -q "^$field" "$COMMAND_FILE"; then
|
||||
echo "❌ ERROR: Missing required field: $field"
|
||||
EXIT_CODE=1
|
||||
fi
|
||||
done
|
||||
|
||||
# Check file length (target: 120-150, allow 15% overage = 172)
|
||||
LINE_COUNT=$(wc -l < "$COMMAND_FILE")
|
||||
TARGET_MAX=150
|
||||
TOLERANCE_MAX=172 # 150 + 15% overage
|
||||
|
||||
if ((LINE_COUNT > TOLERANCE_MAX)); then
|
||||
echo "❌ ERROR: Command file is $LINE_COUNT lines (max: $TOLERANCE_MAX with 15% tolerance)"
|
||||
EXIT_CODE=1
|
||||
elif ((LINE_COUNT > TARGET_MAX)); then
|
||||
OVERAGE=$((LINE_COUNT - TARGET_MAX))
|
||||
echo "⚠️ WARNING: Command file is $LINE_COUNT lines (target: $TARGET_MAX, +$OVERAGE over)"
|
||||
elif ((LINE_COUNT < 50)); then
|
||||
echo "⚠️ WARNING: Command file is $LINE_COUNT lines (might be too short)"
|
||||
fi
|
||||
|
||||
# Check for $ARGUMENTS usage (not $1, $2, $3)
|
||||
if grep -qE '\$[0-9]' "$COMMAND_FILE"; then
|
||||
echo "❌ ERROR: Found \$1/\$2/\$3 - use \$ARGUMENTS instead"
|
||||
EXIT_CODE=1
|
||||
fi
|
||||
|
||||
if grep -q '\$ARGUMENTS' "$COMMAND_FILE" || grep -q 'DOLLAR_ARGUMENTS' "$COMMAND_FILE"; then
|
||||
echo "✅ Uses \$ARGUMENTS correctly"
|
||||
else
|
||||
echo "⚠️ WARNING: No \$ARGUMENTS found"
|
||||
fi
|
||||
|
||||
# Check for agent invocation patterns
|
||||
USES_NATURAL_LANGUAGE=false
|
||||
USES_EXPLICIT_TASK=false
|
||||
USES_PARALLEL_PATTERN=false
|
||||
|
||||
# Check for natural language agent invocation
|
||||
if grep -qiE "(Invoke the|Launch.*agent|Run.*agent)" "$COMMAND_FILE"; then
|
||||
USES_NATURAL_LANGUAGE=true
|
||||
fi
|
||||
|
||||
# Check for explicit Task tool with subagent_type
|
||||
if grep -q "subagent_type=" "$COMMAND_FILE"; then
|
||||
USES_EXPLICIT_TASK=true
|
||||
fi
|
||||
|
||||
# Check for parallel execution pattern
|
||||
if grep -qiE "(in parallel|IN PARALLEL|simultaneously|all at once)" "$COMMAND_FILE"; then
|
||||
USES_PARALLEL_PATTERN=true
|
||||
fi
|
||||
|
||||
# Validate invocation patterns
|
||||
if $USES_NATURAL_LANGUAGE || $USES_EXPLICIT_TASK; then
|
||||
if $USES_NATURAL_LANGUAGE; then
|
||||
echo "✅ Uses agent invocation (natural language)"
|
||||
fi
|
||||
if $USES_EXPLICIT_TASK; then
|
||||
echo "✅ Uses explicit Task tool with subagent_type"
|
||||
fi
|
||||
|
||||
# If parallel pattern detected, check for proper implementation
|
||||
if $USES_PARALLEL_PATTERN; then
|
||||
echo "✅ Uses parallel execution pattern"
|
||||
|
||||
# Check if it properly explains Task tool usage for parallel
|
||||
if grep -q "Task tool" "$COMMAND_FILE" && grep -q "SAME.*message\|single.*message\|ONE message" "$COMMAND_FILE"; then
|
||||
echo "✅ Properly explains parallel Task tool execution (multiple calls in ONE message)"
|
||||
elif $USES_EXPLICIT_TASK; then
|
||||
echo "✅ Uses explicit Task tool (parallel execution implied)"
|
||||
else
|
||||
echo "⚠️ WARNING: Parallel pattern found but no Task tool explanation"
|
||||
echo " Consider adding explicit Task tool syntax for clarity"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo "⚠️ WARNING: No agent invocation found - might be Pattern 1 (simple command)"
|
||||
fi
|
||||
|
||||
# Check for backticks in examples (causes parsing issues)
|
||||
if grep -q '`' "$COMMAND_FILE"; then
|
||||
BACKTICK_COUNT=$(grep -o '`' "$COMMAND_FILE" | wc -l)
|
||||
echo "⚠️ WARNING: Found $BACKTICK_COUNT backticks - may cause parsing issues"
|
||||
fi
|
||||
|
||||
# Check for code blocks (should NOT be in slash commands - use scripts instead)
|
||||
if grep -q "\`\`\`" "$COMMAND_FILE"; then
|
||||
CODE_BLOCK_COUNT=$(grep -c "\`\`\`" "$COMMAND_FILE")
|
||||
echo "❌ ERROR: Found code blocks (triple backticks) - move code to scripts"
|
||||
EXIT_CODE=1
|
||||
fi
|
||||
|
||||
# Check for proper allowed-tools format
|
||||
if grep -q "allowed-tools:.*Task(\*)" "$COMMAND_FILE"; then
|
||||
echo "✅ Proper allowed-tools format found"
|
||||
else
|
||||
echo "⚠️ WARNING: allowed-tools may not be properly formatted"
|
||||
fi
|
||||
|
||||
# Check for bash execution patterns (! prefix)
|
||||
if grep -q '!{' "$COMMAND_FILE"; then
|
||||
echo "✅ Uses bash execution pattern !{command}"
|
||||
fi
|
||||
|
||||
# Check for file loading patterns (@ prefix)
|
||||
if grep -q '@/' "$COMMAND_FILE" || grep -q '@[a-zA-Z]' "$COMMAND_FILE"; then
|
||||
echo "✅ Uses file loading pattern @filename"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
if [ $EXIT_CODE -eq 0 ]; then
|
||||
echo "✅ Command validation passed"
|
||||
else
|
||||
echo "❌ Command validation failed"
|
||||
fi
|
||||
|
||||
exit $EXIT_CODE
|
||||
108
skills/build-assistant/scripts/validate-plugin-completeness.sh
Executable file
108
skills/build-assistant/scripts/validate-plugin-completeness.sh
Executable file
@@ -0,0 +1,108 @@
|
||||
#!/bin/bash
|
||||
# Validate that all plugin skills have sufficient content in templates, scripts, and examples
|
||||
|
||||
set -e
|
||||
|
||||
# Use current directory if no argument provided (portable - works from any location)
|
||||
PLUGIN_DIR="${1:-$(pwd)}"
|
||||
MIN_EXAMPLES=3
|
||||
MIN_SCRIPTS=3
|
||||
MIN_TEMPLATES_PER_DIR=2
|
||||
|
||||
echo "🔍 Validating Plugin Completeness: $(basename $PLUGIN_DIR)"
|
||||
echo "================================================"
|
||||
|
||||
ISSUES_FOUND=0
|
||||
|
||||
# Find all skills
|
||||
for SKILL_DIR in "$PLUGIN_DIR/skills"/*; do
|
||||
if [ ! -d "$SKILL_DIR" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
SKILL_NAME=$(basename "$SKILL_DIR")
|
||||
echo ""
|
||||
echo "📦 Skill: $SKILL_NAME"
|
||||
echo "----------------------------------------"
|
||||
|
||||
# Check SKILL.md exists
|
||||
if [ ! -f "$SKILL_DIR/SKILL.md" ]; then
|
||||
echo " ❌ SKILL.md is missing"
|
||||
((ISSUES_FOUND++))
|
||||
else
|
||||
echo " ✅ SKILL.md exists"
|
||||
fi
|
||||
|
||||
# Check scripts directory
|
||||
if [ -d "$SKILL_DIR/scripts" ]; then
|
||||
SCRIPT_COUNT=$(find "$SKILL_DIR/scripts" -type f -name "*.sh" | wc -l)
|
||||
echo " 📜 Scripts: $SCRIPT_COUNT files"
|
||||
if [ $SCRIPT_COUNT -lt $MIN_SCRIPTS ]; then
|
||||
echo " ⚠️ Warning: Less than $MIN_SCRIPTS scripts"
|
||||
((ISSUES_FOUND++))
|
||||
fi
|
||||
else
|
||||
echo " ❌ scripts/ directory missing"
|
||||
((ISSUES_FOUND++))
|
||||
fi
|
||||
|
||||
# Check templates directory
|
||||
if [ -d "$SKILL_DIR/templates" ]; then
|
||||
echo " 📄 Templates:"
|
||||
|
||||
# Find all template subdirectories
|
||||
EMPTY_DIRS=0
|
||||
for TEMPLATE_DIR in "$SKILL_DIR/templates"/*; do
|
||||
if [ -d "$TEMPLATE_DIR" ]; then
|
||||
DIR_NAME=$(basename "$TEMPLATE_DIR")
|
||||
FILE_COUNT=$(find "$TEMPLATE_DIR" -type f | wc -l)
|
||||
|
||||
if [ $FILE_COUNT -eq 0 ]; then
|
||||
echo " ❌ $DIR_NAME/ is EMPTY"
|
||||
((EMPTY_DIRS++))
|
||||
((ISSUES_FOUND++))
|
||||
elif [ $FILE_COUNT -lt $MIN_TEMPLATES_PER_DIR ]; then
|
||||
echo " ⚠️ $DIR_NAME/ has only $FILE_COUNT file(s)"
|
||||
find "$TEMPLATE_DIR" -type f -exec basename {} \; | sed 's/^/ - /'
|
||||
else
|
||||
echo " ✅ $DIR_NAME/ has $FILE_COUNT files"
|
||||
find "$TEMPLATE_DIR" -type f -exec basename {} \; | sed 's/^/ - /'
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $EMPTY_DIRS -gt 0 ]; then
|
||||
echo " ⚠️ Total empty template directories: $EMPTY_DIRS"
|
||||
fi
|
||||
else
|
||||
echo " ❌ templates/ directory missing"
|
||||
((ISSUES_FOUND++))
|
||||
fi
|
||||
|
||||
# Check examples directory
|
||||
if [ -d "$SKILL_DIR/examples" ]; then
|
||||
EXAMPLE_COUNT=$(find "$SKILL_DIR/examples" -type f -name "*.md" | wc -l)
|
||||
echo " 📚 Examples: $EXAMPLE_COUNT files"
|
||||
|
||||
if [ $EXAMPLE_COUNT -lt $MIN_EXAMPLES ]; then
|
||||
echo " ❌ Less than $MIN_EXAMPLES examples"
|
||||
((ISSUES_FOUND++))
|
||||
fi
|
||||
|
||||
# List examples
|
||||
find "$SKILL_DIR/examples" -type f -name "*.md" -exec basename {} \; | sed 's/^/ - /'
|
||||
else
|
||||
echo " ❌ examples/ directory missing"
|
||||
((ISSUES_FOUND++))
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "================================================"
|
||||
if [ $ISSUES_FOUND -eq 0 ]; then
|
||||
echo "✅ All validations passed! Plugin is complete."
|
||||
exit 0
|
||||
else
|
||||
echo "❌ Found $ISSUES_FOUND issue(s) that need to be addressed."
|
||||
exit 1
|
||||
fi
|
||||
136
skills/build-assistant/scripts/validate-plugin-manifest.sh
Executable file
136
skills/build-assistant/scripts/validate-plugin-manifest.sh
Executable file
@@ -0,0 +1,136 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Validate and fix plugin.json manifest
|
||||
# Usage: ./validate-plugin-manifest.sh <plugin-name> [--fix]
|
||||
|
||||
set -e
|
||||
|
||||
PLUGIN_NAME=$1
|
||||
FIX_MODE=false
|
||||
|
||||
if [ "$2" = "--fix" ]; then
|
||||
FIX_MODE=true
|
||||
fi
|
||||
|
||||
if [ -z "$PLUGIN_NAME" ]; then
|
||||
echo "Usage: $0 <plugin-name> [--fix]"
|
||||
echo "Example: $0 elevenlabs --fix"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
MANIFEST_FILE="plugins/$PLUGIN_NAME/.claude-plugin/plugin.json"
|
||||
|
||||
if [ ! -f "$MANIFEST_FILE" ]; then
|
||||
echo "ERROR: Manifest file not found: $MANIFEST_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "[INFO] Validating plugin manifest: $MANIFEST_FILE"
|
||||
|
||||
# Test 1: Valid JSON syntax
|
||||
if ! python3 -m json.tool "$MANIFEST_FILE" > /dev/null 2>&1; then
|
||||
echo "❌ FAIL: Invalid JSON syntax"
|
||||
exit 1
|
||||
fi
|
||||
echo "✅ PASS: Valid JSON syntax"
|
||||
|
||||
# Test 2: Required fields
|
||||
REQUIRED_FIELDS=("name" "version" "description" "author")
|
||||
MISSING_FIELDS=()
|
||||
|
||||
for field in "${REQUIRED_FIELDS[@]}"; do
|
||||
if ! grep -q "\"$field\"" "$MANIFEST_FILE"; then
|
||||
MISSING_FIELDS+=("$field")
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ${#MISSING_FIELDS[@]} -gt 0 ]; then
|
||||
echo "❌ FAIL: Missing required fields: ${MISSING_FIELDS[*]}"
|
||||
exit 1
|
||||
fi
|
||||
echo "✅ PASS: All required fields present"
|
||||
|
||||
# Test 3: Repository field format (should be string, not object)
|
||||
if grep -q '"repository".*{' "$MANIFEST_FILE"; then
|
||||
echo "❌ FAIL: repository field is an object (should be string)"
|
||||
|
||||
if [ "$FIX_MODE" = true ]; then
|
||||
echo "[INFO] Fixing repository field..."
|
||||
|
||||
# Extract URL from repository object
|
||||
REPO_URL=$(grep -A2 '"repository"' "$MANIFEST_FILE" | grep '"url"' | sed 's/.*"url": "\(.*\)".*/\1/')
|
||||
|
||||
if [ -n "$REPO_URL" ]; then
|
||||
# Create temp file with fixed repository
|
||||
python3 << EOF
|
||||
import json
|
||||
with open("$MANIFEST_FILE", "r") as f:
|
||||
data = json.load(f)
|
||||
if isinstance(data.get("repository"), dict):
|
||||
data["repository"] = data["repository"].get("url", "")
|
||||
with open("$MANIFEST_FILE", "w") as f:
|
||||
json.dump(data, f, indent=2)
|
||||
f.write("\n")
|
||||
EOF
|
||||
echo "✅ FIXED: repository changed to string: $REPO_URL"
|
||||
else
|
||||
echo "❌ Could not extract repository URL"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "[HINT] Run with --fix to automatically correct this"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "✅ PASS: repository field is correct format"
|
||||
fi
|
||||
|
||||
# Test 4: Category field (should NOT exist)
|
||||
if grep -q '"category"' "$MANIFEST_FILE"; then
|
||||
echo "❌ FAIL: 'category' field found (not a valid field)"
|
||||
|
||||
if [ "$FIX_MODE" = true ]; then
|
||||
echo "[INFO] Removing category field..."
|
||||
python3 << EOF
|
||||
import json
|
||||
with open("$MANIFEST_FILE", "r") as f:
|
||||
data = json.load(f)
|
||||
if "category" in data:
|
||||
del data["category"]
|
||||
with open("$MANIFEST_FILE", "w") as f:
|
||||
json.dump(data, f, indent=2)
|
||||
f.write("\n")
|
||||
EOF
|
||||
echo "✅ FIXED: category field removed"
|
||||
else
|
||||
echo "[HINT] Run with --fix to automatically correct this"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "✅ PASS: No invalid 'category' field"
|
||||
fi
|
||||
|
||||
# Test 5: Author field structure
|
||||
if ! grep -A1 '"author"' "$MANIFEST_FILE" | grep -q '"name"'; then
|
||||
echo "❌ FAIL: author.name field missing"
|
||||
exit 1
|
||||
fi
|
||||
echo "✅ PASS: author field properly structured"
|
||||
|
||||
# Final validation
|
||||
if python3 -m json.tool "$MANIFEST_FILE" > /dev/null 2>&1; then
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "✅ MANIFEST VALIDATION PASSED"
|
||||
echo "=========================================="
|
||||
echo "Plugin: $PLUGIN_NAME"
|
||||
echo "File: $MANIFEST_FILE"
|
||||
echo ""
|
||||
exit 0
|
||||
else
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "❌ MANIFEST VALIDATION FAILED"
|
||||
echo "=========================================="
|
||||
exit 1
|
||||
fi
|
||||
137
skills/build-assistant/scripts/validate-plugin.sh
Executable file
137
skills/build-assistant/scripts/validate-plugin.sh
Executable file
@@ -0,0 +1,137 @@
|
||||
#!/usr/bin/env bash
|
||||
# Script: validate-plugin.sh
|
||||
# Purpose: Validate plugin directory compliance with Claude Code standards
|
||||
# Subsystem: build-system
|
||||
# Called by: /build:plugin command after generation
|
||||
# Outputs: Validation report to stdout
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
PLUGIN_DIR="${1:?Usage: $0 <plugin-directory>}"
|
||||
SETTINGS_FILE="$HOME/.claude/settings.local.json"
|
||||
|
||||
echo "[INFO] Validating plugin directory: $PLUGIN_DIR"
|
||||
|
||||
# Check directory exists
|
||||
if [[ ! -d "$PLUGIN_DIR" ]]; then
|
||||
echo "❌ ERROR: Directory not found: $PLUGIN_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check .claude-plugin directory exists
|
||||
if [[ ! -d "$PLUGIN_DIR/.claude-plugin" ]]; then
|
||||
echo "❌ ERROR: Missing .claude-plugin directory"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check plugin.json exists
|
||||
if [[ ! -f "$PLUGIN_DIR/.claude-plugin/plugin.json" ]]; then
|
||||
echo "❌ ERROR: Missing plugin.json manifest"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Validate JSON syntax
|
||||
if ! python3 -m json.tool "$PLUGIN_DIR/.claude-plugin/plugin.json" > /dev/null 2>&1; then
|
||||
echo "❌ ERROR: Invalid JSON in plugin.json"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Validate plugin.json schema (only allowed fields)
|
||||
ALLOWED_FIELDS=("name" "version" "description" "author" "homepage" "repository" "license" "keywords" "category" "tags" "strict" "commands" "agents" "hooks" "mcpServers")
|
||||
INVALID_FIELDS=$(python3 -c "
|
||||
import json, sys
|
||||
with open('$PLUGIN_DIR/.claude-plugin/plugin.json') as f:
|
||||
data = json.load(f)
|
||||
allowed = set($( printf "'%s', " "${ALLOWED_FIELDS[@]}" | sed 's/, $//' ))
|
||||
invalid = [k for k in data.keys() if k not in allowed]
|
||||
if invalid:
|
||||
print(' '.join(invalid))
|
||||
" 2>/dev/null)
|
||||
|
||||
if [[ -n "$INVALID_FIELDS" ]]; then
|
||||
echo "❌ ERROR: Invalid fields in plugin.json: $INVALID_FIELDS"
|
||||
echo "[INFO] Allowed fields: ${ALLOWED_FIELDS[*]}"
|
||||
echo "[INFO] Move custom metadata to keywords array for discoverability"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check required fields in plugin.json
|
||||
REQUIRED_FIELDS=("name" "version" "description")
|
||||
for field in "${REQUIRED_FIELDS[@]}"; do
|
||||
if ! grep -q "\"$field\":" "$PLUGIN_DIR/.claude-plugin/plugin.json"; then
|
||||
echo "❌ ERROR: Missing required field: $field"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# Validate author field structure if present
|
||||
if grep -q "\"author\":" "$PLUGIN_DIR/.claude-plugin/plugin.json"; then
|
||||
AUTHOR_VALID=$(python3 -c "
|
||||
import json
|
||||
with open('$PLUGIN_DIR/.claude-plugin/plugin.json') as f:
|
||||
data = json.load(f)
|
||||
author = data.get('author')
|
||||
if isinstance(author, dict):
|
||||
if 'name' in author:
|
||||
print('valid')
|
||||
else:
|
||||
print('missing_name')
|
||||
elif isinstance(author, str):
|
||||
print('string')
|
||||
" 2>/dev/null)
|
||||
|
||||
if [[ "$AUTHOR_VALID" == "string" ]]; then
|
||||
echo "❌ ERROR: author field must be an object with 'name' and 'email' fields, not a string"
|
||||
exit 1
|
||||
elif [[ "$AUTHOR_VALID" == "missing_name" ]]; then
|
||||
echo "❌ ERROR: author object must include 'name' field"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check component directories are at root (not inside .claude-plugin)
|
||||
if [[ -d "$PLUGIN_DIR/.claude-plugin/commands" ]] || \
|
||||
[[ -d "$PLUGIN_DIR/.claude-plugin/skills" ]] || \
|
||||
[[ -d "$PLUGIN_DIR/.claude-plugin/hooks" ]]; then
|
||||
echo "❌ ERROR: Component directories must be at plugin root, not inside .claude-plugin/"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# NEW: Check if plugin commands are registered in settings.local.json
|
||||
PLUGIN_NAME=$(basename "$PLUGIN_DIR")
|
||||
|
||||
if [[ -f "$SETTINGS_FILE" ]]; then
|
||||
if [[ -d "$PLUGIN_DIR/commands" ]]; then
|
||||
# Check for wildcard permission
|
||||
if ! grep -q "SlashCommand(/$PLUGIN_NAME:\\*)" "$SETTINGS_FILE"; then
|
||||
echo "⚠️ WARNING: Plugin commands not registered in settings.local.json"
|
||||
echo "[INFO] Run: bash plugins/domain-plugin-builder/skills/build-assistant/scripts/sync-settings-permissions.sh"
|
||||
else
|
||||
echo "✅ Plugin commands registered in settings.local.json"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo "⚠️ WARNING: No settings.local.json found"
|
||||
echo "[INFO] Run: bash plugins/domain-plugin-builder/skills/build-assistant/scripts/sync-settings-permissions.sh"
|
||||
fi
|
||||
|
||||
echo "✅ Plugin validation passed"
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "📦 NEXT STEP: Install Plugin to Test"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
echo "To make the plugin available for use:"
|
||||
echo ""
|
||||
echo " 1. Update marketplace in ~/.claude:"
|
||||
echo " cp -r $PLUGIN_DIR ~/.claude/plugins/marketplaces/ai-dev-marketplace/plugins/"
|
||||
echo " cp .claude-plugin/marketplace.json ~/.claude/plugins/marketplaces/ai-dev-marketplace/.claude-plugin/"
|
||||
echo ""
|
||||
echo " 2. Install the plugin:"
|
||||
echo " /plugin install $PLUGIN_NAME@ai-dev-marketplace"
|
||||
echo ""
|
||||
echo " 3. Verify installation:"
|
||||
echo " /$PLUGIN_NAME:init (or any command from the plugin)"
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
exit 0
|
||||
206
skills/build-assistant/scripts/validate-skill.sh
Executable file
206
skills/build-assistant/scripts/validate-skill.sh
Executable file
@@ -0,0 +1,206 @@
|
||||
#!/usr/bin/env bash
|
||||
# Script: validate-skill.sh
|
||||
# Purpose: Validate Agent Skill directory compliance with Claude Code standards
|
||||
# Subsystem: build-system
|
||||
# Called by: /build:skill command after generation
|
||||
# Outputs: Validation report to stdout
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SKILL_DIR="${1:?Usage: $0 <skill-directory>}"
|
||||
EXIT_CODE=0
|
||||
|
||||
echo "[INFO] Validating skill directory: $SKILL_DIR"
|
||||
echo ""
|
||||
|
||||
# Check directory exists
|
||||
if [[ ! -d "$SKILL_DIR" ]]; then
|
||||
echo "❌ ERROR: Directory not found: $SKILL_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check SKILL.md exists
|
||||
if [[ ! -f "$SKILL_DIR/SKILL.md" ]]; then
|
||||
echo "❌ ERROR: Missing SKILL.md file"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check frontmatter exists and starts at line 1
|
||||
FIRST_LINE=$(head -n 1 "$SKILL_DIR/SKILL.md")
|
||||
if [[ "$FIRST_LINE" != "---" ]]; then
|
||||
echo "❌ ERROR: YAML frontmatter MUST start at line 1"
|
||||
echo " Found: $FIRST_LINE"
|
||||
echo " Expected: ---"
|
||||
echo " CRITICAL: Nothing can come before the opening --- (no titles, no comments, no blank lines)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! grep -q "^---$" "$SKILL_DIR/SKILL.md"; then
|
||||
echo "❌ ERROR: Missing closing frontmatter delimiter in SKILL.md"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check required frontmatter fields
|
||||
REQUIRED_FIELDS=("name:" "description:")
|
||||
for field in "${REQUIRED_FIELDS[@]}"; do
|
||||
if ! grep -q "^$field" "$SKILL_DIR/SKILL.md"; then
|
||||
echo "❌ ERROR: Missing required field: $field"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# Check description includes trigger keywords
|
||||
if ! grep -q "Use when" "$SKILL_DIR/SKILL.md"; then
|
||||
echo "⚠️ WARNING: Description should include 'Use when' trigger context"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "[INFO] Checking minimum requirements (scripts, templates, examples)..."
|
||||
echo ""
|
||||
|
||||
# Minimum requirements per skill
|
||||
MIN_SCRIPTS=3
|
||||
MIN_TEMPLATES=4
|
||||
MIN_EXAMPLES=3
|
||||
|
||||
# Count scripts
|
||||
if [[ -d "$SKILL_DIR/scripts" ]]; then
|
||||
SCRIPT_COUNT=$(find "$SKILL_DIR/scripts" -type f -name "*.sh" | wc -l)
|
||||
echo "📂 Scripts found: $SCRIPT_COUNT"
|
||||
|
||||
if ((SCRIPT_COUNT >= MIN_SCRIPTS)); then
|
||||
echo " ✅ Meets minimum requirement (>= $MIN_SCRIPTS scripts)"
|
||||
else
|
||||
echo " ❌ ERROR: Below minimum requirement (need $MIN_SCRIPTS, found $SCRIPT_COUNT)"
|
||||
echo " Each skill should have 3-5 helper scripts (setup, validate, generate, etc.)"
|
||||
EXIT_CODE=1
|
||||
fi
|
||||
|
||||
# List scripts
|
||||
if ((SCRIPT_COUNT > 0)); then
|
||||
echo " Scripts:"
|
||||
find "$SKILL_DIR/scripts" -type f -name "*.sh" -exec basename {} \; | sed 's/^/ - /'
|
||||
fi
|
||||
else
|
||||
echo "📂 Scripts: directory not found"
|
||||
echo " ❌ ERROR: Missing scripts/ directory"
|
||||
EXIT_CODE=1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Count templates
|
||||
if [[ -d "$SKILL_DIR/templates" ]]; then
|
||||
TEMPLATE_COUNT=$(find "$SKILL_DIR/templates" -type f | wc -l)
|
||||
echo "📂 Templates found: $TEMPLATE_COUNT"
|
||||
|
||||
if ((TEMPLATE_COUNT >= MIN_TEMPLATES)); then
|
||||
echo " ✅ Meets minimum requirement (>= $MIN_TEMPLATES templates)"
|
||||
else
|
||||
echo " ❌ ERROR: Below minimum requirement (need $MIN_TEMPLATES, found $TEMPLATE_COUNT)"
|
||||
echo " Each skill should have 4-6 templates (basic, advanced, TS, Python, etc.)"
|
||||
EXIT_CODE=1
|
||||
fi
|
||||
|
||||
# Check for TypeScript and Python coverage
|
||||
TS_COUNT=$(find "$SKILL_DIR/templates" -type f -name "*.ts" -o -name "*.tsx" | wc -l)
|
||||
PY_COUNT=$(find "$SKILL_DIR/templates" -type f -name "*.py" | wc -l)
|
||||
|
||||
if ((TS_COUNT > 0)) && ((PY_COUNT > 0)); then
|
||||
echo " ✅ Has both TypeScript ($TS_COUNT) and Python ($PY_COUNT) templates"
|
||||
elif ((TS_COUNT > 0)); then
|
||||
echo " ⚠️ WARNING: Has TypeScript templates but no Python templates"
|
||||
elif ((PY_COUNT > 0)); then
|
||||
echo " ⚠️ WARNING: Has Python templates but no TypeScript templates"
|
||||
fi
|
||||
|
||||
# List templates by type
|
||||
if ((TEMPLATE_COUNT > 0)); then
|
||||
echo " Templates:"
|
||||
find "$SKILL_DIR/templates" -type f | sed "s|$SKILL_DIR/templates/||" | sed 's/^/ - /'
|
||||
fi
|
||||
else
|
||||
echo "📂 Templates: directory not found"
|
||||
echo " ❌ ERROR: Missing templates/ directory"
|
||||
EXIT_CODE=1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Count examples
|
||||
if [[ -d "$SKILL_DIR/examples" ]]; then
|
||||
EXAMPLE_COUNT=$(find "$SKILL_DIR/examples" -type f -name "*.md" | wc -l)
|
||||
echo "📂 Examples found: $EXAMPLE_COUNT"
|
||||
|
||||
if ((EXAMPLE_COUNT >= MIN_EXAMPLES)); then
|
||||
echo " ✅ Meets minimum requirement (>= $MIN_EXAMPLES examples)"
|
||||
else
|
||||
echo " ❌ ERROR: Below minimum requirement (need $MIN_EXAMPLES, found $EXAMPLE_COUNT)"
|
||||
echo " Each skill should have 3-5 examples (basic, advanced, patterns, edge-cases, integration)"
|
||||
EXIT_CODE=1
|
||||
fi
|
||||
|
||||
# List examples
|
||||
if ((EXAMPLE_COUNT > 0)); then
|
||||
echo " Examples:"
|
||||
find "$SKILL_DIR/examples" -type f -name "*.md" -exec basename {} \; | sed 's/^/ - /'
|
||||
fi
|
||||
else
|
||||
echo "📂 Examples: directory not found"
|
||||
echo " ❌ ERROR: Missing examples/ directory"
|
||||
EXIT_CODE=1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Cross-reference: Check that SKILL.md references match actual files
|
||||
echo "[INFO] Checking SKILL.md references match actual files..."
|
||||
echo ""
|
||||
|
||||
# Count references in SKILL.md
|
||||
SCRIPT_REFS=$(grep -oE 'scripts/[a-zA-Z0-9_-]+\.sh' "$SKILL_DIR/SKILL.md" 2>/dev/null | sort -u | wc -l || echo 0)
|
||||
TEMPLATE_REFS=$(grep -oE 'templates/[a-zA-Z0-9_/.-]+\.(ts|py|tsx|js)' "$SKILL_DIR/SKILL.md" 2>/dev/null | sort -u | wc -l || echo 0)
|
||||
EXAMPLE_REFS=$(grep -oE 'examples/[a-zA-Z0-9_-]+\.md' "$SKILL_DIR/SKILL.md" 2>/dev/null | sort -u | wc -l || echo 0)
|
||||
|
||||
echo "📝 SKILL.md references:"
|
||||
echo " Scripts referenced: $SCRIPT_REFS"
|
||||
echo " Templates referenced: $TEMPLATE_REFS"
|
||||
echo " Examples referenced: $EXAMPLE_REFS"
|
||||
|
||||
echo ""
|
||||
|
||||
# Compare references to actual files
|
||||
if [[ -d "$SKILL_DIR/scripts" ]]; then
|
||||
if ((SCRIPT_REFS == SCRIPT_COUNT)); then
|
||||
echo " ✅ Script references match actual files ($SCRIPT_REFS = $SCRIPT_COUNT)"
|
||||
else
|
||||
echo " ⚠️ WARNING: Script count mismatch (referenced: $SCRIPT_REFS, actual: $SCRIPT_COUNT)"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -d "$SKILL_DIR/templates" ]]; then
|
||||
if ((TEMPLATE_REFS == TEMPLATE_COUNT)); then
|
||||
echo " ✅ Template references match actual files ($TEMPLATE_REFS = $TEMPLATE_COUNT)"
|
||||
else
|
||||
echo " ⚠️ WARNING: Template count mismatch (referenced: $TEMPLATE_REFS, actual: $TEMPLATE_COUNT)"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -d "$SKILL_DIR/examples" ]]; then
|
||||
if ((EXAMPLE_REFS == EXAMPLE_COUNT)); then
|
||||
echo " ✅ Example references match actual files ($EXAMPLE_REFS = $EXAMPLE_COUNT)"
|
||||
else
|
||||
echo " ⚠️ WARNING: Example count mismatch (referenced: $EXAMPLE_REFS, actual: $EXAMPLE_COUNT)"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Final result
|
||||
if [ $EXIT_CODE -eq 0 ]; then
|
||||
echo "✅ Skill validation passed - all minimum requirements met!"
|
||||
else
|
||||
echo "❌ Skill validation failed - does not meet minimum requirements"
|
||||
fi
|
||||
|
||||
exit $EXIT_CODE
|
||||
@@ -0,0 +1,213 @@
|
||||
---
|
||||
name: {{AGENT_NAME}}
|
||||
description: {{AGENT_DESCRIPTION}}
|
||||
model: inherit
|
||||
color: yellow
|
||||
---
|
||||
|
||||
You are a {{DOMAIN}} specialist. Your role is to {{PRIMARY_ROLE}}.
|
||||
|
||||
## Available Tools & Resources
|
||||
|
||||
**MCP Servers Available:**
|
||||
- `mcp__{{MCP_SERVER_1}}` - {{MCP_SERVER_1_PURPOSE}}
|
||||
- `mcp__{{MCP_SERVER_2}}` - {{MCP_SERVER_2_PURPOSE}}
|
||||
- Use these MCP servers when you need {{WHEN_TO_USE_MCP}}
|
||||
|
||||
**Skills Available:**
|
||||
- `!{skill {{PLUGIN_NAME}}:{{SKILL_1}}}` - {{SKILL_1_PURPOSE}}
|
||||
- `!{skill {{PLUGIN_NAME}}:{{SKILL_2}}}` - {{SKILL_2_PURPOSE}}
|
||||
- Invoke skills when you need {{WHEN_TO_USE_SKILLS}}
|
||||
|
||||
**Slash Commands Available:**
|
||||
- `/{{PLUGIN_NAME}}:{{COMMAND_1}}` - {{COMMAND_1_PURPOSE}}
|
||||
- `/{{PLUGIN_NAME}}:{{COMMAND_2}}` - {{COMMAND_2_PURPOSE}}
|
||||
- Use these commands when you need {{WHEN_TO_USE_COMMANDS}}
|
||||
|
||||
You are a {{DOMAIN}} specialist. Your role is to {{PRIMARY_ROLE}}.
|
||||
|
||||
## Core Competencies
|
||||
|
||||
{{COMPETENCY_1}}
|
||||
- {{COMPETENCY_1_DETAIL_1}}
|
||||
- {{COMPETENCY_1_DETAIL_2}}
|
||||
- {{COMPETENCY_1_DETAIL_3}}
|
||||
|
||||
{{COMPETENCY_2}}
|
||||
- {{COMPETENCY_2_DETAIL_1}}
|
||||
- {{COMPETENCY_2_DETAIL_2}}
|
||||
- {{COMPETENCY_2_DETAIL_3}}
|
||||
|
||||
{{COMPETENCY_3}}
|
||||
- {{COMPETENCY_3_DETAIL_1}}
|
||||
- {{COMPETENCY_3_DETAIL_2}}
|
||||
- {{COMPETENCY_3_DETAIL_3}}
|
||||
|
||||
## Project Approach
|
||||
|
||||
### 1. Discovery & Core Documentation
|
||||
- Fetch core documentation:
|
||||
- WebFetch: {{CORE_DOC_URL_1}}
|
||||
- WebFetch: {{CORE_DOC_URL_2}}
|
||||
- WebFetch: {{CORE_DOC_URL_3}} ...
|
||||
- Read package.json to understand framework and dependencies
|
||||
- Check existing setup (providers, configuration)
|
||||
- Identify requested features from user input
|
||||
- Ask targeted questions to fill knowledge gaps:
|
||||
- "{{DISCOVERY_QUESTION_1}}"
|
||||
- "{{DISCOVERY_QUESTION_2}}"
|
||||
- "{{DISCOVERY_QUESTION_3}}"
|
||||
|
||||
**Tools to use in this phase:**
|
||||
|
||||
First, detect the project structure:
|
||||
```
|
||||
Skill({{PLUGIN_NAME}}:{{SKILL_1}})
|
||||
```
|
||||
|
||||
Then validate the configuration:
|
||||
```
|
||||
SlashCommand(/{{PLUGIN_NAME}}:{{COMMAND_1}} {{ARGUMENTS}})
|
||||
```
|
||||
|
||||
Use MCP servers for external integrations:
|
||||
- `mcp__{{MCP_SERVER_1}}` - {{MCP_SERVER_1_ACTION}}
|
||||
|
||||
### 2. Analysis & Feature-Specific Documentation
|
||||
- Assess current project structure
|
||||
- Determine technology stack requirements
|
||||
- Based on requested features, fetch relevant docs:
|
||||
- If {{FEATURE_1}} requested: WebFetch {{FEATURE_1_DOC_URL}}
|
||||
- If {{FEATURE_2}} requested: WebFetch {{FEATURE_2_DOC_URL}}
|
||||
- If {{FEATURE_3}} requested: WebFetch {{FEATURE_3_DOC_URL}}
|
||||
- Determine dependencies and versions needed
|
||||
|
||||
**Tools to use in this phase:**
|
||||
|
||||
Analyze the codebase:
|
||||
```
|
||||
Skill({{PLUGIN_NAME}}:{{SKILL_2}})
|
||||
```
|
||||
|
||||
Run validation checks:
|
||||
```
|
||||
SlashCommand(/{{PLUGIN_NAME}}:{{COMMAND_2}} {{PROJECT_PATH}})
|
||||
```
|
||||
|
||||
Access external services:
|
||||
- `mcp__{{MCP_SERVER_2}}` - {{MCP_SERVER_2_ACTION}}
|
||||
|
||||
### 3. Planning & Advanced Documentation
|
||||
- Design component/module structure based on fetched docs
|
||||
- Plan configuration schema (if needed)
|
||||
- Map out data flow and integration points
|
||||
- Identify dependencies to install
|
||||
- For advanced features, fetch additional docs:
|
||||
- If {{ADVANCED_FEATURE_1}} needed: WebFetch {{ADVANCED_FEATURE_1_DOC_URL}}
|
||||
- If {{ADVANCED_FEATURE_2}} needed: WebFetch {{ADVANCED_FEATURE_2_DOC_URL}}
|
||||
|
||||
**Tools to use in this phase:**
|
||||
|
||||
Load planning templates:
|
||||
```
|
||||
Skill({{PLUGIN_NAME}}:{{SKILL_1}})
|
||||
```
|
||||
|
||||
Verify dependencies:
|
||||
- `mcp__{{MCP_SERVER_1}}` - {{MCP_SERVER_1_PLANNING_ACTION}}
|
||||
|
||||
### 4. Implementation & Reference Documentation
|
||||
- Install required packages
|
||||
- Fetch detailed implementation docs as needed:
|
||||
- For {{IMPLEMENTATION_AREA_1}}: WebFetch {{IMPLEMENTATION_DOC_URL_1}}
|
||||
- For {{IMPLEMENTATION_AREA_2}}: WebFetch {{IMPLEMENTATION_DOC_URL_2}}
|
||||
- Create/update files following fetched examples
|
||||
- Build components/modules following documentation patterns
|
||||
- Implement configuration and setup
|
||||
- Add error handling and validation
|
||||
- Set up types/interfaces (TypeScript) or schemas (Python)
|
||||
|
||||
**Tools to use in this phase:**
|
||||
|
||||
Generate implementation code:
|
||||
```
|
||||
Skill({{PLUGIN_NAME}}:{{SKILL_2}})
|
||||
```
|
||||
|
||||
Deploy or configure:
|
||||
```
|
||||
SlashCommand(/{{PLUGIN_NAME}}:{{COMMAND_1}} {{DEPLOYMENT_TARGET}})
|
||||
```
|
||||
|
||||
Manage external resources:
|
||||
- `mcp__{{MCP_SERVER_2}}` - {{MCP_SERVER_2_IMPLEMENTATION_ACTION}}
|
||||
|
||||
### 5. Verification
|
||||
- Run compilation/type checking (TypeScript: `npx tsc --noEmit`, Python: `mypy` or similar)
|
||||
- Test functionality with sample inputs
|
||||
- Verify configuration is correct
|
||||
- Check error handling paths
|
||||
- Validate against documentation patterns
|
||||
- Ensure code matches best practices from docs
|
||||
|
||||
**Tools to use in this phase:**
|
||||
|
||||
Run comprehensive validation:
|
||||
```
|
||||
SlashCommand(/{{PLUGIN_NAME}}:{{COMMAND_2}} {{VALIDATION_TARGET}})
|
||||
```
|
||||
|
||||
Check deployment health:
|
||||
- `mcp__{{MCP_SERVER_1}}` - {{MCP_SERVER_1_VERIFICATION_ACTION}}
|
||||
|
||||
## Decision-Making Framework
|
||||
|
||||
### {{DECISION_CATEGORY_1}}
|
||||
- **{{OPTION_1_1}}**: {{OPTION_1_1_DESCRIPTION}}
|
||||
- **{{OPTION_1_2}}**: {{OPTION_1_2_DESCRIPTION}}
|
||||
- **{{OPTION_1_3}}**: {{OPTION_1_3_DESCRIPTION}}
|
||||
|
||||
### {{DECISION_CATEGORY_2}}
|
||||
- **{{OPTION_2_1}}**: {{OPTION_2_1_DESCRIPTION}}
|
||||
- **{{OPTION_2_2}}**: {{OPTION_2_2_DESCRIPTION}}
|
||||
- **{{OPTION_2_3}}**: {{OPTION_2_3_DESCRIPTION}}
|
||||
|
||||
## Communication Style
|
||||
|
||||
- **Be proactive**: Suggest best practices and improvements based on fetched documentation
|
||||
- **Be transparent**: Explain what URLs you're fetching and why, show planned structure before implementing
|
||||
- **Be thorough**: Implement all requested features completely, don't skip error handling or edge cases
|
||||
- **Be realistic**: Warn about limitations, performance considerations, and potential issues
|
||||
- **Seek clarification**: Ask about preferences and requirements before implementing
|
||||
|
||||
## Output Standards
|
||||
|
||||
- All code follows patterns from the fetched {{DOMAIN}} documentation
|
||||
- TypeScript types are properly defined (if applicable)
|
||||
- Python type hints included (if applicable)
|
||||
- Error handling covers common failure modes
|
||||
- Configuration is validated
|
||||
- Code is production-ready with proper security considerations
|
||||
- Files are organized following framework conventions
|
||||
|
||||
## Self-Verification Checklist
|
||||
|
||||
Before considering a task complete, verify:
|
||||
- ✅ Fetched relevant documentation URLs using WebFetch
|
||||
- ✅ Implementation matches patterns from fetched docs
|
||||
- ✅ Compilation/type checking passes (TypeScript/Python)
|
||||
- ✅ Functionality works correctly
|
||||
- ✅ Error handling covers edge cases
|
||||
- ✅ Code follows security best practices
|
||||
- ✅ Files are organized properly
|
||||
- ✅ Dependencies are installed in package.json/requirements.txt
|
||||
- ✅ Environment variables documented in .env.example (if needed)
|
||||
|
||||
## Collaboration in Multi-Agent Systems
|
||||
|
||||
When working with other agents:
|
||||
- **{{RELATED_AGENT_1}}** for {{RELATED_AGENT_1_PURPOSE}}
|
||||
- **{{RELATED_AGENT_2}}** for {{RELATED_AGENT_2_PURPOSE}}
|
||||
- **general-purpose** for non-{{DOMAIN}}-specific tasks
|
||||
|
||||
Your goal is to implement production-ready {{DOMAIN}} features while following official documentation patterns and maintaining best practices.
|
||||
@@ -0,0 +1,452 @@
|
||||
# Master Command Pattern Template
|
||||
|
||||
This template shows how to structure slash commands using the Goal → Actions → Phase pattern. Choose the appropriate pattern based on your command's complexity.
|
||||
|
||||
---
|
||||
|
||||
## Pattern Selection Guide
|
||||
|
||||
**Pattern 1: Simple (No Agents)**
|
||||
- Use for: Mechanical tasks, script execution, file operations
|
||||
- Examples: version bumping, config updates, git operations
|
||||
- No AI decision-making needed
|
||||
|
||||
**Pattern 2: Single Agent**
|
||||
- Use for: One specialized capability needed
|
||||
- Examples: project analysis, code generation, architecture design
|
||||
- One focused AI task
|
||||
|
||||
**Pattern 3: Sequential (Multiple Phases)**
|
||||
- Use for: Multi-phase workflows with dependencies
|
||||
- Examples: build → test → deploy, setup → configure → verify
|
||||
- Steps must run in order
|
||||
|
||||
**Pattern 4: Parallel (Multiple Agents)**
|
||||
- Use for: Independent tasks that can run simultaneously
|
||||
- Examples: lint + test + security audit
|
||||
- No dependencies between tasks, faster execution
|
||||
|
||||
---
|
||||
|
||||
## Pattern 1: Simple Command Template
|
||||
|
||||
```markdown
|
||||
---
|
||||
description: [What this command does]
|
||||
argument-hint: [argument-placeholder]
|
||||
allowed-tools: Read, Write, Bash(*), Glob, Grep
|
||||
---
|
||||
|
||||
**Arguments**: $ARGUMENTS
|
||||
|
||||
Goal: [What this command accomplishes]
|
||||
|
||||
Core Principles:
|
||||
- [Principle 1: e.g., "Detect don't assume"]
|
||||
- [Principle 2: e.g., "Validate before executing"]
|
||||
- [Principle 3: e.g., "Provide clear feedback"]
|
||||
|
||||
Phase 1: Discovery
|
||||
Goal: [Understand what needs to be done]
|
||||
|
||||
Actions:
|
||||
- Parse $ARGUMENTS for required inputs
|
||||
- Detect project type/framework
|
||||
- Load relevant configuration files
|
||||
- Example: !{bash ls package.json pyproject.toml 2>/dev/null}
|
||||
|
||||
Phase 2: Validation
|
||||
Goal: [Verify inputs and environment]
|
||||
|
||||
Actions:
|
||||
- Check if required files exist
|
||||
- Validate input parameters
|
||||
- Confirm prerequisites met
|
||||
- Example: @package.json
|
||||
|
||||
Phase 3: Execution
|
||||
Goal: [Perform the main task]
|
||||
|
||||
Actions:
|
||||
- Execute scripts or commands
|
||||
- Example: !{bash npm run build}
|
||||
- Handle errors gracefully
|
||||
- Provide progress feedback
|
||||
|
||||
Phase 4: Summary
|
||||
Goal: [Report results]
|
||||
|
||||
Actions:
|
||||
- Display what was accomplished
|
||||
- Show next steps if applicable
|
||||
- Report any warnings or issues
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Pattern 2: Single Agent Template
|
||||
|
||||
```markdown
|
||||
---
|
||||
description: [What this command does]
|
||||
argument-hint: [argument-placeholder]
|
||||
allowed-tools: Task, Read, Write, Bash(*), Glob, Grep, AskUserQuestion
|
||||
---
|
||||
|
||||
**Arguments**: $ARGUMENTS
|
||||
|
||||
Goal: [What this command accomplishes]
|
||||
|
||||
Core Principles:
|
||||
- [Principle 1: e.g., "Understand before acting"]
|
||||
- [Principle 2: e.g., "Ask when uncertain"]
|
||||
- [Principle 3: e.g., "Follow existing patterns"]
|
||||
|
||||
Phase 1: Discovery
|
||||
Goal: [Gather context and requirements]
|
||||
|
||||
Actions:
|
||||
- If $ARGUMENTS is unclear, use AskUserQuestion to gather:
|
||||
- What is the goal?
|
||||
- What are the constraints?
|
||||
- Any specific requirements?
|
||||
- Load relevant files for context
|
||||
- Example: @src/config.ts
|
||||
|
||||
Phase 2: Analysis
|
||||
Goal: [Understand existing codebase and patterns]
|
||||
|
||||
Actions:
|
||||
- Read relevant files identified
|
||||
- Understand current architecture
|
||||
- Identify where changes need to be made
|
||||
- Example: !{bash find src -name "*.ts" | head -10}
|
||||
|
||||
Phase 3: Planning
|
||||
Goal: [Design the approach]
|
||||
|
||||
Actions:
|
||||
- Outline the implementation steps
|
||||
- Identify potential issues
|
||||
- Confirm approach with user if significant
|
||||
- Present clear plan
|
||||
|
||||
Phase 4: Implementation
|
||||
Goal: [Execute with agent]
|
||||
|
||||
Actions:
|
||||
|
||||
Task(description="[Accomplish task]", subagent_type="[agent-name]", prompt="You are the [agent-name] agent. [Accomplish task] for $ARGUMENTS.
|
||||
|
||||
Context: [What context is needed]
|
||||
|
||||
Requirements:
|
||||
- [Requirement 1]
|
||||
- [Requirement 2]
|
||||
- [Requirement 3]
|
||||
|
||||
Expected output: [What should be delivered]")
|
||||
|
||||
Phase 5: Review
|
||||
Goal: [Verify results]
|
||||
|
||||
Actions:
|
||||
- Check agent's output
|
||||
- Verify functionality
|
||||
- Run validation if applicable
|
||||
- Example: !{bash npm run typecheck}
|
||||
|
||||
Phase 6: Summary
|
||||
Goal: [Document what was accomplished]
|
||||
|
||||
Actions:
|
||||
- Summarize changes made
|
||||
- Highlight key decisions
|
||||
- Suggest next steps
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Pattern 3: Sequential Multi-Phase Template
|
||||
|
||||
```markdown
|
||||
---
|
||||
description: [What this command does]
|
||||
argument-hint: [argument-placeholder]
|
||||
allowed-tools: Task, Read, Write, Edit, Bash(*), Glob, Grep, AskUserQuestion, TodoWrite
|
||||
---
|
||||
|
||||
**Arguments**: $ARGUMENTS
|
||||
|
||||
Goal: [What this command accomplishes - typically a complete workflow]
|
||||
|
||||
Core Principles:
|
||||
- Ask clarifying questions early
|
||||
- Understand before acting
|
||||
- Track progress with TodoWrite
|
||||
- Get user approval before major changes
|
||||
|
||||
Phase 1: Discovery
|
||||
Goal: [Understand what needs to be built]
|
||||
|
||||
Actions:
|
||||
- Create todo list with all phases using TodoWrite
|
||||
- Parse $ARGUMENTS for initial context
|
||||
- If unclear, use AskUserQuestion to gather:
|
||||
- What problem are they solving?
|
||||
- What should the outcome be?
|
||||
- Any constraints or requirements?
|
||||
- Summarize understanding and confirm with user
|
||||
|
||||
Phase 2: Exploration
|
||||
Goal: [Understand relevant existing code and patterns]
|
||||
|
||||
Actions:
|
||||
- Launch 2-3 explorer agents in parallel to understand different aspects:
|
||||
- Agent 1: Find similar features and trace their implementation
|
||||
- Agent 2: Map the architecture and key abstractions
|
||||
- Agent 3: Analyze current state of related areas
|
||||
- Each agent should return list of 5-10 key files to read
|
||||
- Wait for all agents to complete
|
||||
- Read all files identified by agents to build deep understanding
|
||||
- Present comprehensive summary of findings
|
||||
- Update todos as each exploration completes
|
||||
|
||||
Phase 3: Clarifying Questions
|
||||
Goal: [Fill in gaps and resolve ambiguities]
|
||||
|
||||
CRITICAL: Do not skip this phase
|
||||
|
||||
Actions:
|
||||
- Review findings and original request
|
||||
- Identify underspecified aspects:
|
||||
- Edge cases
|
||||
- Error handling
|
||||
- Integration points
|
||||
- Design preferences
|
||||
- Present all questions to user in organized list
|
||||
- Wait for answers before proceeding
|
||||
- Update todos
|
||||
|
||||
Phase 4: Design
|
||||
Goal: [Plan the implementation approach]
|
||||
|
||||
Actions:
|
||||
- Based on exploration and answers, design approach
|
||||
- For complex tasks, consider launching architect agents with different focuses
|
||||
- Present design to user with:
|
||||
- What will be changed
|
||||
- Why this approach
|
||||
- Any trade-offs
|
||||
- Get user approval before implementing
|
||||
- Update todos
|
||||
|
||||
Phase 5: Implementation
|
||||
Goal: [Build the solution]
|
||||
|
||||
DO NOT START WITHOUT USER APPROVAL
|
||||
|
||||
Actions:
|
||||
- Read all relevant files identified
|
||||
- Implement following planned approach
|
||||
- Follow codebase conventions
|
||||
- Write clean, documented code
|
||||
- Update todos as each piece completes
|
||||
|
||||
Phase 6: Verification
|
||||
Goal: [Ensure quality and correctness]
|
||||
|
||||
Actions:
|
||||
- Run tests if applicable
|
||||
- Run type checking if applicable
|
||||
- Example: !{bash npm run test && npm run typecheck}
|
||||
- Verify functionality works as expected
|
||||
- Update todos
|
||||
|
||||
Phase 7: Summary
|
||||
Goal: [Document what was accomplished]
|
||||
|
||||
Actions:
|
||||
- Mark all todos complete
|
||||
- Summarize:
|
||||
- What was built
|
||||
- Key decisions made
|
||||
- Files modified
|
||||
- Suggested next steps
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Pattern 4: Parallel Multi-Agent Template
|
||||
|
||||
```markdown
|
||||
---
|
||||
description: [What this command does - typically comprehensive analysis or audit]
|
||||
argument-hint: [argument-placeholder]
|
||||
allowed-tools: Task, Read, Write, Bash(*), Glob, Grep, TodoWrite
|
||||
---
|
||||
|
||||
**Arguments**: $ARGUMENTS
|
||||
|
||||
Goal: [What this command accomplishes - typically running independent checks]
|
||||
|
||||
Core Principles:
|
||||
- Launch independent tasks in parallel for speed
|
||||
- Consolidate results at the end
|
||||
- Track progress with TodoWrite
|
||||
- Provide comprehensive summary
|
||||
|
||||
Phase 1: Discovery
|
||||
Goal: [Understand the target and scope]
|
||||
|
||||
Actions:
|
||||
- Create todo list using TodoWrite
|
||||
- Parse $ARGUMENTS for target (file, directory, etc.)
|
||||
- Validate target exists
|
||||
- Example: !{bash test -e "$ARGUMENTS" && echo "Found" || echo "Not found"}
|
||||
- Load context about target
|
||||
- Update todos
|
||||
|
||||
Phase 2: Parallel Execution
|
||||
Goal: [Run multiple independent agents simultaneously]
|
||||
|
||||
Actions:
|
||||
|
||||
Run the following agents IN PARALLEL (all at once):
|
||||
|
||||
Task(description="[First Check Name]", subagent_type="[agent-type-1]", prompt="You are the [agent-type-1] agent. [Accomplish first task] for $ARGUMENTS. Focus on: [Focus area 1], [Focus area 2]. Deliverable: [Expected output]")
|
||||
|
||||
Task(description="[Second Check Name]", subagent_type="[agent-type-2]", prompt="You are the [agent-type-2] agent. [Accomplish second task] for $ARGUMENTS. Focus on: [Focus area 1], [Focus area 2]. Deliverable: [Expected output]")
|
||||
|
||||
Task(description="[Third Check Name]", subagent_type="[agent-type-3]", prompt="You are the [agent-type-3] agent. [Accomplish third task] for $ARGUMENTS. Focus on: [Focus area 1], [Focus area 2]. Deliverable: [Expected output]")
|
||||
|
||||
Wait for ALL agents to complete before proceeding.
|
||||
|
||||
Update todos as each agent completes.
|
||||
|
||||
Phase 3: Consolidation
|
||||
Goal: [Combine and analyze results from all agents]
|
||||
|
||||
Actions:
|
||||
- Review all agent outputs
|
||||
- Identify common themes or critical issues
|
||||
- Prioritize findings by severity/importance
|
||||
- Cross-reference findings for validation
|
||||
- Update todos
|
||||
|
||||
Phase 4: Summary
|
||||
Goal: [Present comprehensive results]
|
||||
|
||||
Actions:
|
||||
- Mark all todos complete
|
||||
- Present consolidated report:
|
||||
- Results from each agent
|
||||
- Critical issues (high priority)
|
||||
- Warnings and recommendations
|
||||
- Suggested next steps
|
||||
- Organize by priority or category
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Key Patterns and Syntax
|
||||
|
||||
### Arguments
|
||||
Always use `$ARGUMENTS` never `$1`, `$2`, etc.
|
||||
```
|
||||
If user provided --fix flag:
|
||||
Parse from $ARGUMENTS
|
||||
```
|
||||
|
||||
### File Loading
|
||||
Use `@` prefix to load files:
|
||||
```
|
||||
@package.json
|
||||
@src/config.ts
|
||||
```
|
||||
|
||||
### Bash Execution
|
||||
Use `!{bash command}` for inline execution:
|
||||
```
|
||||
!{bash npm run build}
|
||||
!{bash ls -la | grep package}
|
||||
```
|
||||
|
||||
### Script Execution
|
||||
Reference shared scripts using ABSOLUTE paths:
|
||||
```
|
||||
!{bash ~/.claude/plugins/marketplaces/domain-plugin-builder/plugins/domain-plugin-builder/skills/build-assistant/scripts/validate-plugin.sh}
|
||||
```
|
||||
|
||||
### Agent Invocation
|
||||
Use Task() tool calls with proper parameters:
|
||||
|
||||
**Single agent:**
|
||||
```
|
||||
Task(description="Validate setup", subagent_type="verifier-agent", prompt="You are the verifier agent. Validate the setup for $ARGUMENTS. Focus on: configuration files, dependencies, environment variables. Return validation report with pass/fail status.")
|
||||
```
|
||||
|
||||
**Parallel agents (run all at once in SAME message):**
|
||||
```
|
||||
Task(description="Security check", subagent_type="security-checker", prompt="Audit security for $ARGUMENTS")
|
||||
Task(description="Code scan", subagent_type="code-scanner", prompt="Scan code quality for $ARGUMENTS")
|
||||
Task(description="Performance analysis", subagent_type="performance-analyzer", prompt="Analyze performance for $ARGUMENTS")
|
||||
|
||||
Wait for ALL agents to complete before proceeding.
|
||||
```
|
||||
|
||||
Claude Code will convert this natural language to actual Task() tool calls during execution.
|
||||
|
||||
**Examples:**
|
||||
- Single agent: "Invoke the refactorer agent to improve code quality"
|
||||
- Sequential: "First launch the detector agent, then based on findings, invoke the fixer agent"
|
||||
- Parallel: "Launch 3 reviewer agents in parallel focusing on: security, performance, and maintainability"
|
||||
|
||||
### TodoWrite Integration
|
||||
Track progress throughout:
|
||||
```
|
||||
Phase 1: Create initial todo list
|
||||
Phase N: Update todos as work progresses
|
||||
Phase Final: Mark all todos complete
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Ask Before Acting**: Use AskUserQuestion for clarification
|
||||
2. **Detect Don't Assume**: Check what exists rather than assuming structure
|
||||
3. **Progressive Disclosure**: Load context as needed, not all upfront
|
||||
4. **Clear Communication**: Explain what's happening at each phase
|
||||
5. **Error Handling**: Check for issues and provide helpful messages
|
||||
6. **User Approval**: Get confirmation before major changes
|
||||
7. **Track Progress**: Use TodoWrite for complex workflows
|
||||
8. **Validation**: Verify results before completing
|
||||
|
||||
---
|
||||
|
||||
## When to Use Each Pattern
|
||||
|
||||
**Use Pattern 1 (Simple)** when:
|
||||
- No AI decision-making needed
|
||||
- Clear, deterministic steps
|
||||
- Configuration updates, version bumps
|
||||
- Running predefined scripts
|
||||
|
||||
**Use Pattern 2 (Single Agent)** when:
|
||||
- One specialized capability needed
|
||||
- Analysis, generation, or transformation task
|
||||
- Agent can handle the full scope
|
||||
- Example: code refactoring, project setup
|
||||
|
||||
**Use Pattern 3 (Sequential)** when:
|
||||
- Multiple phases with dependencies
|
||||
- User input needed at checkpoints
|
||||
- Complex workflows: understand → design → implement → verify
|
||||
- Example: feature development, major refactoring
|
||||
|
||||
**Use Pattern 4 (Parallel)** when:
|
||||
- Multiple independent checks or analyses
|
||||
- Tasks have no dependencies
|
||||
- Speed matters (parallel execution faster)
|
||||
- Example: comprehensive audits, multi-aspect validation
|
||||
59
skills/build-assistant/templates/plugins/.gitignore.template
Normal file
59
skills/build-assistant/templates/plugins/.gitignore.template
Normal file
@@ -0,0 +1,59 @@
|
||||
# Python
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
*.so
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# Virtual Environment
|
||||
venv/
|
||||
ENV/
|
||||
env/
|
||||
.venv
|
||||
|
||||
# IDE
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Logs
|
||||
*.log
|
||||
|
||||
# Environment variables
|
||||
.env
|
||||
.env.local
|
||||
|
||||
# Testing
|
||||
.pytest_cache/
|
||||
.coverage
|
||||
htmlcov/
|
||||
|
||||
# Node.js
|
||||
node_modules/
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
|
||||
# MCP
|
||||
.mcp_cache/
|
||||
@@ -0,0 +1,13 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [1.0.0] - {{DATE}}
|
||||
|
||||
### Added
|
||||
- Initial plugin scaffold
|
||||
- Plugin directory structure
|
||||
- Plugin manifest (plugin.json)
|
||||
21
skills/build-assistant/templates/plugins/LICENSE.template
Normal file
21
skills/build-assistant/templates/plugins/LICENSE.template
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 Plugin Builder
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
167
skills/build-assistant/templates/plugins/PLUGIN-JSON-GUIDE.md
Normal file
167
skills/build-assistant/templates/plugins/PLUGIN-JSON-GUIDE.md
Normal file
@@ -0,0 +1,167 @@
|
||||
# Plugin.json Configuration Guide
|
||||
|
||||
## Critical Rule: Auto-Discovery vs Custom Paths
|
||||
|
||||
**Auto-Discovered (DO NOT list in plugin.json):**
|
||||
- `commands/` directory → All `.md` files auto-discovered
|
||||
- `agents/` directory → All `.md` files auto-discovered
|
||||
- `skills/` directory → All `SKILL.md` files auto-discovered
|
||||
|
||||
**Only List in plugin.json IF using custom/non-standard locations**
|
||||
|
||||
---
|
||||
|
||||
## Example 1: Standard Structure (Most Common)
|
||||
|
||||
**Directory structure:**
|
||||
```
|
||||
my-plugin/
|
||||
├── .claude-plugin/
|
||||
│ └── plugin.json
|
||||
├── commands/
|
||||
│ ├── deploy.md
|
||||
│ └── validate.md
|
||||
├── agents/
|
||||
│ ├── orchestrator.md
|
||||
│ └── validator.md
|
||||
└── skills/
|
||||
└── deployment-skill/
|
||||
└── SKILL.md
|
||||
```
|
||||
|
||||
**plugin.json (NO commands/agents/skills fields):**
|
||||
```json
|
||||
{
|
||||
"name": "my-plugin"
|
||||
"version": "1.0.0"
|
||||
"description": "Deployment automation"
|
||||
"author": {
|
||||
"name": "Dev Team"
|
||||
"email": "dev@example.com"
|
||||
}
|
||||
"license": "MIT"
|
||||
"keywords": ["deployment"]
|
||||
}
|
||||
```
|
||||
|
||||
**Why:** Everything is in default directories - auto-discovered automatically.
|
||||
|
||||
---
|
||||
|
||||
## Example 2: Custom Locations (Rare)
|
||||
|
||||
**Directory structure:**
|
||||
```
|
||||
my-plugin/
|
||||
├── .claude-plugin/
|
||||
│ └── plugin.json
|
||||
├── commands/ ← Auto-discovered (default)
|
||||
│ └── deploy.md
|
||||
├── specialized/ ← Custom location
|
||||
│ └── advanced-deploy.md
|
||||
└── custom-agents/ ← Custom location
|
||||
└── reviewer.md
|
||||
```
|
||||
|
||||
**plugin.json (List ONLY custom paths):**
|
||||
```json
|
||||
{
|
||||
"name": "my-plugin"
|
||||
"version": "1.0.0"
|
||||
"description": "Deployment automation"
|
||||
"author": {
|
||||
"name": "Dev Team"
|
||||
"email": "dev@example.com"
|
||||
}
|
||||
"license": "MIT"
|
||||
"keywords": ["deployment"]
|
||||
"commands": ["./specialized/advanced-deploy.md"]
|
||||
"agents": ["./custom-agents/reviewer.md"]
|
||||
}
|
||||
```
|
||||
|
||||
**Result:**
|
||||
- `commands/deploy.md` loaded (auto-discovered)
|
||||
- `specialized/advanced-deploy.md` loaded (from plugin.json)
|
||||
- `custom-agents/reviewer.md` loaded (from plugin.json)
|
||||
|
||||
---
|
||||
|
||||
## ❌ WRONG: Duplication Error
|
||||
|
||||
**Directory structure:**
|
||||
```
|
||||
my-plugin/
|
||||
├── commands/
|
||||
│ └── deploy.md
|
||||
└── agents/
|
||||
└── orchestrator.md
|
||||
```
|
||||
|
||||
**plugin.json (CAUSES DUPLICATION):**
|
||||
```json
|
||||
{
|
||||
"name": "my-plugin"
|
||||
"commands": ["./commands/deploy.md"], ❌ WRONG
|
||||
"agents": ["./agents/orchestrator.md"] ❌ WRONG
|
||||
}
|
||||
```
|
||||
|
||||
**Why wrong:**
|
||||
- `deploy.md` loaded from auto-discovery
|
||||
- `deploy.md` loaded AGAIN from plugin.json listing
|
||||
- **Result: Command appears TWICE**
|
||||
|
||||
---
|
||||
|
||||
## Template Default
|
||||
|
||||
Our `plugin.json.template` defaults to:
|
||||
```json
|
||||
{
|
||||
"name": "{{PLUGIN_NAME}}"
|
||||
"version": "{{VERSION}}"
|
||||
"description": "{{DESCRIPTION}}"
|
||||
"author": {
|
||||
"name": "{{AUTHOR_NAME}}"
|
||||
"email": "{{AUTHOR_EMAIL}}"
|
||||
}
|
||||
"homepage": "{{HOMEPAGE_URL}}"
|
||||
"repository": "{{REPOSITORY_URL}}"
|
||||
"license": "{{LICENSE}}"
|
||||
"keywords": {{KEYWORDS}}
|
||||
}
|
||||
```
|
||||
|
||||
**No `commands`, `agents`, or `skills` fields** - assumes standard structure.
|
||||
|
||||
---
|
||||
|
||||
## When Building Plugins
|
||||
|
||||
**For /build-lifecycle-plugin:**
|
||||
1. Creates standard structure (commands/, agents/, skills/)
|
||||
2. Generates plugin.json WITHOUT component fields
|
||||
3. Everything auto-discovered
|
||||
4. No duplication issues
|
||||
|
||||
**Only add component fields manually if:**
|
||||
- You have scripts in non-standard locations
|
||||
- You're organizing differently for a specific reason
|
||||
- You understand the supplemental (not replacement) behavior
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference
|
||||
|
||||
| Scenario | Include in plugin.json? |
|
||||
|:---------|:------------------------|
|
||||
| Component in `commands/` | ❌ No (auto-discovered) |
|
||||
| Component in `agents/` | ❌ No (auto-discovered) |
|
||||
| Component in `skills/` | ❌ No (auto-discovered) |
|
||||
| Component in `custom-dir/` | ✅ Yes (must specify path) |
|
||||
| Both default AND custom | ✅ List only custom paths |
|
||||
|
||||
---
|
||||
|
||||
**Rule of thumb:** If you're using standard directories, leave `commands`, `agents`, `skills` out of plugin.json entirely.
|
||||
107
skills/build-assistant/templates/plugins/README.md
Normal file
107
skills/build-assistant/templates/plugins/README.md
Normal file
@@ -0,0 +1,107 @@
|
||||
# Plugin Templates
|
||||
|
||||
This directory contains templates for creating Claude Code plugins.
|
||||
|
||||
## Files
|
||||
|
||||
- `plugin.json.template` - Plugin manifest template
|
||||
- `example-plugin/` - Complete working example plugin
|
||||
|
||||
## Template Variables
|
||||
|
||||
| Variable | Purpose | Example |
|
||||
|:---------|:--------|:--------|
|
||||
| `{{PLUGIN_NAME}}` | Unique identifier (kebab-case) | `deployment-tools` |
|
||||
| `{{VERSION}}` | Semantic version | `1.0.0` |
|
||||
| `{{DESCRIPTION}}` | Plugin purpose | `Deployment automation` |
|
||||
| `{{AUTHOR_NAME}}` | Author name | `Dev Team` |
|
||||
| `{{AUTHOR_EMAIL}}` | Author email | `dev@company.com` |
|
||||
| `{{HOMEPAGE_URL}}` | Documentation URL | `https://docs.example.com` |
|
||||
| `{{REPOSITORY_URL}}` | Source code URL | `https://github.com/org/plugin` |
|
||||
| `{{LICENSE}}` | License identifier | `MIT`, `Apache-2.0` |
|
||||
| `{{KEYWORDS}}` | Discovery tags (array) | `["deployment", "ci-cd"]` |
|
||||
|
||||
## Plugin Structure
|
||||
|
||||
```
|
||||
plugin-name/
|
||||
├── .claude-plugin/ # Metadata directory
|
||||
│ └── plugin.json # Required: plugin manifest
|
||||
├── commands/ # Slash commands (auto-discovered)
|
||||
│ ├── deploy.md
|
||||
│ └── status.md
|
||||
├── agents/ # Subagents for multi-step tasks (auto-discovered)
|
||||
│ ├── deployment-orchestrator.md
|
||||
│ └── validator.md
|
||||
├── skills/ # Background skills (auto-discovered)
|
||||
│ ├── deployment-skill/
|
||||
│ │ ├── SKILL.md
|
||||
│ │ ├── scripts/
|
||||
│ │ └── templates/
|
||||
│ └── monitoring-skill/
|
||||
│ └── SKILL.md
|
||||
├── hooks/ # Event hooks (optional)
|
||||
│ └── pre-deploy.hook.md
|
||||
├── docs/ # Documentation (optional)
|
||||
│ ├── guide.md
|
||||
│ ├── examples.md
|
||||
│ └── api.md
|
||||
├── memory/ # Persistent state (optional)
|
||||
│ ├── state.json
|
||||
│ └── cache/
|
||||
├── LICENSE # License file (optional)
|
||||
└── README.md # Plugin overview (optional)
|
||||
```
|
||||
|
||||
**Critical**:
|
||||
- All directories at plugin root, NOT inside `.claude-plugin/`
|
||||
- `commands/`, `agents/`, `skills/` are auto-discovered if present
|
||||
- Only list in plugin.json if using custom locations
|
||||
|
||||
## Usage
|
||||
|
||||
### Creating from Template
|
||||
|
||||
```bash
|
||||
# Create plugin structure
|
||||
mkdir -p my-plugin/.claude-plugin
|
||||
|
||||
# Copy and fill manifest
|
||||
cp plugin.json.template my-plugin/.claude-plugin/plugin.json
|
||||
# Edit plugin.json and replace {{VARIABLES}}
|
||||
|
||||
# Add components
|
||||
mkdir my-plugin/commands
|
||||
mkdir my-plugin/skills
|
||||
```
|
||||
|
||||
### Using Build Command
|
||||
|
||||
```bash
|
||||
# Let build system create it for you
|
||||
/build:plugin my-plugin "Description" --components=cmd,skill
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Use ${CLAUDE_PLUGIN_ROOT}**:
|
||||
- For all paths in hooks and MCP servers
|
||||
- Ensures portability across installations
|
||||
|
||||
2. **Semantic Versioning**:
|
||||
- Major: Breaking changes
|
||||
- Minor: New features (backwards-compatible)
|
||||
- Patch: Bug fixes
|
||||
|
||||
3. **Complete Metadata**:
|
||||
- Author, repository, license
|
||||
- Helps users understand plugin origin
|
||||
|
||||
4. **Test Locally**:
|
||||
- Use local marketplace for testing
|
||||
- Uninstall/reinstall to test updates
|
||||
|
||||
---
|
||||
|
||||
**Purpose**: Templates for creating plugins
|
||||
**Used by**: plugin-builder agent
|
||||
24
skills/build-assistant/templates/plugins/README.md.template
Normal file
24
skills/build-assistant/templates/plugins/README.md.template
Normal file
@@ -0,0 +1,24 @@
|
||||
# {{PLUGIN_NAME}}
|
||||
|
||||
{{DESCRIPTION}}
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
/plugin install {{PLUGIN_NAME}}@marketplace-name
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
[Add usage instructions]
|
||||
|
||||
## Components
|
||||
|
||||
- **Commands**: Available slash commands
|
||||
- **Agents**: Specialized AI agents
|
||||
- **Skills**: Reusable capabilities
|
||||
- **Hooks**: Event-driven automation
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "example-plugin",
|
||||
"version": "1.0.0",
|
||||
"description": "Example plugin demonstrating structure and components",
|
||||
"author": {
|
||||
"name": "Framework Team"
|
||||
},
|
||||
"license": "MIT",
|
||||
"keywords": ["example", "template"],
|
||||
"commands": [
|
||||
"./commands/greet.md"
|
||||
],
|
||||
"skills": [
|
||||
"./skills/hello-skill/SKILL.md"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"PreToolUse": [],
|
||||
"PostToolUse": [],
|
||||
"UserPromptSubmit": [],
|
||||
"SessionStart": [],
|
||||
"SessionEnd": [],
|
||||
"PreCompact": []
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "{{PLUGIN_NAME}}",
|
||||
"version": "1.0.0",
|
||||
"description": "{{DESCRIPTION}}",
|
||||
"owner": {
|
||||
"name": "Plugin Developer",
|
||||
"email": "noreply@{{PLUGIN_NAME}}.dev"
|
||||
},
|
||||
"plugins": [
|
||||
{
|
||||
"name": "{{PLUGIN_NAME}}",
|
||||
"description": "{{DESCRIPTION}}",
|
||||
"version": "1.0.0",
|
||||
"author": {
|
||||
"name": "Plugin Developer",
|
||||
"email": "noreply@{{PLUGIN_NAME}}.dev"
|
||||
},
|
||||
"source": "./plugins/{{PLUGIN_NAME}}",
|
||||
"category": "development",
|
||||
"keywords": []
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"mcpServers": {}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "{{PLUGIN_NAME}}",
|
||||
"version": "{{VERSION}}",
|
||||
"description": "{{DESCRIPTION}}",
|
||||
"author": {
|
||||
"name": "{{AUTHOR_NAME}}",
|
||||
"email": "{{AUTHOR_EMAIL}}"
|
||||
},
|
||||
"homepage": "{{HOMEPAGE_URL}}",
|
||||
"repository": "{{REPOSITORY_URL}}",
|
||||
"license": "{{LICENSE}}",
|
||||
"keywords": {{KEYWORDS}}
|
||||
}
|
||||
50
skills/build-assistant/templates/skills/SKILL.md.template
Normal file
50
skills/build-assistant/templates/skills/SKILL.md.template
Normal file
@@ -0,0 +1,50 @@
|
||||
---
|
||||
name: {{SKILL_NAME}}
|
||||
description: {{DESCRIPTION_WHAT_IT_DOES}}. Use when {{TRIGGER_KEYWORDS_AND_CONTEXT}}.
|
||||
{{ALLOWED_TOOLS}}
|
||||
---
|
||||
|
||||
# {{SKILL_NAME}}
|
||||
|
||||
**CRITICAL: The description field above controls when Claude auto-loads this skill.**
|
||||
|
||||
**Description Template:**
|
||||
```yaml
|
||||
description: [What it does]. Use when [building/creating/validating/analyzing] [specific things], [related activities], or when user mentions [keywords], [terms], [phrases].
|
||||
```
|
||||
|
||||
**Good Examples:**
|
||||
```yaml
|
||||
# Validator Skill
|
||||
description: Validate and auto-fix MCP server structure. Use when building MCP servers, validating server code, fixing server issues, or when user mentions MCP validation, server structure, or FastMCP compliance.
|
||||
|
||||
# Generator Skill
|
||||
description: Generate React components with validation. Use when creating React components, building UI elements, scaffolding components, or when user mentions React, components, or UI generation.
|
||||
|
||||
# Analyzer Skill
|
||||
description: Detect framework and project structure. Use when initializing projects, analyzing codebases, identifying frameworks, or when user mentions project detection, framework identification, or stack analysis.
|
||||
```
|
||||
|
||||
**Bad Examples (too vague - won't trigger):**
|
||||
```yaml
|
||||
description: Helps with files # ❌ Too vague
|
||||
description: Development skill # ❌ No triggers
|
||||
description: Use when needed # ❌ No specifics
|
||||
```
|
||||
|
||||
## Instructions
|
||||
|
||||
{{STEP_BY_STEP_INSTRUCTIONS}}
|
||||
|
||||
## Examples
|
||||
|
||||
{{CONCRETE_EXAMPLES}}
|
||||
|
||||
## Requirements
|
||||
|
||||
{{REQUIREMENTS}}
|
||||
|
||||
---
|
||||
|
||||
**Generated from**: $HOME/.claude/marketplaces/multiagent-dev/plugins/multiagent-build/skills/build-assistant/templates/skills/SKILL.md.template
|
||||
**Template Version**: 1.0.0
|
||||
Reference in New Issue
Block a user