Slash Commands avançados: faça seus comandos entenderem o contexto

Use o prefixo ! para executar comandos shell dentro de slash commands, injetando automaticamente diffs, conteúdo de arquivos e resultados de testes


A maioria dos slash commands tem esta cara:

Revise a qualidade do código das mudanças atuais e dê sugestões concretas.

Funciona, mas tem uma limitação de fundo: o Claude precisa deduzir sozinho "quais são as mudanças atuais". Se o seu command injetar esse contexto por conta própria, o resultado muda completamente.

Este artigo fala sobre como transformar um command em uma instrução "com olhos": ao ser disparado, ele lê arquivos, estado do git e informações do projeto, e enfia tudo isso no prompt para que o Claude não precise adivinhar.


O mecanismo central: !`comando` para injetar saída do shell

Slash commands customizados permitem embutir comandos de shell no prompt. A sintaxe: envolva o comando em backticks e coloque um ponto de exclamação na frente: !`comando`. Ao disparar o command, o comando é executado primeiro, a saída substitui o marcador e o Claude recebe o prompt já montado.

Este é o git diff atual:

!`git diff HEAD`

Revise essas mudanças, focando em erros de lógica e problemas de segurança.

Para comandos de várias linhas, use um bloco de código com cerca começando com ```!:

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

Quando você dispara /review, o que o Claude recebe de fato é:

Este é o git diff atual:

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
...

Revise essas mudanças, focando em erros de lógica e problemas de segurança.

Você não precisa copiar e colar nada. No instante em que o command dispara, o diff já está lá dentro.


Padrões úteis

Injetar o conteúdo do arquivo atual

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

Este é o conteúdo completo do arquivo atual:

!`cat $ARGUMENTS`

Encontre todos os possíveis problemas de performance neste arquivo, com o número da linha e como corrigir.

Uso: /perf app/models/order.rb

$ARGUMENTS recebe o caminho do arquivo e o cat injeta o conteúdo. O Claude vê o código real, não uma descrição vaga tipo "olhe o arquivo atual".

O allowed-tools no frontmatter pré-autoriza o comando cat, então ao disparar não aparece o diálogo de permissão. Sem essa linha, toda execução pede para você clicar em "permitir". Os exemplos a seguir precisam da mesma declaração.

Injetar o estado do git

Branch atual e estado das mudanças:

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

Com base nas informações acima, gere uma descrição de PR enxuta, contendo o conteúdo e a motivação das mudanças.

Este command /pr não precisa que você descreva "o que mudei": ele mesmo lê.

Injetar informações específicas do projeto

Stack técnico do projeto:

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

Estrutura atual do banco (tabelas principais):

!`head -100 db/schema.rb`

Com o contexto acima, escreva um script de migration para $ARGUMENTS seguindo as convenções do projeto.

Escreva as informações de fundo do projeto antes no diretório .claude/context/ e deixe o command ler sob demanda quando disparar. Assim você não precisa repetir a descrição do projeto toda vez.

Ler resultados de testes dinamicamente

Resultado da última execução dos testes:

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

Acima estão os testes que falharam. Analise a causa raiz e proponha uma correção. Não altere os testes em si.

Ao disparar /fix-tests, os testes rodam e o resultado é capturado na hora; o Claude vê as mensagens de erro reais.


Exemplo completo: code review com consciência de contexto

Juntando tudo acima, o /review fica bem preciso:

---
description: Revisa as mudanças atuais, injetando automaticamente o diff e o contexto relevante
allowed-tools: Bash(git diff:*), Bash(cat:*)
---

## Mudanças desta rodada

!`git diff HEAD`

## Arquivos afetados

!`git diff HEAD --name-only`

## Resumo das convenções de código do projeto

!`cat .claude/context/coding-standards.md 2>/dev/null || echo "(sem arquivo de convenções)"`

---

Revise as mudanças acima:

1. Correção lógica: casos-limite não tratados, erros de lógica
2. Segurança: SQL injection, validação de permissão, vazamento de dados sensíveis
3. Aderência às convenções: se bate com o padrão do projeto
4. Legibilidade: nomes, comentários, estrutura

Para cada problema, informe arquivo, linha e sugestão concreta. Se não houver problemas, diga que não há; não encha linguiça.

Este command não exige nenhuma preparação: ao disparar, diff, lista de arquivos e convenções são injetados sozinhos.


Lidando com falhas de comando

Comandos de shell podem falhar (arquivo inexistente, comando fora do PATH, etc.). Use || para fornecer um valor default e evitar que o command trave:

!`git diff HEAD 2>/dev/null || echo "(sem mudanças no git ou fora de um repositório)"`
!`cat .env.example 2>/dev/null || echo "(sem arquivo .env.example)"`
!`which rspec > /dev/null 2>&1 && bundle exec rspec --dry-run 2>&1 | head -20 || echo "(RSpec não detectado)"`

Quando o comando falha, o Claude recebe um texto explicativo em vez de um vazio, e pode ajustar a resposta com base nisso.


Performance: não injete demais

Toda a saída dos comandos ! vai direto para o context window. Armadilhas comuns:

Não dê cat em um arquivo gigante

# Perigoso: pode injetar dezenas de milhares de linhas
!`cat db/schema.rb`

# Melhor: pegue só o que precisa
!`grep -A 5 "create_table \"orders\"" db/schema.rb`

Limite de linhas em arquivos de log

!`tail -50 log/development.log`

Trunque a saída dos testes

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

Quanto mais preciso o contexto, melhor a resposta do Claude. Jogar a base de código inteira lá dentro não o deixa mais esperto; só o perde no meio do ruído.


Divisão de trabalho com o CLAUDE.md

Pergunta recorrente: informação de fundo do projeto deve ir no CLAUDE.md ou ser injetada dinamicamente via !?

Critério:

Tipo de informação Onde vai
Contexto do projeto sempre necessário (stack, estrutura de diretórios, convenções) CLAUDE.md
Estado que muda com o tempo (diff atual, resultado de testes, conteúdo de arquivo) Injeção dinâmica com !
Contexto que só uma tarefa específica precisa (notas de design de um módulo) !cat sob demanda

CLAUDE.md é conhecimento de fundo persistente; ! é um snapshot instantâneo da tarefa. Os dois se complementam, não repita.


Um diretório .claude/commands/ completo

.claude/
├── commands/
│   ├── review.md        # Review: injeta diff + convenções
│   ├── test.md          # Escrever testes: injeta o arquivo alvo
│   ├── fix-tests.md     # Corrigir testes: injeta as falhas
│   ├── pr.md            # Descrição de PR: injeta git log + status
│   ├── explain.md       # Explicar código: injeta o conteúdo do arquivo
│   └── migrate.md       # Migrations: injeta fragmento do schema
├── context/
│   ├── stack.md         # Descrição do stack técnico
│   └── coding-standards.md  # Convenções de código
└── settings.json

O diretório context/ guarda arquivos de fundo estáticos para cada command ler sob demanda. Essa estrutura pode ser commitada no git direto e compartilhada com o time.


Comparativo de resultado

Command estático:

Revise as mudanças atuais do código.

O Claude precisa perguntar "onde estão as mudanças?" ou procurar sozinho; o resultado é inconsistente.

Command com consciência de contexto:

Aqui está o diff (com conteúdo real) e as convenções relevantes (com conteúdo real). Revise.

O Claude já parte para a análise. Responde com precisão, sem enrolação nem rodadas de confirmação.

A diferença não está na capacidade do Claude, mas em quanta informação real você entrega a ele.