> ## Documentation Index
> Fetch the complete documentation index at: https://to11.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Skills

> A skill is the second kind of prompt: a folder of files delivered to a developer's machine, versioned and released through the same engine that serves chat prompts.

A **skill** is the second kind of prompt. A chat prompt is handed to your application as messages; a skill is handed to a developer's machine as **files**, and the coding agent running there turns one into a message when it decides the skill is relevant.

Same storage, same versioning, same releases — different delivery.

## A skill is a folder, not a document

Every skill has an **entry document**, `SKILL.md`, and may have any number of reference files beside it:

```text theme={null}
incident-triage/
├── SKILL.md              the front door — what this skill is, and what to do
├── references/
│   ├── paging.md         the paging runbook
│   └── severity.md       how severity is decided
└── checklists/
    └── postmortem.md
```

Everything a skill needs travels with it, so a developer never receives a procedure that refers to a file they do not have. A markdown link between two of a skill's files keeps working after either file is renamed — the link is stored as a reference to the *file*, not to its name, and comes back pointing at whatever that file is called now.

Files are UTF‑8 text with `\n` line endings and no byte-order mark. A skill holds at most **128 files**, **512 KB** in any one file, and **4 MB** across all of them.

## It is a prompt, so this all works already

A skill reuses the prompt engine rather than sitting beside it. Everything the [prompt documentation](/docs/platform/prompts/overview) describes for versions, labels, releases and history is true for a skill, unchanged:

* **[Versions](/docs/platform/prompts/versions-and-releases#versioning-and-publishing)** — each stored version is an immutable snapshot of the whole file set.
* **[Releases](/docs/platform/prompts/versions-and-releases#releasing-to-environments)** — a skill reaches a machine when a label points at a version. Storing a version and releasing it are separate acts, so you can try a skill yourself before anyone else receives it.
* **[History and comparison](/docs/platform/prompts/versions-and-releases)** — version history and diffs work the same way. A renamed file reads as a rename, not as a file deleted and a different one added.

## What a skill does not have

A skill is delivered to disk and read by an agent. It is not an inference request, so it owns none of the fields that describe one — and a version that carries any of them is rejected rather than quietly ignored:

| Absent                               | Why                                                                                                                                   |
| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- |
| **Variables**                        | Nothing substitutes into a skill, so `{{ … }}` would reach the agent literally. Publishing a skill containing that syntax is refused. |
| **Model config**                     | No model, temperature or token limit: a skill does not make a request, so there is nothing to configure.                              |
| **Tool definitions and tool choice** | Request-level concerns. Which tools an agent may use is the developer's setting, on their own machine.                                |
| **Block roles**                      | A skill's blocks are files, not conversation turns.                                                                                   |
| **Block conditions**                 | A skill delivers its whole file set.                                                                                                  |

A skill's **description is required**, where a chat prompt's is optional. An agent decides whether a skill is relevant by reading it, so a skill without one is undiscoverable.

## The kind is permanent

A prompt's kind is chosen when it is created and never changes. A skill never becomes a chat prompt, and no chat prompt becomes a skill.

There is no converter, and there will not be one: the conversion is lossless in neither direction — chat to skill discards roles, conditions, tools and variables, and skill to chat discards filenames and references. A lossy conversion presented as a conversion produces silent data loss on published content. Choosing wrong means starting over.

One consequence worth knowing before you name a skill: a **slug identifies one prompt in a project whatever its kind**, so a project holding a `code-review` chat prompt cannot also hold a `code-review` skill. A skill's slug can be changed afterward; a chat prompt's cannot.

## Authoring, and where

In this release skills are **authored through the [to11 CLI](/docs/reference/cli)** and **read in the browser**. Writing one and storing it is [Creating skills](/docs/platform/prompts/creating-skills); receiving them on your own machine is [one `to11 init`](/docs/platform/prompts/receiving-skills). The dashboard lists skills, shows each file's content, compares versions, and releases them; it does not create or edit them — see [Reading a skill in the dashboard](#reading-a-skill-in-the-dashboard).

That is deliberate rather than unfinished: a skill is a folder on a developer's machine, and the tool that already has the folder is the one that should send it. Importing brings an existing skill onto the platform as it stands, without restructuring or rewriting it first.

## Reading a skill in the dashboard

A skill lives on the prompts list beside your chat prompts, with a **Skill**
badge on its row. The list shows chat prompts and skills together; the **Kind**
filter narrows it to one or the other.

Opening one shows its **files** where a chat prompt shows its editor:

* **The file list** is flat and shows each filename as stored, path included —
  `references/paging.md`, not a folder to expand. A skill's filenames *are*
  relative paths, so a tree would invent a structure the skill does not have.
  The entry document is first and marked `entry`.
* **The file content** is what a machine receives, unchanged: nothing is
  reflowed, re-indented or rewritten. `{{ … }}` never appears at all — a skill
  has no variables, so nothing would substitute into it, and publishing refuses
  the syntax rather than delivering it literally to an agent. A link to another
  of the skill's files opens that file.
* **The publication state** says which labels point at the version on screen,
  or that none do. Storing a version and releasing it are
  [separate acts](/docs/platform/prompts/versions-and-releases#releasing-a-skill), so
  a version you have just stored reaching nobody is the expected state, not a
  failed save.

**Comparing two versions** works as it does for a chat prompt, with filenames
as the rows. A file renamed between versions reads as one **renamed** row
carrying both names — and its content diff too, if the content changed in the
same version. A rename is not shown as a deletion beside an addition, because
that is the same picture a genuine deletion produces.

### Why there is no edit button

**The browser reads skills; the to11 CLI writes them.** Creating a skill,
changing a file, adding or removing one, renaming one and importing a folder
all happen through the CLI. There is no editor for a skill, and no route,
button or link reaches one — a half-working authoring surface is worse than
none, so the absence is deliberate rather than unfinished.

What you *can* do in the browser: read every file, compare versions, see what
is published, publish a version to a label, and archive the skill.

**New skill** on the prompts list opens a panel rather than an upload control,
because an upload control would imply the browser can create a skill. It hands
you the two things that happen outside the browser: `to11 init`, which
configures this machine, and a prompt to give your coding agent — writing a
skill is writing a folder of documents, which is what a coding agent is for.

The agent is a convenience, not the mechanism; the folder can equally be one
you wrote yourself. [Creating skills](/docs/platform/prompts/creating-skills) is the
procedure for both, and for
[releasing one](/docs/platform/prompts/versions-and-releases#releasing-a-skill),
which is what makes it reach anyone else.

## What a machine receives

The platform renders a skill into the files a machine writes, rather than serving raw content for a client to assemble. So a format fix ships once and reaches every machine on its next sync, and supporting another coding agent is work on the platform rather than a client release.

Every target receives the standards-only form today — the entry document's frontmatter carries a `name` and a `description`, and the files are as they were stored. That is the form every consumer accepts, so one render serves every agent.

## The endpoints behind it

These are control-plane endpoints on the to11 API, not the [gateway](/docs/reference/api) — the gateway serves inference, and a skill is never resolvable for inference. The to11 CLI calls them for you; they are listed because an API-first product's paths are part of its surface.

| Method  | Path                                                                           | Permission       | What it does                                                                                                                                                                                                                                                                                                                            |
| ------- | ------------------------------------------------------------------------------ | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `POST`  | `/v1/projects/:projectId/prompts`                                              | `prompt:create`  | Creates a definition. Send `kind: "skill"` and a description; omitting `kind` creates a chat prompt, as it always did. Creates **no** version.                                                                                                                                                                                          |
| `GET`   | `/v1/projects/:projectId/prompts`                                              | `prompt:read`    | Lists prompts. **Skills are excluded unless you ask** — pass `?kind=skill` or `?kind=chat,skill`. Each row carries its `kind`.                                                                                                                                                                                                          |
| `GET`   | `/v1/projects/:projectId/prompts/summary`                                      | `prompt:read`    | Counts for the directory's summary band — total, published, archived, active releases, rollbacks. Takes the same `?kind=` the listing does, and **excludes skills unless you ask**, so pass whichever kinds you listed and the counts describe the rows you got. The 24-hour fetch count is the one figure that is always project-wide. |
| `PATCH` | `/v1/projects/:projectId/prompts/:promptId`                                    | `prompt:update`  | A skill's `slug` may be changed here; a chat prompt's may not. A skill's description cannot be emptied.                                                                                                                                                                                                                                 |
| `POST`  | `/v1/projects/:projectId/prompts/:promptId/imports`                            | `prompt:create`  | Takes a folder — `{ slug, files: [{ filename, content }] }` — parses its frontmatter and links, and stores a version. Refuses a chat prompt.                                                                                                                                                                                            |
| `POST`  | `/v1/projects/:projectId/prompts/:promptId/versions`                           | `prompt:create`  | Stores a version whose `templateJson` is already structured as `{ files: [...] }`.                                                                                                                                                                                                                                                      |
| `PUT`   | `/v1/projects/:projectId/prompts/:promptId/labels/:label`                      | `prompt:publish` | Releases: moves a label to a version. The same act for both kinds.                                                                                                                                                                                                                                                                      |
| `POST`  | `/v1/projects/:projectId/prompts/by-slug/:slug/labels/:label/render`           | `prompt:read`    | Returns the file set. See [Rendering a skill](/docs/platform/prompts/rendering#rendering-a-skill).                                                                                                                                                                                                                                           |
| `POST`  | `/v1/projects/:projectId/prompts/by-slug/:slug/versions/:versionNumber/render` | `prompt:read`    | Returns the file set for one **named version**, whether or not a label publishes it — what an author has right after storing. Skills only; the answer carries no `releaseId` and no `label`, because there is no release.                                                                                                               |
| `GET`   | `/v1/projects/by-name/:organization/:workspace/:project`                       | `project:read`   | Resolves three names to a project id, so a configuration file can name `acme` and `sre/runbooks` instead of carrying an opaque id nobody can check by eye.                                                                                                                                                                              |

**No new permission exists for skills.** Every endpoint uses a scope that already existed — see [Roles & permissions](/docs/platform/roles-and-permissions).

**The whole folder is the truth on import.** A file present in the previous version and absent from an import is gone from the new one; that is the only way to remove a reference file. Frontmatter keys the platform does not recognize are dropped rather than rejected, so a skill written for one agent imports without being rewritten first. Every problem in a rejected import is reported at once, not one round trip at a time.

## Next steps

<CardGroup cols={2}>
  <Card title="Versions & releases" icon="git-branch" href="/docs/platform/prompts/versions-and-releases">
    Publishing a skill is moving a label — the same act as publishing a prompt.
  </Card>

  <Card title="Rendering prompts" icon="code" href="/docs/platform/prompts/rendering">
    What a render returns for each kind, and what a render target selects.
  </Card>

  <Card title="Roles & permissions" icon="shield" href="/docs/platform/roles-and-permissions">
    Which permission each skill operation carries.
  </Card>

  <Card title="API reference" icon="terminal" href="/docs/reference/api">
    The endpoints that create, import, render and compare a skill.
  </Card>
</CardGroup>
