zot/docs/skills.md

119 lines
4.2 KiB
Markdown
Raw Permalink Normal View History

feat: skills — reusable instructions discovered from SKILL.md files A skill is a single SKILL.md file with a YAML frontmatter header, discovered from well-known directories at startup. Two integration points: 1. The system prompt gains a short manifest listing each skill's name + one-line description. Cheap (a few dozen tokens). 2. A built-in `skill` tool lets the model load any one skill's full body on demand and follow the instructions there. The on-demand-load model keeps token usage cheap: only the manifest goes into every request; the body is fetched as a tool result the one or two turns the model actually needs it. Discovery (priority order — first match wins per name): ./.zot/skills/<name>/SKILL.md project (native) $ZOT_HOME/skills/<name>/SKILL.md global (native) ./.claude/skills/<name>/SKILL.md project (claude-compat) ~/.claude/skills/<name>/SKILL.md global (claude-compat) ./.agents/skills/<name>/SKILL.md project (agent-compat) ~/.agents/skills/<name>/SKILL.md global (agent-compat) Compat paths are deliberate: any SKILL.md written for a related ecosystem works in zot unchanged. Frontmatter fields: name optional; defaults to directory name description required; shown in the system prompt allowed-tools optional list; informational (no enforcement) permissions optional per-tool patterns; informational allowed-tools and permissions are parsed but not enforced this version. They render in the body so the model can self-regulate. What landed: - internal/skills: discovery + frontmatter parsing (no yaml dep — hand-rolled subset for the limited shape skills use), the on- demand `skill` tool implementing core.Tool, system-prompt addendum, FindByName lookup helper. Real unit tests cover all five locations + dedup priority + parser corner cases. - internal/agent/build.go: Resolve discovers skills, registers the skill tool when at least one was found, appends the manifest to the system prompt's append list. Resolved gains a SkillTool field so the tui can read the live set. - internal/agent/modes/skills_dialog.go: /skills picker with two modes — list view (cursor + paging) and body view (markdown- rendered with scroll). Refreshes its snapshot each open via cfg.SkillSnapshot so edits to a SKILL.md during a session are reflected immediately. - /skills slash command + entry in slashCatalog. - examples/skills/code-review and examples/skills/test-fix as starter skills demonstrating procedural style + frontmatter. - docs/skills.md: full reference covering discovery, frontmatter, inspection, authoring tips, and ecosystem compat. End-to-end verified against the live anthropic backend: prompt: "What skills do you have available?" -> "- code-review\n- test-fix" prompt: "Use the skill tool to load the code-review skill, then summarize step 1." -> [tool_call] skill({"name":"code-review"}) -> [tool_result] body returned -> "Step 1 is to establish what changed by running git status..."
2026-04-19 14:32:30 +02:00
# zot skills
A skill is a reusable instruction set written as a single
`SKILL.md` file with a YAML frontmatter header. zot discovers skills
at startup and surfaces them to the model in two ways:
1. The system prompt gains a short manifest:
`Available skills: ... - code-review — Run a self-review pass...`
2. A built-in `skill` tool lets the model load any one skill's full
body on demand.
The on-demand-load model keeps token usage cheap: only the manifest
goes into every request; the body is fetched as a tool result the
one or two turns the model actually needs it.
## Anatomy
```markdown
---
name: code-review
description: Run a thorough self-review pass on a recent change.
allowed-tools: [read, bash]
permissions:
bash: ["git diff*", "git log*"]
---
# Code review
When asked to review code, ...
```
### Frontmatter fields
| field | required | purpose |
|---|---|---|
| `name` | optional | skill identifier; defaults to the directory name |
| `description` | required | one-line summary shown in the system prompt |
| `allowed-tools` | optional | list of tool names the skill is meant to use; informational |
| `permissions` | optional | per-tool patterns; informational |
`allowed-tools` and `permissions` are **parsed but not enforced** in
this version. They appear in the rendered skill body so the model can
see them and self-regulate. Future versions may enforce.
The body (everything after the second `---`) is plain markdown.
There's no template engine; the model sees what you write.
## Discovery
zot looks in these directories, in priority order, and registers the
first `SKILL.md` it finds for each unique name:
| location | scope |
|---|---|
| `./.zot/skills/<name>/SKILL.md` | project (native) |
| `$ZOT_HOME/skills/<name>/SKILL.md` | global (native) |
| `./.claude/skills/<name>/SKILL.md` | project (claude-compat) |
| `~/.claude/skills/<name>/SKILL.md` | global (claude-compat) |
| `./.agents/skills/<name>/SKILL.md` | project (agent-compat) |
| `~/.agents/skills/<name>/SKILL.md` | global (agent-compat) |
The compat paths are deliberate: a `SKILL.md` written for an existing
skill ecosystem works in zot unchanged. Drop your existing
`.claude/skills/` or `.agents/skills/` directories into a project and
zot will pick them up.
`$ZOT_HOME` defaults to `~/Library/Application Support/zot/` on macOS,
`$XDG_STATE_HOME/zot` on Linux, `%LOCALAPPDATA%\zot` on Windows.
## Inspecting installed skills
In zot, run `/skills`. A picker lists every discovered skill with its
description and source path. Press enter on a row to view the full
body inline. Press esc to go back.
## How the model uses a skill
1. The system prompt tells the model that skills exist and what
their names + descriptions are.
2. The model recognises a request that maps to a known skill and
calls the `skill` tool with `name: "<skill-name>"`.
3. The `skill` tool returns the markdown body as the tool result.
4. The model follows the body's instructions.
You can prompt the model directly to use a skill (e.g. "use the
code-review skill") but you don't have to — the descriptions in the
manifest are enough for it to choose on its own.
## Writing good skills
- **Be procedural.** Number steps. Tell the model what to do in what
order. Skills are habits, not knowledge dumps.
- **Be precise about boundaries.** "Stop after step 4" is more
effective than "don't go too far".
- **Trim aggressively.** A 200-line skill bloats every turn the
model uses it. Aim for 2080 lines.
- **One skill per behaviour.** Don't pack three workflows into one
SKILL.md; the model picks one path. Two separate skills work better.
- **Lead with the trigger.** First paragraph should make it
obvious *when* to use the skill so the model self-selects correctly.
## Examples
See `examples/skills/` for two starter skills:
- `code-review/` — self-review pass on a recent diff
- `test-fix/` — diagnose + minimally fix a failing test
## Comparison to other discovery layouts
| ecosystem | path | zot reads it? |
|---|---|---|
| (native) | `.zot/skills/<name>/SKILL.md` | yes |
| (claude-style) | `.claude/skills/<name>/SKILL.md` | yes |
| (agent-style) | `.agents/skills/<name>/SKILL.md` | yes |
Cross-pollination is intentional: pick whichever convention you're
already using and zot tags along.