Navigation
Copy page

Authoring and Discovery

On this page

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.

  • Skill anatomy for the SKILL.md format and frontmatter.
  • Commands for how skill:<name> fits alongside other session commands.