This guide explains how to create commands for ccmd, covering the required structure, best practices, and advanced features.
- Overview
- Project vs Command Configuration
- Required Files
- File Structure
- Command ccmd.yaml Reference
- Project ccmd.yaml Reference
- ccmd-lock.yaml Reference
- Writing Command Instructions
- Best Practices
- Examples
- Testing Your Command
A ccmd command is a Git repository containing instructions for Claude Code. Commands help automate tasks, provide specialized knowledge, or enhance Claude's capabilities in specific domains.
It's important to understand that ccmd uses two different types of ccmd.yaml files:
- Project ccmd.yaml - Located in your project root, lists commands to install
- Command ccmd.yaml - Located in each command's repository, defines command metadata
These files have completely different structures and purposes.
Every command MUST have these two files:
- ccmd.yaml - Metadata about your command
- index.md - Instructions for Claude (can be named differently if specified in ccmd.yaml)
Additional recommended files:
- README.md - Documentation for users
- LICENSE - License for your command
- examples/ - Usage examples
my-command/
├── ccmd.yaml # Required: Command metadata
├── index.md # Required: Claude instructions
└── README.md # Recommended: User documentation
When installed, commands are stored in your project:
your-project/
├── ccmd.yaml # Project configuration
├── ccmd-lock.yaml # Lock file (auto-generated)
└── .claude/
└── commands/
├── my-command.md # Standalone file (copy of index.md)
└── my-command/ # Full command directory
├── ccmd.yaml
├── index.md
└── README.md
The ccmd.yaml file in a command repository defines the command's metadata:
# Required fields
name: my-awesome-command # Command name (lowercase, hyphens allowed)
version: 1.0.0 # Semantic version (major.minor.patch)
entry: index.md # Entry file (default: index.md)
# Optional fields
description: Short description # One-line description
author: Your Name # Command author
repository: https://github.com/user/repo # Source repository
tags: # Tags for discovery
- automation
- testing
- developmentAll fields except tags are required for a valid command.
The ccmd.yaml file in your project root lists commands to install:
commands:
- owner/repo # Install latest version
- owner/repo@1.0.0 # Install specific version
- owner/repo@branch # Install from branchThis is a simple list format - no other fields are used in the project's ccmd.yaml.
The ccmd-lock.yaml file tracks installed command versions:
version: "1.0"
lockfileVersion: 1
commands:
command-name:
name: command-name
version: 1.0.0
source: https://github.com/owner/repo.git
resolved: https://github.com/owner/repo.git@1.0.0
commit: abc123def456...
installed_at: 2025-06-22T01:07:51.524358-03:00
updated_at: 2025-06-22T01:07:51.524358-03:00This file is automatically managed by ccmd and should not be edited manually.
The index.md file contains instructions for Claude. Write clear, specific instructions that help Claude understand what to do.
# Command Name
Brief description of what this command does.
## Purpose
Explain the command's purpose and when to use it.
## Instructions
1. Step-by-step instructions
2. Be specific and clear
3. Include error handling
## Parameters
- `--option`: Description of option
- `--flag`: What this flag does
## Examples
### Example 1: Basic Usage
When the user says "..." you should...
### Example 2: Advanced Usage
For complex scenarios...
## Notes
- Important considerations
- Limitations
- Best practices# Advanced Command
You are an AI assistant specialized in [domain]. When this command is invoked, follow these guidelines:
## Core Responsibilities
1. **Analysis Phase**
- Examine the project structure
- Identify relevant files
- Understand the context
2. **Planning Phase**
- Create a plan of action
- Consider edge cases
- Validate assumptions
3. **Execution Phase**
- Implement the solution
- Provide clear feedback
- Handle errors gracefully
## Context Understanding
You have access to:
- File system operations
- Code analysis capabilities
- Pattern matching
## Decision Framework
When deciding how to proceed:
```flowchart
Start -> Analyze Request -> Is it valid?
| |
Yes No -> Request clarification
|
V
Plan approach -> Execute -> Verify -> CompleteCommon errors and how to handle them:
-
Missing Dependencies
- Check for required tools
- Suggest installation commands
- Provide alternatives
-
Invalid Input
- Validate parameters
- Show usage examples
- Explain what went wrong
When generating code:
- Follow language best practices
- Include error handling
- Add meaningful comments
- Consider performance
Structure your responses as:
- Acknowledgment - Confirm understanding
- Plan - Outline the approach
- Implementation - Execute the plan
- Summary - Recap what was done
- Next Steps - Suggest follow-up actions
## Best Practices
### 1. Clear Instructions
❌ **Bad:**
```markdown
Help with testing stuff.
✅ Good:
You are an AI assistant specialized in creating comprehensive test suites. When invoked:
1. Analyze the codebase to identify testable components
2. Generate unit tests with >80% coverage
3. Include edge cases and error scenarios
4. Use the project's existing test framework❌ Bad:
Handle various cases appropriately.✅ Good:
## Examples
### Creating a REST API Test
When user says: "test my API endpoint"
1. Identify the endpoint (e.g., POST /api/users)
2. Generate test cases:
- Valid input: `{ "name": "John", "email": "john@example.com" }`
- Missing fields: `{ "name": "John" }`
- Invalid email: `{ "name": "John", "email": "invalid" }`
3. Create the test file with proper assertions❌ Bad:
Supports various options.✅ Good:
## Parameters
- `--language <lang>`: Target programming language (js, python, go, rust)
- Default: Detected from project
- Example: `--language python`
- `--style <style>`: Code style to follow
- Options: standard, google, airbnb
- Default: standard
- Example: `--style google`
- `--output <path>`: Where to save generated files
- Default: Current directory
- Example: `--output ./tests/`Include information about what Claude should look for:
## Project Analysis
Before proceeding, analyze:
1. **Technology Stack**
- Check package.json, requirements.txt, go.mod
- Identify frameworks (React, Django, etc.)
- Note build tools and configurations
2. **Project Structure**
- Locate source directories
- Find test directories
- Identify configuration files
3. **Coding Standards**
- Detect linting configurations
- Observe existing code style
- Check for formatting rulesProvide helpful error messages:
## Error Handling
If the project type cannot be determined:
"I couldn't automatically detect your project type. Please specify:
- For Node.js: Ensure package.json exists
- For Python: Ensure requirements.txt or setup.py exists
- For Go: Ensure go.mod exists
Or use the --language flag to specify manually."Command's ccmd.yaml:
name: format-json
version: 1.0.0
description: Format and validate JSON files
author: Jane Doe
repository: https://github.com/janedoe/format-json
entry: index.md
tags:
- json
- formatting
- validation# index.md
# Format JSON Command
This command formats and validates JSON files in your project.
## Instructions
When invoked, you should:
1. Find all JSON files in the current directory and subdirectories
2. Validate each file for proper JSON syntax
3. Format with 2-space indentation
4. Report any errors found
5. Optionally fix the errors if requested
## Parameters
- `--fix`: Automatically fix formatting issues
- `--indent <n>`: Use n spaces for indentation (default: 2)
- `--sort-keys`: Sort object keys alphabetically
## Example Usage
User: "format all json files"
Response:
- Search for .json files
- Validate and format each file
- Report: "Formatted 5 JSON files. Found and fixed 2 syntax errors."Project's ccmd.yaml:
commands:
- janedoe/format-json
- apitools/api-generator@2.1.0
- myorg/internal-tool@mainCommand's ccmd.yaml:
name: api-generator
version: 2.1.0
description: Generate REST API boilerplate with tests and documentation
author: API Tools Team
repository: https://github.com/apitools/api-generator
entry: index.md
tags:
- api
- rest
- boilerplate
- testing# index.md
# API Generator Command
You are an AI assistant specialized in generating REST API boilerplate code with comprehensive tests and documentation.
## Core Capabilities
1. Generate REST API endpoints with CRUD operations
2. Create corresponding test suites
3. Generate OpenAPI/Swagger documentation
4. Set up authentication and validation
## Workflow
### 1. Analysis Phase
- Detect project type and framework
- Identify existing patterns
- Check for configuration files
### 2. Generation Phase
Based on user input, generate:
#### API Endpoints
```javascript
// Example for "generate user API"
router.get('/users', async (req, res) => {
const users = await User.findAll();
res.json(users);
});
router.post('/users', validateUser, async (req, res) => {
const user = await User.create(req.body);
res.status(201).json(user);
});describe('User API', () => {
it('should return all users', async () => {
const response = await request(app).get('/users');
expect(response.status).toBe(200);
expect(response.body).toBeInstanceOf(Array);
});
});paths:
/users:
get:
summary: Get all users
responses:
200:
description: List of users--framework <name>: Target framework (express, fastify, koa)--database <type>: Database type (postgres, mongodb, mysql)--auth <method>: Authentication method (jwt, oauth, basic)--no-tests: Skip test generation--no-docs: Skip documentation generation
User: "generate a product API" Actions:
- Create routes/products.js with CRUD endpoints
- Create tests/products.test.js with test suite
- Update OpenAPI spec with product endpoints
- Create models/Product.js with schema
User: "generate API for blog with posts and comments using postgres" Actions:
- Set up Sequelize with PostgreSQL
- Create models: Post, Comment with associations
- Generate nested routes: /posts/:id/comments
- Include pagination and filtering
- Add comprehensive tests
- Generate full OpenAPI documentation
## Testing Your Command
Before publishing, test your command thoroughly:
### 1. Local Testing
```bash
# Clone your command repository
git clone https://github.com/you/your-command
cd your-command
# Validate structure
ls ccmd.yaml index.md # Should exist
- ccmd.yaml is valid YAML
- All required fields are present (name, version, description, author, repository, entry)
- Version follows semantic versioning (e.g., 1.0.0)
- index.md exists and is readable
- Instructions are clear and specific
- Examples work as documented
- Error cases are handled
Test your command in different scenarios:
# Test in empty directory
mkdir test-empty && cd test-empty
/your-command
# Test in existing project
cd ~/my-project
/your-command --resource users
# Test with parameters
/your-command --resource products --no-tests# Ensure all files are committed
git add .
git commit -m "feat: initial command implementation"
# Create a version tag
git tag -a v1.0.0 -m "Initial release"
git push origin main --tagsOnce published, others can install your command:
ccmd install github.com/username/my-commandCreate a clear README.md with:
- Installation instructions
- Usage examples
- Parameter documentation
- Common use cases
When you run ccmd install, the following happens:
- Repository is cloned to a temporary directory
- Validation ensures ccmd.yaml and index.md exist
- Files are copied to
.claude/commands/[command-name]/ - Standalone file is created at
.claude/commands/[command-name].md - Lock file is updated with version information
The standalone .md file is what Claude Code uses when you invoke the command.
-
Command not found after installation
- Ensure ccmd.yaml has correct name field
- Check file permissions
-
Instructions not working as expected
- Test with different phrasings
- Add more specific examples
- Include edge cases
-
Version conflicts
- Use proper semantic versioning
- Document breaking changes
- Consider backwards compatibility
- Read the ccmd documentation
- Ask in GitHub Discussions
- Report issues on GitHub