Skill Development
Create custom skills to extend CLEO with specialized knowledge and workflows.
Skill Structure
skills/my-skill/
├── SKILL.md # Main skill instructions (required)
├── references/ # Supporting documentation
│ ├── patterns.md
│ └── examples.md
├── examples/ # Example outputs
│ └── sample-output.md
└── assets/ # Templates and resources
└── template.md
---
name: "My Skill"
description: "What this skill does"
version: "1.0.0"
tier: 2
tags:
- "category"
- "subcategory"
triggers:
- "keyword phrase one"
- "keyword phrase two"
---
# My Skill
Brief description of the skill's purpose.
## When to Use
- Use case 1
- Use case 2
- Use case 3
## Workflow
### Step 1: Analysis
[Instructions for first step]
### Step 2: Execution
[Instructions for second step]
### Step 3: Output
[Instructions for output generation]
## Output Format
[Expected output structure]
## References
@skills/my-skill/references/patterns.md
@skills/my-skill/references/examples.md
## Anti-Patterns
- What NOT to do
- Common mistakes
Frontmatter Fields
| Field | Type | Required | Description |
|---|
name | string | ✅ | Human-readable name |
description | string | ✅ | One-line description |
version | string | ✅ | Semantic version |
tier | number | ✅ | 0-3 hierarchy level |
tags | array | ✅ | Category tags |
triggers | array | ❌ | Auto-invocation phrases |
Step-by-Step Guide
Create Directory
mkdir -p skills/ct-my-skill/{references,examples,assets}
Write SKILL.md
Create the main skill file with frontmatter and instructions.
Add to Manifest
Register in skills/manifest.json:{
"name": "ct-my-skill",
"version": "1.0.0",
"description": "My skill description",
"path": "skills/ct-my-skill",
"tags": ["category"],
"status": "active",
"tier": 2
}
Add Dispatch Rules
Update dispatch_matrix if needed:{
"dispatch_matrix": {
"by_task_type": {
"my-type": "ct-my-skill"
},
"by_keyword": {
"my-keyword|my-phrase": "ct-my-skill"
}
}
}
Validate
cleo skills validate ct-my-skill
Naming Conventions
| Convention | Example | Purpose |
|---|
ct- prefix | ct-my-skill | Identifies CLEO skills |
| Hyphenated | ct-task-executor | Readable, URL-safe |
| Descriptive | ct-test-writer-bats | Indicates function |
Tier Selection
| Tier | When to Use |
|---|
| 0 | HITL entry points, orchestration |
| 1 | Planning, decomposition, architecture |
| 2 | Implementation, execution, research |
| 3 | Utilities, documentation, meta-skills |
Most custom skills belong in Tier 2 (execution) or Tier 3 (support).
Tag Selection
Choose tags that enable discovery:
tags:
- "primary-category" # Main function (research, implementation)
- "secondary-category" # Specific domain (bash, testing)
- "use-case" # When to use (validation, analysis)
Writing Effective Instructions
- Be specific: “Create a function that validates JSON against schema”
- Provide structure: Step-by-step workflow with clear phases
- Include examples: Show expected input/output
- Define boundaries: What the skill does NOT do
- Use RFC 2119: MUST, SHOULD, MAY for requirements
DON’T
- Be vague: “Help with coding tasks”
- Overload: Too many responsibilities in one skill
- Skip validation: No output format specification
- Ignore errors: No error handling guidance
Output Protocol Compliance
If your skill produces subagent output, follow the protocol:
## Output Requirements
MUST write findings to `{{OUTPUT_DIR}}/{{DATE}}_{{TOPIC_SLUG}}.md`
MUST append ONE line to `{{MANIFEST_PATH}}`
MUST return ONLY: "Work complete. See MANIFEST.jsonl for summary."
MUST NOT return content in response
Token Resolution
Use dynamic tokens that get resolved at spawn time:
| Token | Description |
|---|
{{TASK_ID}} | Current task ID |
{{EPIC_ID}} | Parent epic ID |
{{DATE}} | Current date (YYYY-MM-DD) |
{{SESSION_ID}} | Active session ID |
{{OUTPUT_DIR}} | Output directory path |
{{MANIFEST_PATH}} | Manifest file path |
Reference Files
Use references/ for supporting documentation:
## References
@skills/ct-my-skill/references/patterns.md
@skills/ct-my-skill/references/edge-cases.md
References are loaded on demand, saving context budget.
Testing Your Skill
Manual Testing
# Direct invocation
@skills/ct-my-skill/SKILL.md
Execute my-skill workflow for task T1234.
Dispatch Testing
# Check if dispatch works
source lib/skill-dispatch.sh
skill=$(skill_dispatch_by_keywords "my-keyword test")
echo "Selected: $skill" # Should show ct-my-skill
Validation
cleo skills validate ct-my-skill
Common Patterns
Research Skill
## Workflow
1. **Gather Sources**: Use web search and Context7
2. **Analyze**: Extract key findings
3. **Synthesize**: Create summary
4. **Output**: Write to manifest
## Output Format
```json
{
"key_findings": ["Finding 1", "Finding 2"],
"sources": ["URL 1", "URL 2"],
"recommendations": ["Action 1", "Action 2"]
}
### Implementation Skill
```markdown
## Workflow
1. **Understand**: Read task requirements
2. **Plan**: Outline approach
3. **Implement**: Write code
4. **Validate**: Run tests
5. **Document**: Add JSDoc/comments
## Quality Gates
- [ ] Tests pass
- [ ] No linting errors
- [ ] Documentation complete
Validation Skill
## Checklist
- [ ] Schema compliance
- [ ] Security scan
- [ ] Performance check
- [ ] Documentation review
## Output
| Check | Status | Notes |
|-------|--------|-------|
| Schema | ✅ | Passes validation |
| Security | ⚠️ | Review needed |
Publishing Skills
To Project
# Just create in skills/ directory
mkdir -p skills/ct-my-skill
To SkillsMP
- Create GitHub repository with SKILL.md
- Follow SkillsMP submission guidelines
- Skills are auto-indexed from GitHub
Debugging
Skill Not Found
# Check manifest
cat skills/manifest.json | jq '.skills[] | select(.name == "ct-my-skill")'
# Check file exists
ls skills/ct-my-skill/SKILL.md
Dispatch Not Working
# Check dispatch matrix
cat skills/manifest.json | jq '.dispatch_matrix'
# Test dispatch manually
source lib/skill-dispatch.sh
skill_dispatch_by_keywords "your keyword"
Token Not Resolved
# Check token resolution
context=$(skill_prepare_spawn "ct-my-skill" "T1234")
echo "$context" | jq '.tokenResolution'