Prerequisites: Load plugins/context/capabilities/events_skills.md first
Purpose: Step-by-step workflow for adding a new skill
Related: See plugins/context/architecture/overview.md for plugin concepts
Adding a new skill involves:
Time: ~10-15 minutes
Skill names should be:
task-management, brand-guidelines, api-reference# Create skill directory
mkdir -p .opencode/skill/{skill-name}
# Create subdirectories as needed
mkdir -p .opencode/skill/{skill-name}/scripts
.opencode/skill/{skill-name}/
├── SKILL.md # Required: Main skill documentation
├── router.sh # Optional: CLI router script
└── scripts/
└── skill-cli.ts # Optional: CLI tool implementation
The SKILL.md file is required and provides skill documentation and integration details.
Claude Code Skills live in .claude/skills/{skill-name}/SKILL.md and support extra frontmatter:
allowed-tools for tool restrictionscontext + agent to run in a forked subagenthooks for lifecycle eventsuser-invocable to hide from slash menuKeep descriptions keyword-rich so auto-discovery triggers reliably. See ../to-be-consumed/claude-code-docs/agent-skills.md for full details.
---
name: {skill-name}
description: Brief description of what the skill provides
---
# Skill Name
**Purpose**: What this skill helps users do
## What I do
- Feature 1
- Feature 2
- Feature 3
## How to use me
### Basic Commands
bash
npx ts-node .opencode/skill/{skill-name}/scripts/skill-cli.ts command1
npx ts-node .opencode/skill/{skill-name}/scripts/skill-cli.ts command2
### Command Reference
| Command | Description |
|---------|-------------|
| `command1` | What command1 does |
| `command2` | What command2 does |
## Examples
### Example 1
$ npx ts-node .opencode/skill/{skill-name}/scripts/skill-cli.ts example
Expected output or behavior
## Architecture
.opencode/ └── skill/
└── {skill-name}/
├── SKILL.md # This file
├── router.sh # CLI router
└── scripts/
└── skill-cli.ts # CLI implementation
## Integration
### With Agents
This skill integrates with agents by:
- Description of how agents use the skill
- Example agent prompt that invokes the skill
### With OpenCode Events
The skill uses OpenCode event hooks:
- `tool.execute.before` - For [what it does]
- `tool.execute.after` - For [what it does]
---
## Step 3: Create Router Script (Optional)
For CLI-based skills, create a router.sh script:
bash #!/bin/bash
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
if [ $# -eq 0 ]; then
echo "Usage: bash router.sh <command> [options]"
echo "Run 'bash router.sh help' for more information"
exit 1
fi
COMMAND="$1" shift
case "$COMMAND" in
help|--help|-h)
echo "{Skill Name} - Skill Description"
echo ""
echo "Usage: bash router.sh <command> [options]"
echo ""
echo "Commands:"
echo " command1 Description of command1"
echo " command2 Description of command2"
echo " help Show this help message"
;;
command1)
npx ts-node "$SCRIPT_DIR/scripts/skill-cli.ts" command1 "$@"
;;
command2)
npx ts-node "$SCRIPT_DIR/scripts/skill-cli.ts" command2 "$@"
;;
*)
echo "Unknown command: $COMMAND"
echo "Run 'bash router.sh help' for available commands"
exit 1
;;
esac
### Make Router Executable
bash chmod +x .opencode/skill/{skill-name}/router.sh
---
## Step 4: Create CLI Implementation
### Basic CLI Structure
typescript #!/usr/bin/env ts-node // CLI implementation for {skill-name} skill
interface Args { command: string
}
async function main() { const args = parseArgs()
switch (args.command) {
case 'command1':
await handleCommand1(args)
break
case 'command2':
await handleCommand2(args)
break
case 'help':
default:
showHelp()
} }
function parseArgs(): Args { const args = process.argv.slice(2) return {
command: args[0] || 'help',
...parseOptions(args.slice(1))
} }
async function handleCommand1(args: Args) { // Implementation console.log('Running command1...') }
function showHelp() { console.log(` { Skill Name }
Usage: npx ts-node scripts/skill-cli.ts [options]
Commands: command1 Description of command1 command2 Description of command2 help Show this help message
Options: --option1 Description of option1 --option2 Description of option2 `) }
main().catch(console.error)
---
## Step 5: Register in Registry (Optional)
If the skill should be included in profiles, add it to `registry.json`:
### Add to Components
json { "skills": [
{
"id": "{skill-name}",
"name": "Skill Name",
"type": "skill",
"path": ".opencode/skill/{skill-name}/SKILL.md",
"description": "Brief description",
"tags": ["tag1", "tag2"],
"dependencies": []
}
] }
### Add to Profiles
json { "profiles": {
"essential": {
"components": [
"skill:{skill-name}"
]
}
} }
---
## Step 6: Test the Skill
### Test CLI Commands
bash
bash .opencode/skill/{skill-name}/router.sh help
bash .opencode/skill/{skill-name}/router.sh command1 --option value
npx ts-node .opencode/skill/{skill-name}/scripts/skill-cli.ts help
### Test OpenCode Integration
If the skill uses OpenCode events:
1. Call the skill via OpenCode
2. Verify event hooks fire correctly
3. Check conversation history for skill content injection
4. Verify output enhancement works
---
## Example: Creating Task-Management Skill
### Directory Creation
bash mkdir -p .opencode/skill/task-management/scripts
### SKILL.md
name: task-management
Purpose: Track and manage feature subtasks
# Show all task statuses
npx ts-node .opencode/skill/task-management/scripts/task-cli.ts status
# Show next eligible tasks
npx ts-node .opencode/skill/task-management/scripts/task-cli.ts next
# Mark complete
npx ts-node .opencode/skill/task-management/scripts/task-cli.ts complete <feature> <seq> "summary"
#!/bin/bash
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
case "$1" in
help|--help|-h)
echo "Task Management Skill"
echo "Usage: bash router.sh <command>"
echo "Commands: status, next, blocked, complete, validate"
;;
status|next|blocked|validate)
npx ts-node "$SCRIPT_DIR/scripts/task-cli.ts" "$@"
;;
complete)
npx ts-node "$SCRIPT_DIR/scripts/task-cli.ts" "$@"
;;
*)
echo "Unknown command: $1"
bash router.sh help
;;
esac
Each skill should do one thing well:
.opencode/skill/{skill-name}/SKILL.md created.opencode/skill/{skill-name}/router.sh created (if CLI-based).opencode/skill/{skill-name}/scripts/skill-cli.ts created (if CLI-based)chmod +x)| Command | Purpose |
|---|---|
mkdir -p .opencode/skill/{name} |
Create skill directory |
chmod +x router.sh |
Make router executable |
npx ts-node scripts/cli.ts help |
Test CLI help |
plugins/context/capabilities/events_skills.mdplugins/context/architecture/overview.mdplugins/context/capabilities/events.mdguides/adding-agent.md../to-be-consumed/claude-code-docs/agent-skills.md