diff --git a/plugins/plugin-dev/skills/skill-development/SKILL.md b/plugins/plugin-dev/skills/skill-development/SKILL.md index d3e9ef6..6cf611b 100644 --- a/plugins/plugin-dev/skills/skill-development/SKILL.md +++ b/plugins/plugin-dev/skills/skill-development/SKILL.md @@ -285,6 +285,14 @@ Good for: Complex domains with validation utilities ## Additional Resources +### Example Skills + +Copy-paste ready skill templates in `examples/`: + +- **`examples/minimal-skill.md`** - Bare-bones skill with just SKILL.md (git conventions example) +- **`examples/complete-skill.md`** - Full skill with references/, examples/, and scripts/ (API testing example) +- **`examples/frontmatter-templates.md`** - Quick-reference frontmatter patterns for common use cases + ### Reference Files For detailed guidance, consult: diff --git a/plugins/plugin-dev/skills/skill-development/examples/complete-skill.md b/plugins/plugin-dev/skills/skill-development/examples/complete-skill.md new file mode 100644 index 0000000..6742ce2 --- /dev/null +++ b/plugins/plugin-dev/skills/skill-development/examples/complete-skill.md @@ -0,0 +1,463 @@ +# Complete Skill Example + +A full-featured skill demonstrating all optional components and progressive disclosure. + +## Directory Structure + +```text +api-testing/ +├── SKILL.md +├── references/ +│ ├── assertion-patterns.md +│ └── authentication-guide.md +├── examples/ +│ ├── rest-api-tests.sh +│ └── graphql-tests.sh +└── scripts/ + └── generate-test.sh +``` + +## File Contents + +### SKILL.md + +```markdown +--- +name: api-testing +description: This skill should be used when the user asks to "write API tests", "test REST endpoints", "test GraphQL queries", "create integration tests for APIs", "mock API responses", "test authentication flows", or needs guidance on API testing patterns, assertion strategies, or test organization. +--- + +# API Testing + +This skill provides guidance for writing comprehensive API tests. + +## Quick Start + +To write an API test: + +1. Identify the endpoint and expected behavior +2. Set up authentication if required +3. Make the request with appropriate headers +4. Assert response status, body, and headers +5. Clean up test data if needed + +## Test Structure + +Organize tests by resource and operation: + +```text +tests/ +├── auth/ +│ ├── login.test.js +│ └── refresh-token.test.js +├── users/ +│ ├── create-user.test.js +│ ├── get-user.test.js +│ └── update-user.test.js +└── helpers/ + ├── auth.js + └── fixtures.js +``` + +## Core Patterns + +### Request Pattern + +```javascript +const response = await request(app) + .post('/api/users') + .set('Authorization', `Bearer ${token}`) + .send({ name: 'Test User', email: 'test@example.com' }) + .expect(201); +``` + +### Assertion Pattern + +```javascript +expect(response.body).toMatchObject({ + id: expect.any(String), + name: 'Test User', + createdAt: expect.any(String) +}); +``` + +## Authentication + +For authenticated endpoints, see `references/authentication-guide.md` for detailed patterns including: + +- JWT token handling +- OAuth2 flows +- API key authentication +- Session-based auth + +## Advanced Assertions + +For complex assertion patterns including nested objects, arrays, and error responses, see `references/assertion-patterns.md`. + +## Generating Tests + +Use the test generator script for scaffolding: + +```bash +./scripts/generate-test.sh users create-user POST /api/users +``` + +## Working Examples + +See `examples/` for complete test files: + +- `rest-api-tests.sh` - curl-based REST API tests +- `graphql-tests.sh` - GraphQL query tests +``` + +### references/authentication-guide.md + +```markdown +# Authentication Testing Guide + +Detailed patterns for testing authenticated API endpoints. + +## JWT Authentication + +### Setup Helper + +```javascript +// helpers/auth.js +const jwt = require('jsonwebtoken'); + +function generateTestToken(userId, role = 'user') { + return jwt.sign( + { sub: userId, role }, + process.env.JWT_SECRET, + { expiresIn: '1h' } + ); +} + +function generateExpiredToken(userId) { + return jwt.sign( + { sub: userId }, + process.env.JWT_SECRET, + { expiresIn: '-1h' } + ); +} + +module.exports = { generateTestToken, generateExpiredToken }; +``` + +### Test Cases + +```javascript +describe('Protected Endpoints', () => { + it('returns 401 without token', async () => { + await request(app) + .get('/api/profile') + .expect(401); + }); + + it('returns 401 with expired token', async () => { + const token = generateExpiredToken('user-123'); + await request(app) + .get('/api/profile') + .set('Authorization', `Bearer ${token}`) + .expect(401); + }); + + it('returns 200 with valid token', async () => { + const token = generateTestToken('user-123'); + await request(app) + .get('/api/profile') + .set('Authorization', `Bearer ${token}`) + .expect(200); + }); +}); +``` + +## API Key Authentication + +```javascript +describe('API Key Auth', () => { + it('accepts valid API key in header', async () => { + await request(app) + .get('/api/data') + .set('X-API-Key', process.env.TEST_API_KEY) + .expect(200); + }); + + it('accepts valid API key in query', async () => { + await request(app) + .get(`/api/data?api_key=${process.env.TEST_API_KEY}`) + .expect(200); + }); +}); +``` +``` + +### references/assertion-patterns.md + +```markdown +# Assertion Patterns + +Common assertion patterns for API response validation. + +## Object Matching + +### Exact Match + +```javascript +expect(response.body).toEqual({ + id: '123', + name: 'Test', + active: true +}); +``` + +### Partial Match + +```javascript +expect(response.body).toMatchObject({ + name: 'Test', + active: true + // id can be anything +}); +``` + +### Type Matching + +```javascript +expect(response.body).toMatchObject({ + id: expect.any(String), + count: expect.any(Number), + tags: expect.any(Array), + meta: expect.any(Object) +}); +``` + +## Array Assertions + +### Contains Item + +```javascript +expect(response.body.items).toContainEqual( + expect.objectContaining({ name: 'Test' }) +); +``` + +### Array Length + +```javascript +expect(response.body.items).toHaveLength(10); +``` + +### All Items Match + +```javascript +response.body.items.forEach(item => { + expect(item).toHaveProperty('id'); + expect(item).toHaveProperty('createdAt'); +}); +``` + +## Error Response Assertions + +```javascript +expect(response.body).toMatchObject({ + error: { + code: 'VALIDATION_ERROR', + message: expect.any(String), + details: expect.any(Array) + } +}); +``` +``` + +### examples/rest-api-tests.sh + +```bash +#!/bin/bash +# REST API test examples using curl + +BASE_URL="${API_URL:-http://localhost:3000}" +TOKEN="${TEST_TOKEN:-}" + +# Test: Create user +echo "Testing POST /api/users..." +response=$(curl -s -w "\n%{http_code}" \ + -X POST "$BASE_URL/api/users" \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer $TOKEN" \ + -d '{"name": "Test User", "email": "test@example.com"}') + +status=$(echo "$response" | tail -1) +body=$(echo "$response" | head -n -1) + +if [ "$status" = "201" ]; then + echo "PASS: User created" + echo "$body" | jq . +else + echo "FAIL: Expected 201, got $status" + exit 1 +fi + +# Test: Get user +echo "Testing GET /api/users/1..." +response=$(curl -s -w "\n%{http_code}" \ + -X GET "$BASE_URL/api/users/1" \ + -H "Authorization: Bearer $TOKEN") + +status=$(echo "$response" | tail -1) + +if [ "$status" = "200" ]; then + echo "PASS: User retrieved" +else + echo "FAIL: Expected 200, got $status" + exit 1 +fi + +echo "All tests passed!" +``` + +### examples/graphql-tests.sh + +```bash +#!/bin/bash +# GraphQL API test examples + +BASE_URL="${API_URL:-http://localhost:3000/graphql}" +TOKEN="${TEST_TOKEN:-}" + +# Test: Query users +echo "Testing users query..." +response=$(curl -s -w "\n%{http_code}" \ + -X POST "$BASE_URL" \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer $TOKEN" \ + -d '{"query": "{ users { id name email } }"}') + +status=$(echo "$response" | tail -1) +body=$(echo "$response" | head -n -1) + +if [ "$status" = "200" ] && echo "$body" | jq -e '.data.users' > /dev/null; then + echo "PASS: Users query successful" +else + echo "FAIL: Query failed" + exit 1 +fi + +# Test: Mutation +echo "Testing createUser mutation..." +response=$(curl -s -w "\n%{http_code}" \ + -X POST "$BASE_URL" \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer $TOKEN" \ + -d '{"query": "mutation { createUser(input: {name: \"Test\", email: \"test@example.com\"}) { id } }"}') + +status=$(echo "$response" | tail -1) + +if [ "$status" = "200" ]; then + echo "PASS: Mutation successful" +else + echo "FAIL: Mutation failed" + exit 1 +fi + +echo "All GraphQL tests passed!" +``` + +### scripts/generate-test.sh + +```bash +#!/bin/bash +# Generate API test scaffold +# Usage: ./generate-test.sh +# Example: ./generate-test.sh users create-user POST /api/users + +set -e + +RESOURCE="${1:?Resource name required}" +OPERATION="${2:?Operation name required}" +METHOD="${3:-GET}" +ENDPOINT="${4:-/api/$RESOURCE}" + +OUTPUT_DIR="tests/$RESOURCE" +OUTPUT_FILE="$OUTPUT_DIR/$OPERATION.test.js" + +mkdir -p "$OUTPUT_DIR" + +cat > "$OUTPUT_FILE" << EOF +const request = require('supertest'); +const app = require('../../src/app'); +const { generateTestToken } = require('../helpers/auth'); + +describe('$METHOD $ENDPOINT', () => { + let token; + + beforeAll(() => { + token = generateTestToken('test-user-id'); + }); + + it('returns expected response', async () => { + const response = await request(app) + .${METHOD,,}('$ENDPOINT') + .set('Authorization', \`Bearer \${token}\`) + .expect(200); + + expect(response.body).toBeDefined(); + // Add specific assertions here + }); + + it('returns 401 without authentication', async () => { + await request(app) + .${METHOD,,}('$ENDPOINT') + .expect(401); + }); +}); +EOF + +echo "Generated: $OUTPUT_FILE" +``` + +## Usage + +After installing the plugin containing this skill: + +```text +$ claude +> How do I write tests for my REST API? + +[Skill loads with core patterns, references available for details] + +> Show me authentication testing patterns + +[Claude loads references/authentication-guide.md for detailed examples] + +> Generate a test scaffold for my users endpoint + +[Claude uses scripts/generate-test.sh or explains the pattern] +``` + +## Key Points + +1. **Progressive disclosure**: Core patterns in SKILL.md, details in references/ +2. **Working examples**: Real executable scripts users can run +3. **Utility scripts**: Automation for common tasks +4. **Strong triggers**: Multiple specific phrases for different use cases +5. **Cross-references**: SKILL.md points to resources when appropriate + +## When to Use This Pattern + +- Complex domains requiring detailed documentation +- Skills with reusable scripts or utilities +- Topics with multiple sub-areas (auth, assertions, etc.) +- Skills that benefit from working code examples + +## Progressive Disclosure in Action + +| Level | Content | Word Count | +|-------|---------|------------| +| Metadata | name + description | ~50 words | +| SKILL.md | Core patterns, quick start | ~400 words | +| references/ | Detailed guides | ~600 words | +| examples/ | Working code | N/A (code) | +| scripts/ | Automation | N/A (code) | + +Total context loaded depends on user needs, not skill complexity. diff --git a/plugins/plugin-dev/skills/skill-development/examples/frontmatter-templates.md b/plugins/plugin-dev/skills/skill-development/examples/frontmatter-templates.md new file mode 100644 index 0000000..5799a7a --- /dev/null +++ b/plugins/plugin-dev/skills/skill-development/examples/frontmatter-templates.md @@ -0,0 +1,167 @@ +# Frontmatter Templates + +Copy-paste ready YAML frontmatter templates for common skill patterns. + +## Basic Skill + +The minimal required frontmatter: + +```yaml +--- +name: skill-name +description: This skill should be used when the user asks to "do X", "perform Y", or needs guidance on Z. +--- +``` + +**Requirements:** + +- `name`: kebab-case, matches directory name +- `description`: Third-person, starts with "This skill should be used when..." + +## Skill with Strong Triggers + +Multiple specific trigger phrases for better activation: + +```yaml +--- +name: database-migrations +description: This skill should be used when the user asks to "create a migration", "run migrations", "rollback migration", "migration status", "schema changes", "alter table", "add column", "database versioning", or needs guidance on database migration patterns, schema evolution, or migration best practices. +--- +``` + +**Best practices:** + +- Include 5-10 specific trigger phrases +- Use phrases users actually say (quoted) +- Cover variations ("create a migration", "write migration", "new migration") +- Include related concepts ("schema changes", "alter table") + +## Read-Only Skill + +Restrict to read-only tools for safe exploration: + +```yaml +--- +name: codebase-analyzer +description: This skill should be used when the user asks to "analyze codebase", "find patterns", "code quality report", "architecture overview", "dependency analysis", or needs guidance on understanding existing code structure. +allowed-tools: Read, Grep, Glob, Task +--- +``` + +**Use cases:** + +- Code analysis and exploration +- Documentation generation +- Security audits +- Dependency reviews + +## Multi-Domain Skill + +Skill covering related sub-topics: + +```yaml +--- +name: aws-infrastructure +description: This skill should be used when the user asks to "deploy to AWS", "configure S3", "set up Lambda", "create EC2 instance", "configure IAM", "CloudFormation template", "AWS CDK", "Terraform for AWS", or needs guidance on AWS services, infrastructure as code, or cloud deployment patterns. +--- +``` + +**Organization tip:** Use references/ subdirectories for sub-topics: + +```text +references/ +├── compute/ +│ ├── ec2.md +│ └── lambda.md +├── storage/ +│ └── s3.md +└── iam/ + └── policies.md +``` + +## Security-Focused Skill + +Restricted tools for sensitive operations: + +```yaml +--- +name: secrets-manager +description: This skill should be used when the user asks to "manage secrets", "rotate credentials", "environment variables", "secure configuration", "vault integration", or needs guidance on secrets management patterns. +allowed-tools: Read, Grep, AskUserQuestion +--- +``` + +**Security considerations:** + +- Exclude Write, Edit, Bash to prevent accidental exposure +- Include AskUserQuestion for confirmation flows +- Document why restrictions exist in SKILL.md + +## Plugin-Specific Skill + +Skill designed for a specific plugin context: + +```yaml +--- +name: plugin-testing +description: This skill should be used when the user asks to "test plugin", "validate plugin", "plugin integration tests", "test commands", "test hooks", "test agents", or needs guidance on testing Claude Code plugin components. +--- +``` + +**Plugin context:** + +- Reference plugin-specific paths with `${CLAUDE_PLUGIN_ROOT}` +- Assume plugin structure exists +- Cross-reference other plugin skills + +## Frontmatter Field Reference + +| Field | Required | Type | Description | +|-------|----------|------|-------------| +| `name` | Yes | string | Skill identifier (kebab-case) | +| `description` | Yes | string | When to use (third-person) | +| `allowed-tools` | No | string | Comma-separated tool names | + +## Common Mistakes + +### Wrong: Second-person description + +```yaml +# DON'T +description: Use this skill when you want to create migrations. +``` + +### Right: Third-person description + +```yaml +# DO +description: This skill should be used when the user asks to "create migrations"... +``` + +### Wrong: Vague triggers + +```yaml +# DON'T +description: This skill should be used for database stuff. +``` + +### Right: Specific triggers + +```yaml +# DO +description: This skill should be used when the user asks to "create a migration", "run migrations", "rollback migration"... +``` + +### Wrong: Missing quotes around phrases + +```yaml +# DON'T +description: This skill should be used when the user asks to create a migration... +``` + +### Right: Quoted trigger phrases + +```yaml +# DO +description: This skill should be used when the user asks to "create a migration"... +``` diff --git a/plugins/plugin-dev/skills/skill-development/examples/minimal-skill.md b/plugins/plugin-dev/skills/skill-development/examples/minimal-skill.md new file mode 100644 index 0000000..7ed12dd --- /dev/null +++ b/plugins/plugin-dev/skills/skill-development/examples/minimal-skill.md @@ -0,0 +1,109 @@ +# Minimal Skill Example + +A bare-bones skill with just a SKILL.md file. + +## Directory Structure + +```text +git-conventions/ +└── SKILL.md +``` + +## File Contents + +### SKILL.md + +```markdown +--- +name: git-conventions +description: This skill should be used when the user asks about "git commit message format", "conventional commits", "commit conventions", "branch naming", or needs guidance on git workflow standards. +--- + +# Git Conventions + +This skill provides guidance on git commit messages and branch naming conventions. + +## Commit Message Format + +Follow the Conventional Commits specification: + +```text +(): + +[optional body] + +[optional footer(s)] +``` + +### Types + +- **feat**: New feature +- **fix**: Bug fix +- **docs**: Documentation changes +- **style**: Code style changes (formatting, semicolons) +- **refactor**: Code refactoring without behavior change +- **test**: Adding or updating tests +- **chore**: Maintenance tasks + +### Examples + +```text +feat(auth): add OAuth2 login support + +fix(api): handle null response from external service + +docs(readme): update installation instructions +``` + +## Branch Naming + +Use descriptive prefixes: + +- `feature/` - New features +- `fix/` - Bug fixes +- `docs/` - Documentation updates +- `chore/` - Maintenance tasks + +### Examples + +```text +feature/user-authentication +fix/null-pointer-exception +docs/api-reference +``` +``` + +## Usage + +After installing the plugin containing this skill: + +```text +$ claude +> What format should I use for commit messages? + +[Skill loads and provides Conventional Commits guidance] +``` + +## Key Points + +1. **Single file**: Only SKILL.md required +2. **Strong triggers**: Description includes specific phrases users would say +3. **Third-person description**: "This skill should be used when..." +4. **Imperative body**: Instructions use "Follow...", "Use...", not "You should..." +5. **Focused content**: ~300 words, no external resources needed + +## When to Use This Pattern + +- Simple domain knowledge +- Quick reference guides +- Team conventions and standards +- Single-topic utilities +- Learning skill development + +## Extending This Skill + +To add more functionality: + +1. **Add references**: Create `references/` for detailed documentation +2. **Add examples**: Create `examples/` for working code samples +3. **Add scripts**: Create `scripts/` for automation utilities