Просунуті Slash Commands: команди, що розуміють контекст

Використовуй префікс ! для виконання shell-команд усередині slash commands — автоматично підставляй diff, вміст файлів і результати тестів


Більшість slash commands виглядають приблизно так:

Перевір якість коду в поточних змінах і дай конкретні рекомендації.

Це працює, але є фундаментальне обмеження: Claude мусить сам здогадатися, що таке «поточні зміни». Якщо твій command активно інжектить контекст, результат змінюється кардинально.

У цій статті — про те, як перетворити команди на інструкції «із зором»: при спрацюванні вони автоматично читають вміст файлів, стан git та інформацію про проєкт, запихаючи це все в prompt, щоб Claude не доводилося гадати.


Ключовий механізм: !`команда` інжектить вивід Shell

Кастомні slash commands дозволяють вбудовувати shell-команди прямо в prompt. Синтаксис: команда береться в зворотні лапки й перед нею ставиться знак оклику — !`команда`. При спрацюванні команда виконується першою, її вивід підставляється замість плейсхолдера, і Claude отримує вже зібраний prompt.

Ось поточний git diff:

!`git diff HEAD`

Перевір ці зміни, звертаючи увагу на логічні помилки та проблеми безпеки.

Багаторядкові команди оформлюй огородженим блоком коду, що починається з ```!:

```!
node --version
git status --short
```

Коли спрацьовує /review, Claude фактично отримує ось що:

Ось поточний git diff:

diff --git a/app/models/user.rb b/app/models/user.rb
index 3a2f1c8..9b4e2d1 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -12,6 +12,9 @@ class User < ApplicationRecord
...

Перевір ці зміни, звертаючи увагу на логічні помилки та проблеми безпеки.

Жодного ручного копіювання: у момент спрацювання command diff уже всередині.


Практичні патерни

Інжект вмісту поточного файлу

---
allowed-tools: Bash(cat:*)
---

Ось повний вміст поточного файлу:

!`cat $ARGUMENTS`

Знайди всі потенційні проблеми продуктивності в цьому файлі. Вкажи конкретні номери рядків і способи виправлення.

Використання: /perf app/models/order.rb

$ARGUMENTS приймає шлях до файлу, cat читає вміст та інжектить його. Claude отримує реальний код, а не розмите «поглянь на поточний файл».

allowed-tools у frontmatter заздалегідь авторизує команду cat, і при спрацюванні запит дозволу не з'являється. Без цього рядка довелося б вручну натискати «Дозволити» при кожному запуску. Всі приклади нижче потребують такого ж оголошення.

Інжект стану git

Поточна гілка та стан змін:

!`git status --short`
!`git log --oneline -10`

На основі цієї інформації згенеруй короткий опис PR, що охоплює що змінилося і чому.

Цей /pr command не просить тебе описувати «що я змінив» — він сам іде й читає.

Інжект специфіки проєкту

Технологічний стек проєкту:

!`cat .claude/context/stack.md`

Поточна схема бази даних (ключові таблиці):

!`head -100 db/schema.rb`

З урахуванням цього контексту напиши скрипт міграції для $ARGUMENTS, що відповідає конвенціям проєкту.

Поклади фонову інформацію про проєкт у .claude/context/ заздалегідь, і command читатиме її за потреби при спрацюванні, без необхідності щоразу заново описувати проєкт.

Динамічне читання результатів тестів

Останній запуск тестів:

!`bundle exec rspec --format progress 2>&1 | tail -30`

Це тести, що впали. Проаналізуй першопричину та запропонуй виправлення. Самі тести не чіпай.

Коли спрацьовує /fix-tests, тести запускаються тут і зараз, а результат збирається на місці — Claude бачить справжні повідомлення про помилки.


Повний приклад: ревʼю коду з розумінням контексту

Якщо зібрати все це разом, /review може стати дійсно точним:

---
description: Ревʼю поточних змін з автоматичним інжектом diff і контексту
allowed-tools: Bash(git diff:*), Bash(cat:*)
---

## Поточні зміни

!`git diff HEAD`

## Список зачеплених файлів

!`git diff HEAD --name-only`

## Стандарти кодування проєкту

!`cat .claude/context/coding-standards.md 2>/dev/null || echo "(файлу стандартів немає)"`

---

Перевір наведені зміни:

1. Логічна коректність: необроблені граничні випадки, помилки в логіці
2. Безпека: SQL-інʼєкції, перевірки авторизації, витоки чутливих даних
3. Відповідність стандартам: чи дотримано стандартів кодування проєкту?
4. Читабельність: іменування, коментарі, структура

Для кожної проблеми вкажи імʼя файлу, номер рядка та конкретну рекомендацію. Якщо проблем немає — так і скажи, не вигадуй заради кількості.

Цей command не вимагає від тебе жодної підготовки — при спрацюванні diff, список файлів і стандарти кодування інжектяться автоматично.


Обробка відмов команд

Shell-команди можуть падати (файла немає, команди немає в PATH тощо). Використовуй ||, щоб дати значення за замовчуванням і не дозволити command перерватися:

!`git diff HEAD 2>/dev/null || echo "(немає git-змін або це не git-репозиторій)"`
!`cat .env.example 2>/dev/null || echo "(файлу .env.example немає)"`
!`which rspec > /dev/null 2>&1 && bundle exec rspec --dry-run 2>&1 | head -20 || echo "(RSpec не виявлено)"`

Коли команда падає, Claude отримує пояснювальний текст замість порожнечі й може скоригувати стратегію відповіді.


Міркування продуктивності: не інжектуй забагато

Весь вивід команд ! потрапляє у context window. Кілька типових пасток:

Не роби cat цілого великого файлу

# Небезпечно: може інжектнути десятки тисяч рядків
!`cat db/schema.rb`

# Краще: витягни лише потрібне
!`grep -A 5 "create_table \"orders\"" db/schema.rb`

Лог-файли — з обмеженням за кількістю рядків

!`tail -50 log/development.log`

Вивід тестів обрізай

!`bundle exec rspec 2>&1 | tail -40`

Чим точніший контекст, тим кращі відповіді Claude. Якщо запхати в нього всю кодову базу, він не стане розумнішим — просто загубиться в шумі.


Розподіл праці з CLAUDE.md

Часте питання: фонову інформацію про проєкт класти в CLAUDE.md чи інжектити динамічно через !?

Критерій:

Тип інформації Куди
Постійно потрібний контекст проєкту (стек, структура каталогів, конвенції) CLAUDE.md
Стан, що змінюється з часом (поточний diff, результати тестів, вміст файлів) Динамічний інжект через !
Контекст під конкретне завдання (документація з дизайну конкретного модуля) !cat на вимогу

CLAUDE.md — це сталі фонові знання, ! — миттєвий знімок на момент завдання. Вони доповнюють одне одного — не дублюй.


Повний каталог .claude/commands/

.claude/
├── commands/
│   ├── review.md        # Ревʼю: інжектить diff + стандарти
│   ├── test.md          # Написання тестів: інжектить цільовий файл
│   ├── fix-tests.md     # Полагодження тестів: інжектить упалі результати
│   ├── pr.md            # Опис PR: інжектить git log + status
│   ├── explain.md       # Пояснення коду: інжектить вміст файлу
│   └── migrate.md       # Написання міграцій: інжектить фрагмент schema
├── context/
│   ├── stack.md         # Опис стеку
│   └── coding-standards.md  # Стандарти кодування
└── settings.json

У каталозі context/ лежать статичні фонові файли, які окремі command читають за потреби. Цю структуру можна одразу комітити в git і ділитися з командою.


Різниця на практиці

Статичний command:

Перевір поточні зміни коду.

Claude спершу мусить запитати «де зміни?» або шукати сам — результат непередбачуваний.

Command з розумінням контексту:

Ось diff (зі справжнім вмістом), ось відповідні стандарти (зі справжнім вмістом), перевіряй.

Claude одразу переходить до аналізу. Точні відповіді, без води, без нескінченних уточнень.

Різниця не у можливостях Claude, а в тому, скільки реальної інформації ти йому дав.