# Skills

> Instructions the model loads only when a task needs them. Built-in skills, your own, and the SKILL.md format.

A skill is a directory with a `SKILL.md` file: a name, a one-line description
of when to use it, and Markdown instructions. The system prompt carries only
the name and description. When a task matches, the model runs
`shelley skill cat <name>` to read the instructions, so a long skill costs
nothing until it's needed.

Shelley implements the [Agent Skills](https://agentskills.io) format and also
reads the shared `~/.agents/skills` and `~/.config/agents/skills` directories.

## Built-in skills

These are compiled into the binary. `shelley skill ls` lists what you have.

| Skill | What it's for |
|---|---|
| `commit-tour` | Writing a [commit tour](/docs/commit-tours): a narrated walkthrough of a commit, stored as a git note. |
| `customizing-shelley` | Changing Shelley's own code or UI, and upgrading a customized build. See [Self-modifying Shelley](/docs/self-modifying). |
| `excalidraw` | Hand-drawn-style diagrams rendered from Excalidraw JSON. |
| `mcp` | Using [MCP servers](/docs/mcp) through `shelley mcp`. |
| `node-and-js-frameworks` | Installing Node, and dev-server trouble (WebSockets, allowed hosts) on exe.dev VMs. |
| `previous-conversations` | Looking up earlier conversations, including subagents'. |
| `schedule` | Reminders, recurring tasks, and waking a conversation later. |
| `shelley-hooks` | Writing [hooks](/docs/hooks). |
| `reflection-integration` | exe.dev only: discovering the VM's integrations and metadata. |
| `suggesting-exe-dev-actions` | exe.dev only: offering exe.dev action links. |
| `transcribing-audio` | exe.dev only: speech-to-text. |

The last three have `when: exe.dev` and stay out of the system prompt anywhere
else. The sources are in
[skills/builtin](https://github.com/boldsoftware/shelley/tree/main/skills/builtin).

## Writing your own

```sh
shelley skill new deploy-checklist
```

This creates `~/.config/shelley/deploy-checklist/SKILL.md` from a template and
prints its path. Edit it:

```markdown
---
name: deploy-checklist
description: Use when the user asks to deploy, release, or ship to production.
---

1. Run `make test`. Stop if anything fails.
2. Tag the release: `git tag vX.Y.Z` (ask which version).
3. Run `./scripts/deploy.sh prod` and watch for the health check.
4. Post the tag and the deploy log URL to the user.
```

The description does the work: it's all the model sees until it decides to
load the skill, so say *when* to use it, not only what it is.

### Front matter

| Field | Required | Notes |
|---|---|---|
| `name` | yes | Must equal the directory name. 1-64 characters: lowercase letters, digits, hyphens; no leading, trailing, or doubled hyphens. |
| `description` | yes | Up to 1024 characters. |
| `when` | no | `exe.dev` limits the skill to exe.dev VMs. Any other value hides the skill everywhere. |
| `license`, `compatibility`, `allowed-tools`, `metadata` | no | Parsed and shown in the UI's system prompt view; they don't change behavior. `compatibility` is limited to 500 characters. |

A `SKILL.md` that doesn't parse, or whose `name` doesn't match its directory,
is left out. `shelley skill cat <name>` usually shows the parse error.

`shelley skill cat` prints `SKILL.md` and nothing else. If your skill comes
with scripts, refer to them by absolute path.

## Where skills live

Shelley looks in these places, in order, and the first skill found with a
given name is the one `shelley skill cat` loads. Later ones are left out of
the prompt, with one wrinkle: duplicates within places 1-5 are all listed,
each with its own description, though they all load the first. Give your
skills distinct names.

1. `~/.config/shelley/<name>/SKILL.md`
2. `~/.config/agents/skills/<name>/SKILL.md`
3. `~/.agents/skills/<name>/SKILL.md`
4. `~/.shelley/<name>/SKILL.md`
5. `.skills/<name>/SKILL.md` in the working directory and each parent, up to
   the git root (or `/` outside a repository).
6. Any `<name>/SKILL.md` in the project tree: the git root, or the working
   directory outside a repository. Hidden directories, `node_modules`, and
   `vendor` are skipped, and the walk stops after two seconds. Outside a
   repository that can be a lot: a conversation started in `~` can pick up
   skills from the projects under it.
7. On exe.dev VMs, skills provided by the VM's integrations.
8. Built-in skills.

`skill.md` works as well as `SKILL.md`.

To switch off a built-in skill, shadow it with an empty file:

```sh
mkdir -p ~/.config/shelley/excalidraw
: > ~/.config/shelley/excalidraw/SKILL.md
```

It disappears from the prompt, and `shelley skill cat excalidraw` says
`skill "excalidraw" is disabled`.

## How skills reach the model

When a conversation starts, Shelley adds a `<skills>` block to the system
prompt listing each skill's name, description, and activation command
(`shelley skill cat <name>`; for exe.dev integration skills, a `curl` of
the skill's URL). Subagents get the same list.

The model loads a skill by running that command with its bash tool, in the
conversation's working directory. Two consequences:

- **`shelley` must be on the `PATH` that Shelley runs with.** Otherwise the
  activation command fails with `shelley: command not found`, and skills
  (MCP too) quietly stop working.
- **Timing.** The list is fixed when the conversation starts; a new skill, or a
  new description, shows up in the next conversation (or after `/clear` or
  `/compact`, which rebuild the system prompt). The body is read at
  activation, so edits to the instructions take effect right away.

## Commands

None of the `skill` subcommands take flags; `-h` is not help here.

| Command | Does |
|---|---|
| `shelley skill ls` | Lists every skill visible from the current directory, except integration skills, as `name<TAB>description`. Skills with a `when:` show it as a prefix, e.g. `[when: exe.dev]`; `ls` doesn't filter them out. |
| `shelley skill cat NAME` | Prints the skill's `SKILL.md`, front matter included, using the lookup order above. |
| `shelley skill new NAME` | Creates `~/.config/shelley/NAME/SKILL.md` from a template and prints the path. Refuses if it already exists. |

The code is in [skills/skills.go](https://github.com/boldsoftware/shelley/blob/main/skills/skills.go).
