Custom commands об'єднали зі Skills. Коли мігрувати на `.claude/skills/` і що отримуєш натомість.
Перші три статті повністю розібрали слеш-команди: від Markdown-файлу та ін'єкції через !команду до оркестрування через subagent і MCP. Нічого з цього не застаріло — але за лаштунками відбулося офіційне злиття: custom commands тепер входять до Skills.
Твій .claude/commands/review.md досі працює, /review так само доступний, змінювати нічого не треба. Але якщо хочеш, щоб команда обросла новими можливостями (кілька файлів, виконання у fork, автоматична активація за path), новий шлях — .claude/skills/review/SKILL.md. Ця стаття розʼясняє дві речі: як мігрувати і чи варто.
Обіцянка сумісності від розробників однозначна: .claude/commands/deploy.md та .claude/skills/deploy/SKILL.md обидва реєструються як /deploy і поводяться однаково. У разі колізії імен перемагають skills.
Мінімальні кроки:
cd .claude/commands
mkdir -p ../skills/review
mv review.md ../skills/review/SKILL.md
У вмісті файлу не треба змінювати жодного рядка. YAML frontmatter, !`команда`, @file, $ARGUMENTS — усе залишається сумісним.
Але якщо обмежитися лише цим, читач слушно запитає: а навіщо тоді взагалі мігрувати? Відповідь у тому, що в директорію skill можна покласти скільки завгодно файлів, а command — лише один.
SKILL.md — це точка входу, а в тій самій теці можна зберігати будь-які супутні файли. Уяви таку структуру:
.claude/skills/review/
├── SKILL.md # entry point, короткі інструкції + посилання
├── checklist.md # довгий чек-лист code review
├── examples/
│ └── good-diff.md # позитивний приклад
└── scripts/
└── lint.sh # скрипт, який може викликати SKILL.md
Всередині SKILL.md на них посилаються через відносний path:
Переглянь поточний diff за критеріями з [checklist.md](checklist.md).
Див. [examples/good-diff.md](examples/good-diff.md) для очікуваного формату виводу.
Ці допоміжні файли не потрапляють у context автоматично — Claude читає їх за потреби. Офіційна рекомендація: тримати SKILL.md у межах 500 рядків, а решту виносити в допоміжні файли.
disable-model-invocation: які skills запускаються лише вручнуЗа замовчуванням Claude може сам вирішити викликати відповідний skill, якщо бачить слушний момент. Для команд із побічними ефектами на кшталт /deploy, /commit, /send-email — це небезпечно: ти не хочеш, щоб він «задеплоїв, бо код йому сподобався».
---
name: deploy
description: Деплой у продакшн
disable-model-invocation: true
allowed-tools: Bash(kamal deploy:*), Bash(git push:*)
---
З цим рядком /deploy запускається лише вручну — у діалозі Claude не викличе його з власної ініціативи.
Навпаки, user-invocable: false означає «викликати може лише сам Claude, але в меню / цього skill немає» — підходить для skills-фонових знань (наприклад, legacy-system-context, який Claude автоматично завантажує в потрібних ситуаціях і викликати який вручну не має сенсу).
context: fork: запускати skill у subagentЦе найбільше оновлення. У попередній статті ми бачили, що command через allowed-tools: Task може попросити модель підняти subagent — але опис «підніми Explore subagent, щоб…» доводилося писати вручну у самому prompt.
У SKILL достатньо одного рядка frontmatter:
---
name: deep-research
description: Глибоке дослідження символу
context: fork
agent: Explore
---
Дослідь усі використання $ARGUMENTS:
- усі точки виклику
- бізнес-сценарії
- альтернативні реалізації
Поверни зведення ≤300 слів.
Коли ти запускаєш /deep-research SomeClass, увесь SKILL.md стає prompt'ом окремого subagent, виконується агентом типу Explore і наприкінці повертає лише висновок. Context основної розмови залишається повністю чистим.
Це перетворює «підняти subagent» із текстового опису в prompt на декларативний атрибут skill.
paths: автоматична активація за типом файлу---
name: rails-conventions
description: Кодові конвенції цього Rails-проєкту
paths: ["app/**/*.rb", "config/**/*.rb"]
---
Дотримуйся Rails-конвенцій проєкту:
- використовуй service object замість fat controller
- усі ActiveRecord scope мають бути іменованими
...
Коли ти редагуєш app/models/user.rb, цей skill автоматично додається в context; під час редагування package.json — ні. Точніше, ніж глобальне тло CLAUDE.md — фактично «CLAUDE.md, пошарований за path».
/plan до skillОстанній приклад /plan з попередньої статті був однофайловою command:
.claude/commands/plan.md
Версія як skill:
.claude/skills/plan/
├── SKILL.md
├── research-prompt.md # інструкції для subagent 1
└── risk-prompt.md # інструкції для subagent 2
SKILL.md:
---
name: plan
description: Сформувати план впровадження за Linear-тикетом
disable-model-invocation: true
allowed-tools: mcp__linear__*, Task, Read, Grep, Bash(git log:*)
---
## Context
@.claude/context/architecture.md
## Стан
!`git log --oneline -10`
## Завдання
Отримай опис і коментарі Linear-тикета $ARGUMENTS.
Через Task паралельно підніми два subagent:
1. Дослідження коду: prompt у [research-prompt.md](research-prompt.md)
2. Оцінка ризиків: prompt у [risk-prompt.md](risk-prompt.md)
Зведи обидва результати в: кроки впровадження + список ризиків + рекомендації щодо гранулярності commit.
Prompts двох subagent лежать в окремих файлах — їх можна правити, не чіпаючи SKILL.md. Сам skill залишається компактним, у межах 30 рядків, тоді як допоміжні файли за потреби можуть сягати й кількох сотень рядків кожен.
Якщо не хочеться самому оркеструвати subagents — можна піти радикальніше і кинути весь skill у fork, щоб агент Explore виконав усе одним заходом:
---
name: plan
context: fork
agent: Explore
allowed-tools: mcp__linear__*
---
/plan ENG-4213 → агент Explore в ізольованому context бере весь вміст SKILL.md як завдання → повертає лише фінальний план. Основна розмова залишається повністю чистою.
Не кожна command заслуговує на апгрейд. Залишатися в .claude/commands/ доречніше, коли:
Прості /commit, /pr-desc і подібні — frontmatter плюс кілька рядків prompt — у .claude/commands/ виглядають навіть наочніше. Офіційно обидві форми співіснують, і жодну не депрекейтять.
На сьогодні найохайніша організація .claude/:
.claude/
├── commands/ # легкі: один файл + простий prompt
│ ├── commit.md
│ └── pr-desc.md
├── skills/ # важкі: багато файлів / fork / контроль доступу
│ ├── plan/
│ │ ├── SKILL.md
│ │ ├── research-prompt.md
│ │ └── risk-prompt.md
│ ├── deploy/
│ │ └── SKILL.md # disable-model-invocation
│ └── rails-conventions/
│ └── SKILL.md # автоактивація через paths glob
└── context/
└── coding-standards.md
Не варто мігрувати все скопом. Сигнал до міграції: «ця command починає розпухати» — понад 200 рядків, хочеться винести документацію, хочеться запускати у subagent. Тоді й змінити path — справа кількох хвилин.
| Бажана можливість | commands/ |
skills/ |
|---|---|---|
| Шорткат-prompt в одному файлі | ✅ | ✅ |
!`команда` / @file / $ARGUMENTS |
✅ | ✅ |
Контроль доступу через allowed-tools |
✅ | ✅ |
| Допоміжні файли (посилання, scripts) | ❌ | ✅ |
disable-model-invocation проти хибних спрацьовувань |
❌ | ✅ |
Ізольований запуск через context: fork + agent: |
❌ | ✅ |
Автоактивація за paths: glob |
❌ | ✅ |
На перших трьох рядках commands і skills повністю еквівалентні; останні чотири — лише у skills. Береш те, що потрібно, решту не чіпаєш.
Офіційний вектор схиляється у бік skills, але обіцянка сумісності commands/ однозначна — це не «мігруй зараз або вимреш», а розширення «ось тобі нові можливості, без примусу». Розберись у відмінностях, мігруй за потреби і не женись за косметичною стрункістю.