Os custom commands se fundiram com Skills. Quando migrar para `.claude/skills/` e o que você ganha com isso.
Os três posts anteriores cobriram o uso completo de slash commands: do arquivo Markdown, passando pela injeção !command, até orquestrar subagents e MCP. Nada disso ficou obsoleto — mas a Anthropic fez uma fusão silenciosa nos bastidores: os custom commands foram absorvidos pelo Skills.
Seu .claude/commands/review.md ainda roda, /review continua funcionando, nada precisa mudar. Mas se você quer que o comando ganhe mais capacidades — múltiplos arquivos, execução em fork, ativação automática por path — o novo endereço é .claude/skills/review/SKILL.md. Este post responde duas perguntas: como migrar, e se vale a pena.
A promessa oficial de compatibilidade é explícita: .claude/commands/deploy.md e .claude/skills/deploy/SKILL.md são ambos registrados como /deploy, com comportamento idêntico. Se houver conflito de nome, skills ganha.
Passos mínimos:
cd .claude/commands
mkdir -p ../skills/review
mv review.md ../skills/review/SKILL.md
Nenhuma linha do arquivo precisa mudar. YAML frontmatter, !`command`, @file, $ARGUMENTS — tudo é compatível.
Mas se você parar aí, a pergunta óbvia aparece: então por que migrar? A resposta está no fato de que um diretório de skill pode abrigar vários arquivos, enquanto um command fica preso a apenas um.
SKILL.md é o ponto de entrada, e o mesmo diretório pode receber qualquer arquivo auxiliar. Imagina uma estrutura assim:
.claude/skills/review/
├── SKILL.md # entrada: instrução curta + referências
├── checklist.md # o checklist longo de code review
├── examples/
│ └── good-diff.md # exemplo positivo
└── scripts/
└── lint.sh # script que o SKILL.md pode chamar
Referencie por caminho relativo dentro do SKILL.md:
Revise o diff atual seguindo os padrões de [checklist.md](checklist.md).
Veja [examples/good-diff.md](examples/good-diff.md) para o formato esperado.
Esses arquivos auxiliares não entram no context automaticamente — Claude lê sob demanda. A recomendação oficial é manter o SKILL.md abaixo de 500 linhas e empurrar o resto para os arquivos de suporte.
disable-model-invocation: quais skills só você pode dispararPor padrão, Claude invoca qualquer skill quando acha o momento adequado. Isso é perigoso para comandos com efeitos colaterais — /deploy, /commit, /send-email. Você não quer que ele "achar o código bonito e sair deployando".
---
name: deploy
description: Deploy para produção
disable-model-invocation: true
allowed-tools: Bash(kamal deploy:*), Bash(git push:*)
---
Com essa linha, /deploy só dispara quando você digita. Claude não vai invocar por conta própria no meio da conversa.
O inverso é user-invocable: false — "só Claude pode invocar e isso não aparece no menu /". Serve para skills de conhecimento de fundo (tipo legacy-system-context: Claude carrega automaticamente em cenários relevantes, mas não faz sentido você chamar na mão).
context: fork: rodar o skill em um subagentEsse é o upgrade maior. No post anterior, vimos que um command pode usar allowed-tools: Task para o modelo subir subagents — mas você tinha que descrever no próprio prompt "sobe um subagent Explore para fazer...".
O skill resolve com uma linha de frontmatter:
---
name: deep-research
description: Investigação profunda sobre um símbolo
context: fork
agent: Explore
---
Investigue todos os usos de $ARGUMENTS:
- todos os pontos de chamada
- cenários de negócio
- implementações alternativas
Retorne um resumo de ≤300 palavras.
Ao disparar /deep-research SomeClass: o SKILL.md inteiro vira o prompt de um subagent independente, executado com o agent type Explore, e quando termina só volta a conclusão. O context da conversa principal fica completamente limpo.
É como transformar "subir um subagent" de uma descrição dentro do prompt em um atributo declarativo do skill.
paths: ativação automática por tipo de arquivo---
name: rails-conventions
description: Convenções de código do projeto Rails
paths: ["app/**/*.rb", "config/**/*.rb"]
---
Siga as convenções Rails deste projeto:
- use service object em vez de fat controller
- scopes de ActiveRecord precisam ter nome
...
Quando você está editando app/models/user.rb, esse skill é adicionado ao context automaticamente; quando edita package.json, não. Mais preciso do que o fundo global do CLAUDE.md — pense nisso como "um CLAUDE.md estratificado por path".
/plan para skillO exemplo de /plan do post anterior era originalmente um command de arquivo único:
.claude/commands/plan.md
Promovido a skill:
.claude/skills/plan/
├── SKILL.md
├── research-prompt.md # instruções do subagent 1
└── risk-prompt.md # instruções do subagent 2
SKILL.md:
---
name: plan
description: Gerar plano de implementação a partir de um ticket do Linear
disable-model-invocation: true
allowed-tools: mcp__linear__*, Task, Read, Grep, Bash(git log:*)
---
## Contexto
@.claude/context/architecture.md
## Estado
!`git log --oneline -10`
## Tarefa
Busque a descrição e comentários do ticket do Linear $ARGUMENTS.
Use Task para subir dois subagents em paralelo:
1. Pesquisa de código: prompt em [research-prompt.md](research-prompt.md)
2. Avaliação de riscos: prompt em [risk-prompt.md](risk-prompt.md)
Consolide os dois resultados e produza os passos de implementação + lista de riscos + sugestão de granularidade de commit.
Os prompts dos dois subagents ficam em arquivos separados, então você atualiza um sem precisar encostar no SKILL.md. O skill em si fica enxuto com menos de 30 linhas, e os arquivos auxiliares podem ter centenas de linhas cada.
Se não quiser orquestrar os subagents na mão, dá para ir mais fundo — jogar o skill inteiro num fork e deixar um agent Explore comer tudo de uma vez:
---
name: plan
context: fork
agent: Explore
allowed-tools: mcp__linear__*
---
Dispara /plan ENG-4213 → um agent Explore num context próprio recebe o SKILL.md inteiro como tarefa → só o plano final volta. A conversa principal fica imaculada.
Nem todo command merece um upgrade. Ficar em .claude/commands/ faz mais sentido quando:
Um /commit ou /pr-desc simples é só frontmatter + algumas linhas de prompt — colocar em .claude/commands/ é até mais direto. A Anthropic deixou explícito: as duas formas coexistem e nenhuma será descontinuada.
A organização mais limpa hoje em .claude/:
.claude/
├── commands/ # leve: arquivo único + prompt simples
│ ├── commit.md
│ └── pr-desc.md
├── skills/ # pesado: multi-arquivo / fork / controle de permissão
│ ├── plan/
│ │ ├── SKILL.md
│ │ ├── research-prompt.md
│ │ └── risk-prompt.md
│ ├── deploy/
│ │ └── SKILL.md # disable-model-invocation
│ └── rails-conventions/
│ └── SKILL.md # ativação automática via glob de paths
└── context/
└── coding-standards.md
Não migre tudo de uma vez. O gatilho da migração é "esse command começou a inchar" — o corpo passou de 200 linhas, precisa separar documentação, quer que um subagent execute. Quando esse dia chegar, trocar o path leva alguns minutos.
| Capacidade desejada | commands/ |
skills/ |
|---|---|---|
| Atalho de prompt em arquivo único | sim | sim |
!`command` / @file / $ARGUMENTS |
sim | sim |
Controle de permissão allowed-tools |
sim | sim |
| Arquivos de suporte (references, scripts) | não | sim |
disable-model-invocation contra disparos acidentais |
não | sim |
Execução isolada com context: fork + agent: |
não | sim |
Ativação automática por glob em paths: |
não | sim |
Nos três primeiros itens, commands e skills são equivalentes; os quatro últimos são exclusivos de skills. Use a forma que atende o que você precisa.
A direção oficial está pendendo para skills, mas a promessa de compatibilidade do commands/ é explícita — isso não é uma mudança de "migre agora ou vai virar poeira", é uma extensão de "novas capacidades ofertadas, sem imposição". Entenda a diferença, migre quando precisar e não persiga arrumação cosmética.