A CLI tool for Agent Skills development.
Skilo includes a skill that teaches AI coding assistants how to use the CLI. Add it to your project to enable your assistant to create and validate skills:
# Create the skills directory
mkdir -p .claude/skills
# Copy the use-skilo skill from the skilo repository
curl -fsSL https://raw.githubusercontent.com/manuelmauro/skilo/main/.claude/skills/use-skilo/SKILL.md \
-o .claude/skills/use-skilo/SKILL.md --create-dirsOr clone and copy manually:
git clone https://github.com/manuelmauro/skilo.git /tmp/skilo
cp -r /tmp/skilo/.claude/skills/use-skilo .claude/skills/Once installed, your AI assistant will be able to:
- Create new skills using
skilo new - Validate skills with
skilo lint - Format SKILL.md files with
skilo fmt - Extract skill metadata with
skilo read-properties - Generate agent prompts with
skilo to-prompt - Set up CI workflows for skill validation
# Clone the repository
git clone https://github.com/manuelmauro/skilo.git
cd skilo
# Install using make
make install
# Or directly with cargo
cargo install --path .- Rust 1.92.0 (pinned in
rust-toolchain.toml)
# Create a skill with the default template (hello-world)
skilo new my-skill
# Use a specific template
skilo new my-skill --template minimal
# Specify the script language
skilo new my-skill --lang python
# Add a description and license
skilo new my-skill --description "My awesome skill" --license MITAvailable templates:
hello-world(default) - A minimal working skill with a greeting scriptminimal- Bare-bones skill with only SKILL.mdfull- Complete skill with all optional directoriesscript-based- Skill focused on script execution
Supported languages: python, bash, javascript, typescript
# Lint a skill directory
skilo lint path/to/skill
# Lint all skills in current directory
skilo lint .
# Strict mode (treat warnings as errors)
skilo lint --strict .
# Auto-fix simple issues
skilo lint --fix .# Format SKILL.md files (includes table alignment)
skilo fmt path/to/skill
# Check formatting without modifying
skilo fmt --check .
# Show diff of changes
skilo fmt --diff .Formatting includes:
- YAML frontmatter normalization
- Markdown table column alignment
# Run lint + format check (ideal for CI)
skilo check .Extract skill metadata as JSON for programmatic use:
# Read properties from a single skill (outputs JSON object)
skilo read-properties path/to/skill
# Read properties from multiple skills (outputs JSON array)
skilo read-properties path/to/skills/
# Read from multiple paths
skilo read-properties skill-a skill-bOutput includes: name, description, license, compatibility, metadata, allowed_tools, and path.
Generate XML for use in agent system prompts:
# Generate XML for a single skill
skilo to-prompt path/to/skill
# Generate XML for all skills in a directory
skilo to-prompt path/to/skills/Example output:
<available_skills>
<skill>
<name>my-skill</name>
<description>A brief description of what the skill does.</description>
<location>path/to/my-skill/SKILL.md</location>
</skill>
</available_skills>All commands support multiple output formats:
skilo lint --format text . # Human-readable (default)
skilo lint --format json . # JSON output
skilo lint --format sarif . # SARIF for code scanning integrationsA valid skill follows this structure:
my-skill/
├── SKILL.md # Required: manifest with YAML frontmatter
├── scripts/ # Optional: executable scripts
├── references/ # Optional: additional documentation
└── assets/ # Optional: static resources
---
name: my-skill
description: A brief description of what the skill does.
license: MIT
---
# My Skill
Detailed documentation goes here.Create a .skilorc.toml file for project-specific settings:
[lint]
strict = true
[lint.rules]
name_format = true # E001: Name format validation
name_length = 64 # E002: Name max length (false to disable)
name_directory = true # E003: Name matches directory
description_required = true # E004: Description not empty
description_length = 1024 # E005: Description max length (false to disable)
compatibility_length = 500 # E006: Compatibility max length (false to disable)
references_exist = true # E009: Referenced files exist
body_length = 500 # W001: Max body lines (false to disable)
script_executable = true # W002: Scripts are executable
script_shebang = true # W003: Scripts have shebang
[fmt]
sort_frontmatter = true
indent_size = 2
format_tables = true
[new]
default_license = "MIT"
default_template = "hello-world"
default_lang = "python"Rules with thresholds accept true (default), false (disabled), or a number:
[lint.rules]
name_directory = false # Disable for monorepos
script_executable = false # Disable for Windows
name_length = 128 # Custom max name length
description_length = false # Disable description length check
body_length = 1000 # Custom max body linesAdd skilo validation to your GitHub Actions workflow:
# .github/workflows/skills.yml
name: Validate Skills
on:
push:
branches: [main]
pull_request:
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Install skilo
run: cargo install [email protected]
- name: Lint skills
run: skilo lint . --strict
- name: Check formatting
run: skilo fmt . --checkTo upload results to GitHub's Security tab, use SARIF output:
- name: Run skilo check
run: skilo lint . --format sarif > results.sarif
continue-on-error: true
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: results.sarif| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Validation errors found |
| 2 | Invalid arguments or configuration |
| 3 | I/O error |
MIT OR Apache-2.0