Skills
Skills are markdown-based prompt templates that extend agent capabilities. Each skill is a markdown file with YAML frontmatter defining metadata and a body containing the instructions injected into the agent's prompt when invoked.
Skill File Format
A skill file has two parts:
---
name: review-pr
description: Review a pull request
user-invocable: true
argument-hint: "<PR number>"
---
Review pull request $ARGUMENTS and provide feedback on:
1. Code quality
2. Test coverage
3. Security concerns
Frontmatter Fields
The YAML frontmatter (between --- delimiters) supports these fields:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
name | String | No | Derived from filename | Skill identifier |
description | String | No | "" | Human-readable description |
user-invocable | bool | No | false | Whether users can invoke this skill directly |
allowed-tools | Vec<String> | No | [] | Tools the skill is allowed to use |
model | String | No | null | Model override for this skill |
context | String | No | null | Additional context instructions |
agent | String | No | null | Target agent for the skill |
hooks | Vec<String> | No | [] | Hook events this skill responds to |
argument-hint | String | No | null | Hint text shown when skill expects arguments |
unsafe | bool | No | false | Whether the skill performs potentially dangerous operations |
Frontmatter uses kebab-case field names (e.g., user-invocable) which are deserialized to snake_case internally.
If frontmatter parsing fails, the skill still loads with default values — this is non-fatal.
Argument Substitution
Skill bodies support argument placeholders that are replaced at invocation time:
| Placeholder | Replacement |
|---|---|
$ARGUMENTS | The full argument string passed to the skill |
$ARGUMENTS0 through $ARGUMENTS9 | Positional arguments (0-indexed) |
$0 through $9 | Shorthand for positional arguments |
Example:
---
name: compare
description: Compare two files
---
Compare the files $0 and $1, highlighting the differences.
Invoked as /compare src/old.rs src/new.rs, this becomes:
Compare the files src/old.rs and src/new.rs, highlighting the differences.
Resolution Order
When a skill is invoked by name, swarm searches three directories in priority order:
| Priority | Path | Style |
|---|---|---|
| 1 | .claude/skills/<name>/SKILL.md | Project-local, directory-style |
| 2 | .skills/<name>.md | Project-local, flat files (backward-compatible) |
| 3 | ~/.claude/skills/<name>/SKILL.md | Global user skills |
The first match wins. This means project-local skills override global ones.
Skill Names
Valid skill names contain only: [a-zA-Z0-9_:-]. Names with other characters are rejected.
Skill Discovery
The discover_skills() function scans all three directories and returns a BTreeMap<String, SkillSummary> of available skills:
| Field | Description |
|---|---|
name | Skill name |
description | From frontmatter |
user_invocable | Whether the skill can be invoked by users |
Discovery is sorted alphabetically for consistent ordering.
Skill Resolution
The resolve() function finds a skill by name and returns a fully-resolved SkillDefinition:
| Field | Description |
|---|---|
path | File path where the skill was found |
frontmatter | Parsed SkillFrontmatter |
body | Skill body text (with frontmatter stripped) |
Related
- Custom Skills — How to create and test skills
- Prompt Pipeline — How skills integrate into the prompt
- Tools — The skill tool that invokes skills