# Authoring and Discovery


A skill is a `SKILL.md` file in its own directory. kli finds skills by name from a fixed set of locations, makes each one runnable as `skill:<name>`, and expands a `$name` sigil in your prompt into that skill's content. This page covers where to put a skill so kli finds it, how to override a builtin, and how to invoke a skill once it is found.

## Place a skill where kli looks

kli searches these locations, in this order, and stops at the first skill it finds for any given name:

1. The project skills directory: `<repo>/.kli/skills/`
2. `.agents/skills/` in each directory from the working directory up to the repo root, nearest first
3. The global skills directory: `~/.config/kli/skills/`
4. `~/.agents/skills/`
5. The skills shipped inside kli (the builtins)

To add a skill to one project, create its directory and `SKILL.md` under `.kli/skills/`:

```
<repo>/.kli/skills/run-migrations/SKILL.md
```

To make a skill available in every project, put it under `~/.config/kli/skills/` instead. The two `.agents/skills/` locations are read the same way kli reads its own skills, so a skill written for another agent that follows the Agent Skills layout is discovered without changes.

A skill's name comes from the `name` field in its `SKILL.md` frontmatter; with no `name` field, kli uses the directory holding the file. Names are lowercase letters, digits, and hyphens. The `.kli/skills/` and `~/.config/kli/skills/` directories also load a plain `.md` file placed directly in them as a single skill; the `.agents/skills/` and builtin locations load skills only from subdirectories that contain a `SKILL.md`.

The repo root bounds the upward walk. kli treats a directory holding `.git` as the root and does not look above it. Dot-directories and `node_modules` are skipped during the search, and `.gitignore`, `.ignore`, and `.fdignore` rules under a skills directory exclude matching paths.

## Override a builtin by name

The builtins sit last in the search order, so any skill you write with the same name takes precedence. kli keeps the first skill it finds for a name and drops every later one. To replace a builtin named `creating-extensions` for one project, create a skill with that name in the project directory:

```
<repo>/.kli/skills/creating-extensions/SKILL.md
```

The project skill now answers to `skill:creating-extensions` and to the `$creating-extensions` sigil; the builtin no longer loads. The same rule shadows a global skill from a project, or a builtin from `~/.config/kli/skills/`. A name that collides between two locations is reported as a diagnostic at startup so the shadowing is visible.

## Reference a skill with the $name sigil

Write `$` immediately followed by a skill name anywhere in a prompt, and kli prepends that skill's content before the prompt is sent. The reference itself stays in your text. To pull in the `run-migrations` skill:

```
$run-migrations against the staging database
```

kli reads the longest skill name that matches at the `$`. If you have both `run` and `run-migrations`, `$run-migrations` resolves to `run-migrations`, not `run`. The match must end at a boundary: the character after the name must be something other than a letter, digit, or hyphen (end of line counts). So `$run-migrations` matches but `$run-migrationsx` does not, because the name would have to continue.

A `$` only opens a reference when the character before it is not a letter, digit, or another `$`. This keeps `cost$run` and `$$run` from being read as skill references. A `$name` that matches no discovered skill stays as ordinary text, so `$5` is left alone unless you have a skill whose name starts with `5`. Each referenced skill is added once, in the order the references first appear.

## Run a skill with skill:name

Every discovered skill registers a command named `skill:<name>`. Run it from the session to load that skill's content as input:

```
skill:run-migrations
```

Anything you type after the name is passed to the skill as arguments:

```
skill:run-migrations --dry-run
```

The command reads the `SKILL.md` body fresh each time it runs, so editing a skill takes effect on the next invocation without a restart. The transcript keeps the command line you typed while the model receives the skill content.

## Related

- [Skill anatomy](/kli/extend/skills/anatomy) for the `SKILL.md` format and frontmatter.
- [Commands](/kli/commands/slash-commands) for how `skill:<name>` fits alongside other session commands.
