Pular para o conteúdo
Zumkai

Slash commands: transformar processo em comando

Comando personalizado virou skill. O que muda: argumentos posicionais, injeção de contexto antes do agente ver, e empilhamento de até seis numa mensagem.

  • claude code
  • slash commands
Card com as três categorias de comando do Claude Code e a substituição de argumentos posicionais.
Sumário
  1. Três categorias que coexistem
  2. Do processo repetido ao comando
  3. Argumentos: três formas e um fallback
  4. Injeção de contexto: o que separa comando de prompt salvo
  5. Empilhamento: até seis numa mensagem
  6. Cinco comandos que valem construir
  7. Onde o comando mora define quem o tem
  8. O comando que funciona aqui e quebra lá
  9. Quando não virar comando
  10. Perguntas frequentes
  11. Fontes

Comando personalizado deixou de ser uma categoria separada. Ele virou skill.

Um arquivo em .claude/commands/deploy.md e uma skill em .claude/skills/deploy/SKILL.md criam o mesmo /deploy e funcionam do mesmo jeito. Se os dois existirem, a skill tem precedência.

O que sobrou de diferença é o que a skill ganha: uma pasta para arquivos de apoio, frontmatter que controla quem invoca, e a possibilidade de o agente carregar sozinho quando a tarefa for relevante.

Três categorias que coexistem

Ao digitar / você vê itens de origens diferentes, e a distinção importa quando algo não se comporta como esperado.

CategoriaO que éVocê pode alterar
Comando embutidoComportamento codificado na própria CLINão
Skill empacotadaPrompt que vem junto, marcado [Skill]Substituível por skill de mesmo nome
Comando personalizadoSkill que você escreveSim

Os embutidos são os que mexem no funcionamento da sessão: /model, /effort, /clear, /resume, /branch, /fork, /diff, /context, /compact, /permissions, /memory.

As empacotadas são prompts entregues ao Claude, exatamente como as suas: /batch, /code-review, /verify, /debug, /doctor, /deep-research. E como todas elas são skills, o agente pode carregá-las por conta própria sempre que a tarefa parecer relevante, sem você digitar barra nenhuma.

Há uma pegadinha de substituição que vale conhecer: uma skill sua com o mesmo nome substitui a empacotada, mas não os apelidos dela. Uma code-review sua no projeto substitui a /code-review embutida, e digitar o apelido nunca roda a sua.

A referência completa dos comandos cobre os 294 que existem hoje.

Do processo repetido ao comando

O gatilho para criar é o mesmo das skills: quando você digita a mesma sequência de instruções pela terceira vez.

1. Crie a pasta. O nome dela vira o comando:

bash
mkdir -p .claude/skills/revisar-pr

2. Escreva o SKILL.md:

md
---
name: revisar-pr
description: Revisa o PR atual seguindo o checklist do time
disable-model-invocation: true
---

Revise as mudanças do PR atual seguindo esta ordem:

1. Rode `git diff main...HEAD`
2. Cheque tratamento de erro em toda função que faz IO
3. Confirme que existe teste para cada caminho novo
4. Aponte valor hardcoded que deveria ser configuração

Devolva em três blocos: Crítico, Alerta e Sugestão.

O disable-model-invocation: true é a escolha que define o caráter: com ele, só você dispara. Sem ele, o agente pode carregar o comando sozinho quando julgar relevante.

A regra que uso: processo que muda o estado do mundo fica manual. Deploy, commit, migração, publicação. Análise e verificação podem ficar automáticas.

3. Teste com /revisar-pr.

Note que o campo name no frontmatter define só o rótulo exibido na listagem. O comando vem do nome da pasta — exceto em skill de plugin, onde o name define o último segmento.

Argumentos: três formas e um fallback

Tudo que vem depois do nome do comando chega como argumento, e você escolhe entre três formas de recebê-lo, com um comportamento de reserva para quando esquece de declarar qualquer uma delas.

A forma simples usa $ARGUMENTS, que recebe o texto inteiro:

md
Corrija a issue $ARGUMENTS do GitHub seguindo nossos padrões.

Rodando /corrigir-issue 123, o agente recebe "Corrija a issue 123 do GitHub...".

A forma posicional usa $ARGUMENTS[N] ou a abreviação $N:

md
Migre o componente $0 de $1 para $2.
Preserve todo o comportamento e os testes existentes.

Rodando /migrar-componente SearchBar React Vue, cada posição é substituída na ordem.

A forma nomeada troca $0 por $origem e depende de um campo de frontmatter. Ela aparece mais adiante, junto dos comandos que valem construir.

E há o fallback que evita frustração: se você invocar com argumentos e o corpo não tiver $ARGUMENTS, o Claude Code anexa ARGUMENTS: <o que você digitou> ao final do conteúdo. O agente vê o que você escreveu mesmo assim.

Esquecer o placeholder degrada a precisão. Não quebra o comando.

Injeção de contexto: o que separa comando de prompt salvo

Esta é a capacidade que muda a natureza da coisa.

A sintaxe !`comando` roda shell antes de o conteúdo ser enviado ao agente. A saída substitui o placeholder, então o agente recebe dado real, não a instrução de buscar o dado.

md
---
description: Resume as mudanças não commitadas e sinaliza riscos.
---

## Mudanças atuais

!`git diff HEAD`

## Instruções

Resuma em dois ou três bullets, depois liste os riscos que notar.

Compare com a alternativa sem injeção: você pediria "rode git diff e resuma", o agente gastaria um turno chamando a ferramenta, e só então começaria a análise. Com a injeção, o diff chega junto com a instrução.

O ganho é de turno e de precisão: o agente não pode "esquecer" de buscar o dado, nem buscar o dado errado.

Uma limitação documentada: esses comandos não rodam quando a skill vem sincronizada da sua conta no claude.ai. A injeção é recurso de corpo exclusivo do Claude Code.

O formato completo, incluindo o ciclo de vida do conteúdo, está em como escrever a sua primeira Agent Skill.

Empilhamento: até seis numa mensagem

Recurso pouco conhecido e bastante útil.

Você pode empilhar skills no começo de uma mensagem:

txt
/escrever-testes /corrigir-issue 123

As duas carregam, e o texto final (123) vira $ARGUMENTS para cada uma delas.

O limite é a primeira skill mais até cinco empilhadas depois. E há uma regra de parada que explica comportamento estranho: a expansão para no primeiro token que não é uma skill inline invocável pelo usuário.

Dois casos param a cadeia:

  • Skill que roda como subagente forkado, como /code-review
  • Skill cujos argumentos podem começar com barra, como /loop

Esse token e tudo depois dele viram o texto de argumento para as skills já expandidas.

Na prática: se você empilhar algo depois de /code-review, o que vier depois é tratado como argumento, não como comando. Não é bug — é a regra de parada funcionando.

Cinco comandos que valem construir

Não são exemplos de manual. São os padrões que aparecem em qualquer projeto e que se pagam já na segunda execução.

1. Contexto do estado atual. Injeta o que o agente precisaria buscar em três chamadas de ferramenta:

md
---
description: Situação do repositório agora — branch, diff e últimos commits.
---

Branch: !`git branch --show-current`
Mudanças: !`git status --short`
Últimos commits: !`git log --oneline -5`

Resuma em que ponto o trabalho está e o que parece pendente.

2. Revisão com o checklist do time. O valor não é o agente saber revisar — é ele revisar pelo seu critério, na mesma ordem, toda vez.

3. Preparação de release. Sequência que você faz na mão e sempre esquece um passo. Aqui o disable-model-invocation: true é obrigatório: muda estado do mundo.

4. Investigação de bug com dados já anexados. Injeta o log, o diff recente e a saída do teste antes de pedir o diagnóstico.

5. Tradução de convenção. Comando que aplica a convenção do projeto a um trecho colado, útil quando a convenção é longa demais para caber no CLAUDE.md.

Dois campos de frontmatter atacam o motivo mais comum de abandono: você lembra o nome do comando e esquece a ordem dos argumentos.

argument-hint mostra a assinatura no autocompletar. arguments vai além e dá nome a cada posição, liberando $componente no lugar de $0:

md
---
name: migrar-componente
description: Migra um componente de um framework para outro
argument-hint: "[componente] [origem] [destino]"
arguments: [componente, origem, destino]
---

Migre o $componente de $origem para $destino.
Preserve o comportamento e os testes existentes.

Os nomes mapeiam para as posições na ordem em que aparecem. O ganho é de leitura: seis meses depois, $origem continua dizendo o que é, e $1 não.

Sem nenhum dos dois, esquecer a ordem dos argumentos — que é o motivo mais comum para parar de usar um comando que você mesmo escreveu.

Onde o comando mora define quem o tem

Os mesmos escopos das skills, com uma precedência que surpreende.

EscopoCaminhoVale para
Pessoal~/.claude/skills/<nome>/Todos os seus projetos
Projeto.claude/skills/<nome>/Só este projeto, versionado
Plugin<plugin>/skills/<nome>/Onde o plugin estiver ativo

Pessoal sobrepõe projeto. Se você tem um /deploy pessoal e o time tem outro no repositório, o seu vence — o que é bom quando você quer sobrescrever, e confuso quando você esquece que criou.

Comandos de plugin escapam do conflito por usarem namespace plugin:comando. E ali o campo name do frontmatter define o último segmento do comando, ao contrário do que acontece em skill pessoal ou de projeto.

Quando o comportamento não bate com o esperado, a pergunta certa não é o que o comando faz, e sim qual dos comandos com esse nome está rodando.

O comando que funciona aqui e quebra lá

A maior parte dos campos de frontmatter é extensão do Claude Code, não da especificação aberta. Se o comando nunca sai do seu terminal, tanto faz. Se ele vai para o claude.ai, para a API de Skills ou para um pacote distribuído, só seis campos passam.

CampoOnde valePara que serve
name, description, license, compatibility, metadataEspecificação abertaIdentificação e catálogo
allowed-toolsEspecificação abertaFerramentas liberadas sem pedir permissão
argument-hint, arguments, disable-model-invocation, user-invocable, model, effort, context, paths, hooksSó Claude CodeControle de invocação, execução e escopo

O erro no upload é literal e fácil de reconhecer: Unexpected key(s) in SKILL.md frontmatter: argument-hint.

Recursos de corpo também não atravessam. A injeção !`comando` não funciona em chat do claude.ai nem via API, o que é a mesma limitação que aparece em skill sincronizada da sua conta.

A regra prática: comando de uso pessoal usa tudo. Comando que você pretende publicar nasce com os seis campos da especificação, e o resto entra como conteúdo do corpo.

Dois campos que vale conhecer antes de precisar deles.

allowed-tools libera ferramentas sem prompt de permissão, e a liberação expira na sua próxima mensagem. Combinado com ${CLAUDE_SKILL_DIR}, deixa o comando rodar um script que mora na pasta dele, independente de onde a skill esteja instalada:

md
---
description: Renderiza o preview com o script do time
allowed-tools: Bash(${CLAUDE_SKILL_DIR}/scripts/render.sh *)
---

paths limita a ativação automática por glob. Um comando de revisão de migração que só faz sentido em db/migrations/** para de disputar atenção no resto do projeto.

Quando não virar comando

Quatro situações em que criar o comando piora.

Quando o processo ainda está mudando. Comando cristaliza a sequência. Se você ainda está descobrindo a ordem certa, cristalizar cedo é criar dívida.

Quando ele precisa de garantia de execução. Comando é prompt entregue ao agente, e o agente pode desviar. Se algo tem que acontecer sempre, num ponto fixo do ciclo, o mecanismo é hook — que roda independentemente do que o modelo decidir.

Quando o corpo vai crescer muito. O conteúdo de uma skill invocada permanece no contexto pelo resto da sessão. Comando longo é custo recorrente. Material de referência extenso vai para arquivo de apoio na pasta, carregado sob demanda.

Quando é fato, não procedimento. Convenção que vale em toda tarefa pertence ao CLAUDE.md, não a um comando que você precisa lembrar de rodar.

O teste que resolve: você quer disparar isso, ou quer que valha sempre? Disparar é comando. Valer sempre é CLAUDE.md ou hook.

Perguntas frequentes

Devo usar .claude/commands/ ou .claude/skills/?

Skills, para conteúdo novo. Os arquivos em .claude/commands/ continuam funcionando e criam o mesmo comando, mas skills adicionam pasta para arquivos de apoio, frontmatter de controle de invocação e carregamento automático quando relevante. Se existirem os dois com o mesmo nome, a skill vence.

Como impeço que o agente dispare meu comando sozinho?

disable-model-invocation: true no frontmatter. Vale para o que muda estado — deploy, commit, migração. O inverso também existe: user-invocable: false esconde do menu / e deixa só o agente invocar, útil para conhecimento de fundo.

Por que o agente ignora meu comando quando descrevo a tarefa?

A description não está casando com o jeito que você pede as coisas. É por ela que o agente decide invocar. Se o YAML do frontmatter estiver malformado, o corpo carrega com metadados vazios: o comando funciona e não existe descrição para casar. Rode com --debug para ver o erro de parse.

Dá para passar argumento com espaço?

Os argumentos posicionais são separados por espaço, então $0, $1 e $2 pegam palavras individuais. Para texto livre com espaços, use $ARGUMENTS, que recebe tudo que vem depois do nome do comando.

Fontes

Verificado em 20 de agosto de 2026.

Gatilho de reavaliação: revisar quando (a) mudar o limite de seis skills empilhadas ou a regra de parada da expansão, (b) .claude/commands/ for descontinuado, ou (c) a sintaxe de substituição posicional mudar.

Leia também

Claude Code

Hooks: a única camada que garante

Um hook que nega bloqueia a ferramenta até com bypassPermissions. Hooks apertam restrição e nunca afrouxam, e é isso que os torna a camada de política.

  • claude code
  • hooks