# Тестируем и публикуем плагин

Курс: Claude Code: уровень профи — https://zero2claude.ru/learn/claude-code-pro
Канонический URL: https://zero2claude.ru/learn/claude-code-pro/6-2-test-i-publikaciya-plagina

claude plugin validate проверяет файлы плагина, claude plugin eval — его поведение, сравнивая прогоны с плагином и без. Публикация — это marketplace.json в git-репозитории, а новая версия доходит до пользователей, только когда ты поднимаешь version.

В уровне про плагины ты их ставил. Теперь — обратная сторона: выпустить свой так, чтобы ему можно было доверять. Проверка идёт двумя способами, а публикация оказывается проще, чем кажется.

## Две проверки

`claude plugin validate` читает **файлы**: манифесты и frontmatter. С `--strict` даже предупреждение роняет проверку.

```bash
claude plugin validate --strict ./plugins/commit-helper
claude plugin validate --strict .
```

Проверяй и плагин, и маркетплейс: проверка маркетплейса смотрит его файл и `plugin.json` каждого плагина, но в файлы навыков не заглядывает.

`claude plugin eval` меряет **поведение**. Каждый кейс — запрос плюс грейдеры, проверки, которые оценивают прогон. Кейс запускается в свежей изолированной сессии, где загружен только твой плагин: по умолчанию три раза с ним (ветка WITH) и столько же без него (W/OUT). Разница их оценок — **Δ**, вклад самого плагина.

## Первый кейс

```bash
cd plugins/commit-helper
claude plugin eval init --bare names-the-rename
```

`--bare` ничего не запускает: создаёт `prompt.md` и заготовку `graders/criteria.md` — рубрику для модели-судьи. Её обычно заменяют бесплатными проверками.

`prompt.md` — запрос с frontmatter:

```markdown
---
max_turns: 10
allowed_tools: [Skill]
---

Write me a commit message for this change: I renamed getUser to fetchUser and updated the three call sites.
```

Прогон получает только перечисленные инструменты, поэтому `allowed_tools: [Skill]` и даёт Claude запустить навык. Две проверки в `graders/`:

```markdown
---
type: tool_used
tool: Skill
input_match: 'commit-message'
---
```

```markdown
---
type: regex
pattern: 'fetchUser'
---
```

Первая — «навык сработал», вторая — «в ответе есть факт из запроса». Формулировку Claude каждый раз пишет по-своему, поэтому regex ищет то, что дал запрос, а не конкретную фразу.

## Какие грейдеры бесплатные

| Грейдер | Цена |
|---|---|
| `regex`, `tool_used`, `tool_order`, `file_exists` | бесплатно |
| `llm`, `baseline` | вызов модели-судьи в каждом прогоне |

Хорошее правило: одна проверка на **результат** и одна на **шаги**. Судью оставь для того, что бесплатные проверки не видят.

## Прогон

Дешёвый пробный прогон — один раз, только с плагином, отчёт остаётся у тебя:

```bash
claude plugin eval . --runs 1 --ablation none --no-publish
```

Полный прогон с порогом:

```bash
claude plugin eval . --threshold 0.8 --no-publish
```

Без `--threshold` проваленным считается любой кейс ниже идеальной оценки. Результаты ложатся в `evals/results/` — их исключают из git, а сами кейсы коммитят.

Одна ловушка. Проверка «навык НЕ сработал на постороннем запросе» — это `tool_used` на `Skill` с `min: 0` и `max: 0`. Но в прогоне с двумя ветками грейдеры `tool_used` на `Skill` по умолчанию в счёт не идут: без плагина навыка нет. Чтобы проверка считалась, добавь `arm: both`.

## Публикация и релиз

Опубликовать — значит положить `.claude-plugin/marketplace.json` в git-репозиторий и запушить. Никаких форм заявки: кто может клонировать репозиторий, тот может и установить.

```bash
claude plugin marketplace add owner/claude-plugins
claude plugin install commit-helper@owner-plugins
```

Имя маркетплейса берётся из `marketplace.json`, а не из названия репозитория. Некоторые имена маркетплейсов зарезервированы — например, всё, что начинается с `claudeai-`.

Новый релиз: подними `version` в `plugin.json` (а в записи маркетплейса свою версию не задавай), запушь, и пользователь обновится командой:

```bash
claude plugin update commit-helper@owner-plugins
```

Она закончится фразой `Restart to apply changes.` Если пишет, что версия и так последняя, — новая `version` ещё не запушена.

Имя плагина считай постоянным: его ставят и настраивают как `имя@маркетплейс`, и переименованный плагин для всех — другой плагин. Для новой подписи есть `displayName`.

**Осторожно.** 
claude plugin eval запускает навыки, хуки и агенты плагина на твоей машине от твоего имени, и зелёный прогон ничего не говорит о безопасности. А хук или MCP-сервер, который ты добавишь в следующей версии, выполнится у каждого, кто обновится, с его правами. Прежде чем делать репозиторий маркетплейса публичным, прочитай в нём каждый файл. И помни: --max-cost-usd ограничивает оценку по прайс-листу, а не лимит твоего плана.
