Продвинутые 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, а в том, сколько реальной информации ты ему дал.