Thank you for your interest in contributing to the Plugin Dev toolkit for Claude Code! This document provides guidelines and instructions for contributing.
- Code of Conduct
- Getting Started
- Development Setup
- How to Contribute
- Development Guidelines
- Component-Specific Guidelines
- Testing
- Submitting Changes
- Style Guide
- Community
This project adheres to the Contributor Covenant Code of Conduct. By participating, you are expected to uphold this code. Please report unacceptable behavior to sjnims@gmail.com.
Before contributing, ensure you have:
- Claude Code: Install from claude.ai/code
- GitHub CLI (
gh): Installed and authenticatedbrew install gh # macOS gh auth login - Git: For version control
- markdownlint-cli2 and prettier: For linting (should be available globally)
# Verify they're installed markdownlint-cli2 --version prettier --version
-
Read the documentation:
- README.md - User-facing documentation
- CLAUDE.md - Development documentation
- SECURITY.md - Security policy
-
Explore the architecture:
plugins/plugin-dev/ ├── commands/ # 4 slash commands ├── skills/ # 10 skills └── agents/ # 3 specialized agents -
Understand the plugin components:
- 10 skills for different plugin development aspects
- 3 agents for validation and generation
- 4 slash commands:
/plugin-dev:start,/plugin-dev:create-plugin,/plugin-dev:create-marketplace,/plugin-dev:plugin-dev-guide
# Fork the repository on GitHub, then:
git clone https://github.com/YOUR-USERNAME/plugin-dev.git
cd plugin-devgit remote add upstream https://github.com/sjnims/plugin-dev.gitgit checkout -b feature/your-feature-name
# or
git checkout -b fix/issue-description# From repository root
claude --plugin-dir plugins/plugin-dev
# Test command in Claude Code
/plugin-dev:create-plugingh auth status # Should show logged in with 'repo' and 'project' scopes- Check existing issues: Look for issues labeled
good first issueorhelp wanted - Review the roadmap: See what features are planned
- Fix bugs: Found a bug? Open an issue first, then submit a PR
- Improve documentation: Documentation improvements are always welcome
- Suggest features: Open a feature request issue to discuss first
- Check for existing work: Search issues and PRs to avoid duplicates
- Discuss major changes: Open an issue first for significant changes
- One feature per PR: Keep pull requests focused on a single feature or fix
- Follow the architecture: Maintain the three-layer design (Commands → Skills → Agents)
- Simplicity First: Don't over-engineer. Keep solutions simple and focused.
- Consistency: Follow existing patterns in the codebase.
- Minimal Dependencies: This plugin only requires GitHub CLI (
gh) as an external dependency. - Documentation: Document all user-facing changes.
- Testing: Always test locally before submitting.
- Commands:
plugins/plugin-dev/commands/*.md - Skills:
plugins/plugin-dev/skills/*/SKILL.md - Agents:
plugins/plugin-dev/agents/*.md
All markdown files must follow the repository's style:
# Lint before committing
markdownlint-cli2 '**/*.md'
# Format with prettier
prettier --check '**/*.md'
prettier --write '**/*.md' # fix formatting issuesGitHub Actions workflows must pass YAML linting:
# Lint workflow files
uvx yamllint .github/workflows/Style Rules (see .markdownlint.json):
- Use ATX-style headers (
#,##,###) - Use dash-style lists (
-, not*or+) - Use 2-space indentation for lists
- Use fenced code blocks (not indented)
- No line length limits
- Allowed HTML:
<p>,<img>,<example>,<commentary>
When documenting bash execution patterns in skill files, use [BANG] instead of ! to prevent unintended execution during skill loading (Claude Code #12781).
<!-- In skill documentation (SKILL.md, references/, examples/) -->
Current branch: [BANG]`git branch --show-current`
<!-- The [BANG] placeholder prevents execution while loading -->Important:
- This applies to skill files that get loaded into context
- Command files (
.claude/commands/*.md) use actual!syntax - See SECURITY.md for full details
All shell scripts should pass shellcheck validation:
# Check all plugin scripts
shellcheck plugins/plugin-dev/skills/*/scripts/*.sh
# Check a specific script
shellcheck plugins/plugin-dev/skills/hook-development/scripts/test-hook.shIf a pattern intentionally triggers a shellcheck warning, add a directive comment:
# shellcheck disable=SC2086 # Word splitting intended for arguments
command $unquoted_varAlways include a comment explaining why the directive is needed.
| Warning | Typical Fix |
|---|---|
| SC2086 | Quote variables: "$var" |
| SC2046 | Quote command substitution: "$(cmd)" |
| SC2034 | Remove unused variables or export them |
| SC2155 | Separate declaration and assignment: local var; var=$(cmd) |
When creating or modifying commands:
-
YAML Frontmatter Required:
--- description: Brief description argument-hint: [optional-argument] allowed-tools: AskUserQuestion, Bash(gh:*), Read ---
-
Imperative Form: Write instructions FOR Claude, not TO the user
- ✅ Good: "Do X", "Run Y", "Create Z"
- ❌ Bad: "You should do X", "Please run Y"
-
Error Handling: Include error handling for:
- GitHub CLI not found
- Not authenticated
- Not in git repository
- Insufficient permissions
-
Clear Outputs: Provide clear success/failure messages
When creating or modifying skills:
-
YAML Frontmatter Required:
--- name: skill-name description: This skill should be used when the user asks to "trigger phrase 1"... ---
-
Description: Use third-person with specific trigger phrases
- ✅ Good:
This skill should be used when the user asks to "create user stories" - ❌ Bad:
Use this skill to help users
- ✅ Good:
-
Progressive Disclosure:
SKILL.md: Core methodology (<2,000 words)references/: Detailed documentation- No duplication between files
-
Templates: Store in
references/subdirectory
When creating or modifying agents:
-
YAML Frontmatter Required:
--- name: agent-name description: Use this agent when... model: inherit color: blue tools: Bash, AskUserQuestion skills: skill-name-1, skill-name-2 ---
-
Trigger Examples: Include 3-4
<example>blocks showing when the agent should trigger -
Clear System Prompt: Be specific about the agent's role and responsibilities
-
Minimal Tools/Skills: Only include tools and skills the agent actually needs
When creating and/or modifying hooks:
- Matcher Patterns: Keep regex patterns simple and specific
- Timeout: Set appropriate timeouts (default: 10 seconds)
- Testing: Test thoroughly to avoid false positives
| Mistake | Problem | Solution |
|---|---|---|
| Testing in development repo | Pollutes your environment with test files | Create a separate test repository |
Using ! in skill documentation |
Shell execution during skill load | Use [BANG] placeholder (see SECURITY.md) |
| Missing trigger phrases | Skills don't load when expected | Include specific user queries in descriptions |
| Overly broad tool matchers | Hooks trigger unexpectedly | Use specific patterns like Write|Edit not * |
| Hardcoded paths | Plugin breaks on other machines | Use ${CLAUDE_PLUGIN_ROOT} |
| Large SKILL.md files | Slow loading, excessive context | Keep core <2,000 words; use references/ for details |
| Missing frontmatter fields | Components fail validation | Always include required fields (name, description) |
| Committing test files | Repository bloat | Use .gitignore and clean up test repos |
Use the built-in validation scripts before submitting (paths relative to plugins/plugin-dev/):
# Validate agents
./skills/agent-development/scripts/validate-agent.sh agents/my-agent.md
# Validate commands
./skills/command-development/scripts/validate-command.sh commands/my-command.md
# Validate hooks
./skills/hook-development/scripts/validate-hook-schema.sh hooks/hooks.json
# Validate plugin settings
./skills/plugin-settings/scripts/validate-settings.sh .claude/plugin.local.md- Load plugin:
claude --plugin-dir plugins/plugin-dev - Run validation scripts for changed components
- Test affected commands
- Verify GitHub CLI integration works
- Test in a clean repository (not your development repo)
- Test error cases (missing permissions, no git repo, etc.)
For significant changes, test the complete lifecycle:
/plugin-dev:create-pluginCreate a test repository to avoid polluting your development environment:
# Create a private test repo (recommended for security)
mkdir test-plugin-repo
cd test-plugin-repo
git init
gh repo create test-plugin-repo --private --source=. --remote=origin
git push -u origin main
# Now test the plugin
claude --plugin-dir /path/to/plugin-dev/plugins/plugin-devCleanup: After testing, delete the test repository:
# Delete local directory
cd .. && rm -rf test-plugin-repo
# Delete remote repository
gh repo delete test-plugin-repo --yes- Update README.md if user-facing changes
- Update CLAUDE.md if architectural changes
- Update component documentation if applicable
# Lint all markdown
markdownlint-cli2 '**/*.md'
# Format with prettier
prettier --write '**/*.md'Use clear, descriptive commit messages:
git commit -m "Add feature: description of what you added
- Bullet point of change 1
- Bullet point of change 2
Fixes #123"git push origin feature/your-feature-name- Go to the repository
- Click "New Pull Request"
- Select your fork and branch
- Fill out the PR template completely
- Link related issues
See pull_request_template.md for the complete checklist. Key items:
- Code follows style guidelines
- Documentation updated
- Markdown linted
- Tested locally
- Component-specific checks completed
- No breaking changes (or clearly documented)
Your PR will automatically run these checks:
| Workflow | What It Checks |
|---|---|
markdownlint.yml |
Markdown style and formatting |
links.yml |
Broken links in documentation |
component-validation.yml |
Plugin component structure |
version-check.yml |
Version consistency across manifests |
validate-workflows.yml |
GitHub Actions syntax |
claude-pr-review.yml |
AI-powered code review |
All checks must pass before merging. Fix any failures before requesting review.
Version releases are handled by maintainers. If your contribution requires a version bump, maintainers will follow the Version Release Procedure.
- Headers: Use ATX-style (
#,##,###) - Lists: Use dash-style (
-) - Code blocks: Use fenced blocks with language tags
- Line length: No limit (MD013 disabled)
- Emphasis: Use
**bold**for strong,*italic*for emphasis
- Always include required fields (
name,description) - Use consistent indentation (2 spaces)
- Use comma-separated lists for tools/skills:
Tool1, Tool2
- Use imperative mood: "Create", "Run", "Execute"
- Be specific: "Run
gh project create" not "Create a project" - Include error handling
- Provide clear outputs
- First line: Brief summary (50 chars max)
- Blank line
- Detailed description (wrap at 72 chars)
- Reference issues:
Fixes #123,Closes #456
- Questions: Open an issue with the question template
- Discussions: Use GitHub Discussions
- Bugs: Use the bug report template
- Features: Use the feature request template
- Documentation: Use the documentation template
- Security: See SECURITY.md
- Automated Checks: PR must pass all checks
- Review: At least one maintainer review required
- Feedback: Address review comments
- Approval: Maintainer approves PR
- Merge: Maintainer merges (usually squash merge)
Contributors are recognized in:
- Release notes
- README.md (for significant contributions)
- Git commit history
If you have questions not covered here:
- Check CLAUDE.md for development details
- Search existing issues
- Open a question issue
- Start a discussion
Thank you for contributing to Plugin Dev! Your contributions help make plugin development better for everyone using Claude Code.