$ sudo teach IT

Доработка вёрстки — это чек-лист. Отступы по единой шкале, цвета из токенов, все интерактивные состояния, фокус с клавиатуры, поведение на узком экране. Список каждый раз один и тот же, и именно поэтому его каждый раз выполняют наполовину: две трети пунктов помнишь, про фокус и disabled вспоминаешь на ревью.

Это классический кандидат в скиллы. Скилл хорош там, где нужна процедура, а не факт: последовательность проверок, которую надо выполнить целиком. В этом уроке мы соберём /polish-ui <путь-к-компоненту> и по дороге разберём вслух главное инженерное решение — форкать этот скилл или нет.

Что уже умеем / что добавим

Вы умеете создавать скилл, писать description, передавать аргументы, подмешивать вывод команд через !команда``, выносить материалы в соседние файлы, изолировать выполнение через context: fork и ставить чужие скиллы плагинами. Новых механизмов в этом уроке нет — есть одна задача, на которой всё это сходится вместе, и один непростой выбор.

Что вы узнаете в рамках статьи

  • Почему длинный чек-лист лучше живёт в скилле, чем в CLAUDE.md
  • Как принять путь к компоненту и что делать, если его не передали
  • Как вшить в скилл реальные дизайн-токены проекта и не обрушить вызов
  • Почему для скилла, который правит файлы, context: fork — спорное решение
  • Как проверить, что скилл даёт стабильный результат

Ключевые термины

  • Дизайн-токен — именованная переменная оформления (цвет, отступ, размер шрифта), заданная в одном месте и используемая вместо литерального значения.
  • Магическое число — захардкоженное значение в стилях (13px, #3b7ddd) вместо ссылки на токен.
  • Чек-лист скилла — тело SKILL.md, сформулированное как перечень проверок, действующих постоянно, а не как одноразовый сценарий.
  • Динамический контекст — вывод shell-команды, подставленный в тело скилла до отправки модели.

Почему это скилл, а не CLAUDE.md

Соблазн понятен: правила оформления — это же проектные договорённости, им место в CLAUDE.md. Но CLAUDE.md находится в контексте всегда, а полный чек-лист по вёрстке — это десятки строк, которые нужны раз в день. У скилла тело загружается только при вызове; в контексте постоянно висит лишь description. Правило простое: короткое и всегда актуальное — в CLAUDE.md, длинное и нужное по требованию — в скилл.

Первая версия выглядит так.

---
description: Доводит вёрстку компонента до стандартов проекта: токены, отступы, состояния, доступность, адаптивность. Используй, когда просят причесать или доработать дизайн компонента.
argument-hint: [путь-к-компоненту]
---

Приведите компонент `$0` к стандартам проекта. Проверьте каждый пункт:

1. Цвета, радиусы, тени, размеры шрифта — только из дизайн-токенов,
   никаких литеральных значений.
2. Отступы — по единой шкале проекта, произвольные значения недопустимы.
3. Типографика — из заданных стилей, без локальных `font-size`.
4. Состояния: `hover`, `focus`, `active`, `disabled` — описаны все.
5. Фокус виден с клавиатуры и не убран через `outline: none`.
6. Контраст текста к фону соответствует требованиям доступности.
7. На узком экране компонент не ломается и не даёт горизонтальной прокрутки.
8. Дублирующиеся и мёртвые правила удалены.

Если путь к компоненту не передан, попросите его и ничего не меняйте.

Последняя строка обязательна, и вот почему. $0 — индексный плейсхолдер, и если аргумента нет, он остаётся в тексте как есть: Claude увидит буквально символы $0 и начнёт гадать. С $ARGUMENTS было бы иначе — там подставится пустая строка, — но результат не лучше: скилл правит файлы, и «сам выбери компонент» здесь недопустимо. Явная инструкция закрывает оба случая.

Реальные токены вместо выдуманных

Пока Claude не видит вашего файла токенов, он их придумает: назовёт переменную --color-primary, когда у вас --brand-500. Подставим настоящие значения.

---
description: Доводит вёрстку компонента до стандартов проекта.
argument-hint: [путь-к-компоненту]
allowed-tools: Bash(cat src/styles/tokens.css), Bash(cat tailwind.config.js)
---

И в теле:

## Дизайн-токены проекта

!`cat src/styles/tokens.css || true`

Используйте только перечисленные выше переменные. Если подходящего
токена нет — не выдумывайте новый, отметьте это в отчёте.

Здесь два обязательных элемента. || true — потому что файла может не быть или он может переехать, а неуспешная внедрённая команда обрывает всю инвокацию скилла: Claude не увидит даже текста инструкций. И allowed-tools — потому что внедрённые команды никогда не спрашивают разрешение: если проверка разрешений не вернула «allow», вызов так же обрывается.

Гайдлайн — в соседний файл

Полный свод правил с примерами «до/после» в теле скилла — это повторяющаяся стоимость в токенах при каждом вызове. Документация советует держать SKILL.md короче 500 строк.

.claude/skills/polish-ui/
├── SKILL.md
├── guidelines.md
└── examples.md
## Дополнительные материалы

- Полный гайдлайн по вёрстке — [guidelines.md](guidelines.md)
- Примеры «до/после» — [examples.md](examples.md)

Имя команды берётся из имени директории, поэтому каталог обязан называться polish-ui. Кладите его в .claude/skills/ и коммитьте: дизайн-стандарты — командная договорённость.

Форкать или нет: разбор решения

Теперь главное. Задача объёмная: прочитать компонент, стили, токены, соседние компоненты для сверки. Всё это осядет в вашем разговоре. Аргумент за context: fork сильный.

Аргументы против сильнее. Первый: скилл правит файлы, а правки фонового форкнутого скилла применяются вне чекпоинтов сессии — /rewind их не откатит, откатывать придётся через git. Второй: фоновый форк работает с более узким набором инструментов, чем обычный ход, и шаги вашего скилла могут в этот набор не уложиться.

Вывод: если форкать, то так.

---
description: Доводит вёрстку компонента до стандартов проекта.
argument-hint: [путь-к-компоненту]
context: fork
agent: general-purpose
background: false
disable-model-invocation: true
allowed-tools: Bash(cat src/styles/tokens.css)
---

background: false возвращает результат в том же ходе и сохраняет полный набор инструментов. agent: general-purpose — а не Explore, потому что Explore и Plan пропускают CLAUDE.md, а скилл, пишущий код, должен видеть конвенции проекта. disable-model-invocation: true — потому что скилл меняет файлы, и момент запуска логично оставить за человеком; заодно описание уходит из контекста.

Проверка результата

Скилл не считается готовым, пока не проверен. Смотрите git diff до принятия правок — вы ищете подмену магических чисел на токены, а не переписывание разметки.

- padding: 13px 18px;
- color: #3b7ddd;
+ padding: var(--space-3) var(--space-4);
+ color: var(--brand-500);

И прогоните на двух-трёх разных компонентах. Один удачный запуск ничего не доказывает: стабильность видна только на разнотипных случаях — кнопке, форме, карточке.

Частые ошибки

  • Динамическая команда без || true. Отсутствующий файл токенов обрушит весь вызов, и Claude не получит даже чек-листа. Дописывайте || true везде, где файл может не найтись.
  • Ставка на индексный плейсхолдер без запасного варианта. Непереданный $0 остаётся в тексте буквально и уходит модели как мусор. Всегда пишите, что делать при пустом аргументе.
  • Фоновый форк для скилла, который правит файлы. Такие правки не откатываются через /rewind. Либо background: false, либо готовность откатывать через git.
  • Принимать правки не глядя. Скилл может «причесать» разметку шире, чем нужно. Diff перед принятием — обязательный шаг, а не формальность.

Наиболее частые вопросы

  • Почему не положить чек-лист в CLAUDE.md? — Он длинный и нужен редко, а CLAUDE.md в контексте всегда. Тело скилла загружается только при вызове.
  • $0 или $ARGUMENTS для пути? — Оба рабочие. Разница в поведении при отсутствии аргумента: $ARGUMENTS даст пустую строку, $0 останется литералом.
  • Зачем allowed-tools, если разрешения и так настроены? — Внедрённые команды не спрашивают разрешение: любой не-«allow» немедленно обрывает инвокацию. Предодобрение это исключает.
  • Можно ли форкнуть с background: true? — Технически да, но тогда правки уйдут вне чекпоинтов и /rewind их не вернёт.
  • Как понять, что скилл стабилен? — Результат воспроизводится на разнотипных компонентах, а diff содержит только ожидаемые замены.

Итоги

Глава закончена, и стоит оглянуться. Вы начали с вопроса, зачем скиллы вообще нужны, и собрали первый; научились передавать аргументы — целиком, по индексу и по имени; подтягивать в скилл живое состояние репозитория через внедрённые команды и делать это устойчиво; выносить объёмные материалы в соседние файлы; изолировать выполнение через context: fork и осознанно выбирать между фоном и ожиданием; ставить чужие скиллы через плагины. Сегодня всё это сошлось в одной задаче, где решение принималось не по инструкции, а по инженерным доводам — именно так это и выглядит в реальной работе.

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

На следующий урок