Navigation
Copy page

Write Your First Skill

On this page

A skill is a Markdown file of instructions kli hands to the model when a task calls for them. You write the instructions once; the model reaches for them on its own when your request matches what the skill is for. In this tutorial you'll write one skill and trigger it two ways. No code, just a file.

We'll build a skill that tells the model how to write a git commit message the way you like them: a short subject line, then a body that explains why the change was made.

Create the skill directory

A skill is a directory holding a file named SKILL.md. The directory name is the skill's name, so kli reads the two together. Move into the root of any git project and make the directory:

sh
mkdir -p .kli/skills/commit-message

commit-message is the name you'll use to call the skill. Keep skill names lowercase, with hyphens between words and no spaces.

Write the skill

Create the file .kli/skills/commit-message/SKILL.md:

sh
$EDITOR .kli/skills/commit-message/SKILL.md

Put this in it:

markdown
---
name: commit-message
description: Write a git commit message for staged changes, following our subject-then-body format.
---

Run `git diff --staged` to see what changed.

Write a commit message with:

- A subject line under 50 characters, in the imperative mood
  ("Add", not "Added"), with no trailing period.
- A blank line.
- A body that explains why the change was made, wrapped at 72
  columns. Describe the reason, not a restatement of the diff.

Print the message. Don't commit anything yet.

The frontmatter is two lines that kli reads:

  • name is how you call the skill. Match it to the directory name.
  • description is one sentence saying what the skill is for and when to use it. This is the line the model reads to decide whether the skill fits the task in front of it, so write it as a trigger, not a label.

Everything below the closing --- is the body: the instructions kli gives the model when the skill is invoked. Save the file.

Start kli and confirm the skill loaded

Start kli from the project root:

sh
kli

At startup kli walks .kli/skills/, finds your SKILL.md, and registers the skill. From here, the same skill triggers two different ways.

Trigger it by name with $

Write $ immediately followed by the skill's name anywhere in your message:

text
$commit-message

kli sees $commit-message, matches it to the skill you wrote, and prepends the skill's body to your message before the model reads it. The model runs git diff --staged, then writes the message in your format. Stage a change first so there's something to describe:

sh
git add -A

The $name sigil is for when you already know which skill you want. You're naming it on purpose. It also works mid-sentence, so you can fold it into a longer request:

text
Stage the auth fix and then $commit-message for it.

kli expands $commit-message into the skill's instructions and leaves the rest of your sentence untouched. The model follows the skill and applies it to the auth fix you named.

Trigger it by description

You don't have to name the skill. kli also shows the model every skill's name and description at the start of the session. When your request matches a skill's description, the model loads the skill itself. Ask for the thing the skill is for, without the $:

text
Write a commit message for what I've staged.

The model reads its list of skills, sees that commit-message is described as writing a commit message for staged changes, and loads the body on its own. You get the same formatted message, and you never typed the skill's name. The description you wrote is the line the model matched against.

What you built

You have a working skill at .kli/skills/commit-message/SKILL.md. It lives in the project, so anyone who clones the repo and runs kli gets the same skill. Edit SKILL.md and start a fresh session to change what the model does.

To see how the description advertisement and the $name sigil work, the directories kli searches beyond the project, and the rest of the frontmatter you can set, read Skill anatomy.