Используй префикс ! для выполнения 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 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 |
| Меняющееся со временем состояние (текущий 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, а в том, сколько реальной информации ты ему дал.