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

# vetta skill

> Push and version skills.

Manage [skills](/docs/capabilities/skills) — persisted, versioned expertise loaded with progressive disclosure.

## Commands

| Command                            | Description                                                                 |
| ---------------------------------- | --------------------------------------------------------------------------- |
| `vetta skill push`                 | Create or update a skill from a `SKILL.md` file (new version), **by slug**. |
| `vetta skill push-version <skill>` | Push a new version of a skill that **already exists**, by id or slug.       |
| `vetta skill list`                 | List skills in the org.                                                     |
| `vetta skill show <slug>`          | Show a skill's current version.                                             |
| `vetta skill versions <slug>`      | List version history.                                                       |
| `vetta skill version <slug> <n>`   | One version, **including its content**.                                     |
| `vetta skill rm <slug>`            | Delete a skill.                                                             |
| `vetta skill catalog [slug]`       | The platform's published skills; with a slug, its latest `SKILL.md`.        |

## push

```bash theme={"system"}
vetta skill push --slug refund-policy --file ./skills/refund-policy/SKILL.md
```

Each push is content-addressed by a hash over the whole file, so an identical push is a no-op and any change creates a new immutable version.

```json theme={"system"}
{
  "slug": "refund-policy",
  "name": "refund-policy",
  "version": 3,
  "sha256": "b1946ac9...",
  "description": "How to evaluate and process customer refund requests within policy."
}
```

| Flag            | Description                                            |
| --------------- | ------------------------------------------------------ |
| `--slug`        | The skill's slug (required).                           |
| `--file`        | Path to the `SKILL.md` body. Defaults to `./SKILL.md`. |
| `--description` | Optional one-line description stored with the skill.   |

## push-version

`push` is addressed at a **slug** and creates the skill when that slug is unknown. `push-version` is addressed at a skill that **already exists** — by id or by slug — and answers `404 not_found` when it does not. A release pipeline pinned to a skill id wants this one, so a rename cannot silently mint a second skill.

```bash theme={"system"}
vetta skill push-version skl_2sm3cgp2c7yzz5vscfqyaasdfr --file ./skills/refund-policy/SKILL.md
vetta skill push-version --skill refund-policy --file ./skills/refund-policy/SKILL.md
```

```json theme={"system"}
{
  "version": 2,
  "sha256": "4b3e74d57ebbcb8a0af871b11de338f560f4db1cf42af70090b94275a6337381",
  "size_bytes": 23,
  "created_at": "2026-08-23T05:47:42.700Z",
  "id": "skl_2sm3cgp2c7yzz5vscfqyaasdfr",
  "slug": "parity-demo-d33"
}
```

| Flag      | Description                                                           |
| --------- | --------------------------------------------------------------------- |
| `--skill` | Skill id or slug. May also be given as the first positional argument. |
| `--file`  | Path to the `SKILL.md` body. Defaults to `./SKILL.md`.                |

An unknown skill is a hard error rather than a create — that is the entire difference from `push`:

```
error: not_found: no such skill: skl_does_not_exist_xxxxxxxxx (req_4dbetv5ejeyjvkyt2f3ktpay9x)
```

The same operation is [`client.skills.pushVersion`](/docs/sdk/typescript#method-index) in the SDK and `POST /v1/skills/{id}/versions` in the [API reference](/docs/api/skills).

## Attaching to an agent

Skills are referenced on the agent by slug. A **bare slug floats** to the latest version at session start; a **`slug@N` reference pins** an immutable version that never moves when someone pushes a new `SKILL.md`:

```bash theme={"system"}
vetta agent create --name Refunder --model zai-org/GLM-5.2-FP8 \
  --skill refund-policy@3 --skill escalation-matrix \
  --budget-usd 50 --max-task-usd 5 --budget-period month
```

Here `refund-policy@3` is frozen to version 3 for reproducibility, while `escalation-matrix` resolves to the latest version at session start. Use `vetta skill versions <slug>` to see the pinnable version numbers.

A `naive/` prefix names the platform catalogue instead of your organization's skills: `naive/landing-page-copy` floats and `naive/landing-page-copy@1` pins, with the same rules. Your own `landing-page-copy` and the platform's never collide.

## catalog

The platform publishes a small catalogue of skills any agent can reference as `naive/<slug>`. Without a slug, `catalog` lists the newest version of each; `--tag` narrows it to one family (`agency`, `seo`, `media`, …) and `--search` is free text over the slug, name and description.

```bash theme={"system"}
vetta skill catalog --tag seo
```

```json theme={"system"}
{
  "object": "list",
  "data": [
    {
      "object": "skill_catalog_entry",
      "slug": "seo-content-brief",
      "version": 1,
      "name": "SEO content brief",
      "description": "Turn a target query into a brief a writer can execute: intent, audience, outline, entities, links, length.",
      "tags": ["seo", "content"],
      "content_hash": "3f1a…",
      "published_at": "2026-09-08T00:00:00.000Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}
```

With a slug it prints the latest version **including its content** — the text a floating `naive/<slug>` ref hands an agent today. The `version` in the answer is the number to pin.

```bash theme={"system"}
vetta skill catalog seo-content-brief
```

| Flag                 | Description                                |
| -------------------- | ------------------------------------------ |
| `--tag`              | Only skills carrying this tag.             |
| `--search`           | Free text over slug, name and description. |
| `--limit`, `--after` | Cursor pagination over the list.           |

The same reads are [`client.skills.catalog.list()`, `client.skills.catalog.get()` and `client.skills.catalog.retrieve()`](/docs/sdk/skills) in the SDK and `GET /v1/skills/catalog` in the [API reference](/docs/api/skills#the-platform-catalogue).

## version

`vetta skill versions` lists the version numbers; `vetta skill version` returns one of them in full,
and it is the only command that returns the skill's **content**. That split is deliberate — a
history listing stays small no matter how large the skills are.

```bash theme={"system"}
vetta skill version parity-demo-27e5fc9d 1
```

```json theme={"system"}
{
  "id": "skl_sn4ajzazpade2v1hj4gmkyerpe",
  "slug": "parity-demo-27e5fc9d",
  "version": 1,
  "sha256": "5f22eb6cabbfe6b898548754a4da28d7e6d4e54d53a80780088d28662fe4869f",
  "size_bytes": 14,
  "created_at": "2026-08-23T00:43:41.571Z",
  "content": "# Demo\nfirst.\n"
}
```

The `sha256` is over the content exactly as stored, so a pin of `slug@N` is reproducible: re-pushing
identical bytes is a no-op and mints no new version.
