Navigation
Copy page

Choosing an Altitude

On this page

kli extends at three altitudes. They differ by what they can do and how much of the contribution you write, not by a cost you minimize. A few lines of Markdown give you a slash command. A short instruction file gives the model a procedure it reaches for on its own. Lisp gives you tools the model calls, interface changes, and behavior that fires on events. Lisp is the native floor you can always reach, the same kind of object kli itself is built from, not a last resort you fall back to. This page says what each altitude can and cannot do, so you pick by what the task needs.

Prompt templates

A prompt template is a Markdown file that becomes a slash command. The file's name is the command name, and its body is the text sent to the model when you run it. Drop review.md in ~/.config/kli/prompts/ (every session) or <project>/.kli/prompts/ (one project), and /review types its body into the conversation as your message.

The body is a template, not a fixed string. Placeholders fill in from what you type after the command: $1 and $2 for positional arguments, ${@:2} for everything from the second word on, $ARGUMENTS for the whole line. A frontmatter description and argument-hint show up in command listings. That is the entire feature.

Reach for a prompt template when you keep retyping the same instruction. A code-review prompt, a commit-message format, a "explain this file" request with your house conventions: anything you would otherwise paste from a notes file. You decide when it runs, because you type the command.

What it cannot do: a template cannot run code, call a tool, read a file on its own, or decide for itself when to act. It is one message, expanded and sent. The model never sees the command itself, only the text it expands to. When you want the model to pull in a procedure without being told, the next altitude does that.

See Prompt Templates for the full placeholder syntax.

Skills

A skill is a SKILL.md file with a name and a description. The description is the load-bearing part: kli shows every skill's name and description to the model, and the model reads the skill's body itself, on its own initiative, when a task matches that description. You write the procedure once; the model decides when it applies.

That is the difference from a prompt template. A prompt template fires when you type its command. A skill fires when the model judges it relevant, so you do not have to remember it exists at the moment it would help. Put skills in ~/.config/kli/skills/<name>/SKILL.md for every session or <project>/.kli/skills/<name>/SKILL.md for one project. kli also discovers .agents/skills/ directories on the way up to the repository root, so skills you already keep for other agent tools are visible too.

A skill is still no code. The body is instructions: how to run a migration, the steps your test harness expects, the conventions a reviewer should apply. Files next to SKILL.md are referenced by relative path, and the model resolves them against the skill's own directory, so a skill can carry checklists, examples, or scripts the instructions point at. Skills can also be invoked deliberately, as a /skill:<name> command or by writing $name inside a prompt, and a skill marked disable-model-invocation: true is reachable only those ways and never offered to the model automatically.

Reach for a skill when the trigger is the task, not the keystroke: when you want a procedure followed whenever it fits, without you naming it each time. The work beyond a prompt template is writing a description sharp enough that the model loads the skill at the right moments and leaves it alone otherwise.

What it cannot do: a skill is still text the model reads. It cannot add a tool the model can call, change the terminal UI, bind a key, or run when an event happens. It can only describe what to do with the tools and commands kli already has.

See Skills for the SKILL.md format and discovery order.

Lisp extensions

A Lisp extension is code. It can add a tool the model calls, a slash command backed by a function, a theme, a keybinding, a status-bar widget, a handler that fires on an event like a tool call, or a new method on existing behavior. kli itself is built out of these contributions, and an extension you write is the same kind of object as the program's own parts.

Extensions load from ~/.config/kli/extensions/ and <project>/.kli/extensions/ as plain Lisp files, and /reload re-reads them into the running program. Because kli runs as one live image rather than a fixed binary, an extension installs into the program while it is running and retracts again without a restart. That is what lets you change a tool's behavior and try it in the same session, and it is why a contribution here is reversible rather than permanent: every contribution an extension adds carries a retractor that removes exactly what it installed. A command that replies with text is a handful of lines; you do not need the install/retract machinery in your head to write the first one.

Reach for a Lisp extension when Markdown hits its wall: you need the model to call something that does real work (hit an API, query a database, run a computation), you want behavior triggered by events rather than by the model or by you, or you want to change kli's interface, the themes, keys, and status line. It is the only altitude that adds capability rather than text, and it is where everything kli ships already lives.

Writing one is programming, in Common Lisp, against kli's extension vocabulary. The built-in creating-extensions skill walks through it, and the model can write an extension for you from a description, then reload and test it in the session with you.

See Lisp Extensions and The Live Image for how extensions install and retract.

Picking an altitude

Match the altitude to what the task needs:

  1. You retype the same instruction and want a command for it. Prompt template. Markdown, no code, fires when you type it.
  2. You want a procedure followed whenever a task fits, without naming it. Skill. Markdown plus a sharp description, no code, the model loads it on its own.
  3. You need a new tool, an event handler, or a change to the interface. Lisp extension. Code, installed live, the only altitude that adds capability.

The altitudes compose rather than rank. A project commonly carries a few prompt templates, a couple of skills, and one extension that adds the tool those skills tell the model to use. Pick the altitude that can do the job, and reach for more than one when the job spans them.