- Peça ao Claude para escrever: descreva o que você quer em uma sessão do Claude Code
- Escreva você mesmo: siga o tutorial para aprender como o código de um mod funciona. Você não precisa de Node.js, um bundler ou uma etapa de compilação, porque o Claude Code carrega arquivos
.jse.tsdiretamente.
Mods requerem Claude Code v2.1.287 ou posterior. Em seu shell, execute
claude --version para verificar. Para ver se mods podem ser carregados para você, consulte Verificar se mods podem ser carregados.Peça ao Claude para um mod
Descreva o mod que você quer em uma sessão interativa do Claude Code, e Claude o escreve. Claude trabalha a partir de uma skill integrada chamadaplugin-authoring, que diz a ele onde escrever o mod, quais eventos e métodos sua versão tem, e como o mod é carregado. Claude pode carregar a skill quando você pede um mod, ou você pode carregá-la você mesmo executando /plugin-authoring no prompt do Claude Code.
O mod é executado assim que você o aprova, exceto em sessões onde um mod que Claude escreve não pode ser carregado.
1
Descreva o mod
Peça pelo mod com suas próprias palavras, por exemplo
make a mod that shows the current git branch above the prompt. Claude escreve o mod em um diretório próprio na pasta de mods da sessão, que é ~/.claude/dev-mods/ seguido pelo ID da sessão. O caminho completo de um mod se parece com ~/.claude/dev-mods/3f2a9c1e-5b7d-4e8a-9c21-6d0f4b8a7e13/git-branch/.Nos modos de permissão
default e acceptEdits, o Claude Code pergunta antes que Claude crie cada um dos arquivos do mod, porque ~/.claude é um caminho protegido. Aprove cada arquivo conforme ele aparecer.2
Aprove o mod
Quando Claude salva o primeiro arquivo, o Claude Code pergunta se deve ativar o hot reloading para a sessão. O hot reloading executa os mods que Claude escreve nesta sessão e pega cada mudança posterior.Escolha uma destas respostas:
- Enable for this session: os mods na pasta de mods da sessão são carregados quando a rodada termina, e recarregam no final de cada rodada que os altera. Sua resposta dura para a sessão, inclusive depois que você a retoma.
- Not now: nada é carregado por enquanto. Os arquivos permanecem onde Claude os escreveu, e os mods são carregados na próxima vez que essa sessão inicia. Para evitar que um mod seja carregado, delete seu diretório.
3
Verifique se o mod foi carregado
Execute
/plugin no prompt do Claude Code e pressione Tab até que a aba Installed seja selecionada. Ela lista o mod, e você pode desativá-lo lá.4
Experimente o mod
Use o que você pediu. Para o prompt de exemplo, o nome do branch atual aparece acima da caixa de prompt. Se o mod não fizer o que você queria, diga ao Claude o que mudar. O mod recarrega no final de cada rodada que altera seus arquivos, então você pode tentar a mudança assim que Claude terminar.
Use o mod em outras sessões
Um mod que Claude escreveu é carregado apenas na sessão que o criou, e o Claude Code deleta a pasta de mods dessa sessão uma vez que é mais antiga quecleanupPeriodDays. Para manter o mod, copie seu diretório para fora da pasta de mods para um lugar seu, como ~/mods/git-branch. Depois escolha como carregá-lo:
- Em uma sessão que você inicia: em seu shell, execute
claude --plugin-dir ~/mods/git-branch - Para outras pessoas: adicione-o a um marketplace para que possam instalá-lo
Sessões onde um mod que Claude escreve não pode ser carregado
Um mod que Claude escreve é carregado apenas depois que você o aprova, em um workspace confiável onde mods podem ser executados. Nestas sessões ele não é carregado:- Ninguém está lá para aprovar: a sessão não pode mostrar um prompt, como em uma execução
claude -pou mododontAsk - O workspace não é confiável: você não aceitou o prompt de confiança para o diretório
- Mods estão parados: você iniciou com
--safe-modeou--bare, você definiudisableAllHooks, ou as configurações gerenciadas da sua organização bloqueiam
Escreva um mod você mesmo
Neste tutorial você constrói um mod chamadofirst-mod que conta as chamadas de ferramentas que Claude faz, mostra a contagem ao lado do spinner enquanto Claude trabalha, e adiciona um comando /tally que a imprime. Você então lê as declarações de tipo que o Claude Code escreve ao lado do seu mod e executa claude plugin validate. Juntas elas mostram os eventos e métodos que sua versão oferece e o que o Claude Code lê do seu código.
Esta gravação mostra o mod finalizado. O spinner conta chamadas de ferramentas, /tally imprime a contagem, e uma edição no código entra em efeito enquanto a sessão é executada:
plugin.json: o manifest do pluginhooks.json: aponta para seu arquivo de códigoregister.js: seu código, chamado de hooks module
1
Crie o diretório do plugin
Crie os dois diretórios que contêm os arquivos:
- Bash ou Zsh
- PowerShell
2
Escreva o manifest
Um mod é um plugin, e um mod precisa de um manifest. O manifest deste mod não tem campos especiais. Salve isto como
first-mod/.claude-plugin/plugin.json:first-mod/.claude-plugin/plugin.json
3
Diga ao Claude Code onde seu código está
Quando o Claude Code carrega um plugin, ele lê o
hooks/hooks.json do plugin. A chave modules naquele arquivo dá o caminho para seu código, e tê-la é o que torna o plugin um mod. Liste um caminho, relativo a hooks.json. Aqui ele aponta para register.js, que você escreve no próximo passo.Salve isto como first-mod/hooks/hooks.json:first-mod/hooks/hooks.json
4
Escreva o código
Este arquivo é o código do mod, chamado de hooks module. Quando o mod é carregado, o Claude Code chama a função O arquivo mantém uma contagem em
register que o arquivo exporta e passa a ela uma função chamada on. Cada chamada a on registra um manipulador de evento, chamado de hook, para o evento que ele nomeia.Salve isto como first-mod/hooks/register.js:first-mod/hooks/register.js
calls e registra quatro hooks:session.starté executado quando a sessão inicia, antes do seu primeiro prompt, e novamente cada vez que o mod recarrega. Ele adiciona o comando/tallyao Claude Code.tool.callé executado cada vez que Claude está prestes a usar uma ferramenta. Ele adiciona um acallse pede ao Claude Code para desenhar a interface novamente.command.runé executado quando você digita/tally. Ele retorna o texto a ser impresso.ui.renderé executado cada vez que o Claude Code desenha o spinner. Ele adiciona a contagem após a palavra do spinner.
5
Carregue o mod
Inicie o Claude Code com a flag
--plugin-dir, que carrega um diretório de plugin para uma sessão sem instalá-lo:6
Experimente o mod
Peça ao Claude para fazer algo que leve algumas chamadas de ferramentas, como Se
list the files here and read the README. Enquanto Claude trabalha, a palavra do spinner é seguida por uma contagem que sobe, como em Thinking · tool calls: 2…. Quando Claude termina, digite /tally e pressione Enter. A transcrição mostra first-mod: Claude has made 2 tool calls since this mod loaded, com sua própria contagem. O Claude Code coloca o nome do plugin na frente do texto do comando.Para verificar o comando sem uma sessão interativa, execute-o em modo não interativo:/tally não estiver na lista de comandos, o módulo não foi carregado. Consulte Descubra por que um mod não faz nada.7
Altere o código enquanto a sessão é executada
Deixe a sessão aberta. Em Uma linha na transcrição diz que
register.js, altere ' · tool calls: ' para ' · tools used: ' no hook ui.render e salve. A linha destacada é a que muda:first-mod/hooks/register.js
first-mod recarregou e lista seus hooks, e o próximo spinner usa o novo texto, como em Thinking · tools used: 1….Como o mod de exemplo funciona
Cada função que você passa aon é um hook, que é um manipulador de evento. O Claude Code passa a cada hook os mesmos três argumentos:
- A API de mods, chamada
$: cada método que um mod pode chamar para alcançar fora de si mesmo, em namespaces como$.uie$.command - O evento, chamado
e: a entrada do evento como dados simples, como o nome e argumentos de uma chamada de ferramenta - O próximo manipulador, chamado
next: uma função que passa o evento para os outros mods e depois para o comportamento próprio do Claude Code, e retorna o resultado
first-mod lidam com seus eventos das três maneiras que um hook pode:
- Observar: o hook
session.startregistra o comando, e o hooktool.callconta a chamada e pede um redesenho. Ambos retornamnext(e), então a sessão inicia e a ferramenta é executada como usual. - Responder: o hook
command.runretorna seu próprio resultado e nunca chamanext. O segundo argumento aon,{ command: 'tally' }, é um filtro, chamado de matcher, então o hook é executado apenas para/tally. - Reescrever: o hook
ui.renderchamanextcom uma cópia deecujosuffixcontém a contagem, então o Claude Code desenha seu spinner usual com seu texto após a palavra
--plugin-dir e hot-recarrega o hooks module quando um arquivo nele muda. Cada recarga executa register novamente, então calls volta a 0 e /tally começa a contar novamente. Para manter um valor entre recargas, consulte Manter estado.
Continue trabalhando em um mod
Uma vez que um mod é carregado, você pode fazer Claude alterá-lo, verificar seu código contra as definições de tipo para sua versão, listar os eventos e chamadas que o Claude Code encontra nele, e testá-lo.Altere um mod com Claude
Para alterar um mod que você já tem, inicie a sessão com--plugin-dir apontado para o diretório do mod, para que o que Claude escreve seja carregado na mesma sessão:
add a /tally-reset command to this mod that sets the tally back to zero. Claude edita o hooks module, executa claude plugin validate, e corrige o que ele relata. Um diretório que você carrega com --plugin-dir é um caminho protegido, então nos modos default e acceptEdits você é solicitado a aprovar cada edição de Claude ao mod. A tabela de caminhos protegidos dá o resultado para os outros modos de permissão.
Os arquivos que Claude salva durante sua rodada recarregam quando a rodada termina, então você pode tentar /tally-reset assim que Claude terminar.
Obtenha definições de tipo para sua versão
Cada vez que o Claude Code carrega ou recarrega um mod de um diretório que você passa a--plugin-dir, ou um mod que Claude escreveu para você, ele escreve arquivos de declaração TypeScript, terminando em .d.ts, em .claude-plugin/types/ dentro do diretório do mod. Eles descrevem os eventos exatos, métodos da API de mods e elementos na versão do Claude Code que você está executando, então seu editor pode autocompletar e verificar tipos em seus hooks. Para navegar pelas declarações online, leia mods/types/claude-code.d.ts no repositório do Claude Code, cuja primeira linha nomeia a versão que a escreveu. O diretório contém estes arquivos:
Se seu mod não tem seu próprio
tsconfig.json, o Claude Code adiciona um na raiz do mod que estende o gerado, então seu editor e tsc -p ./first-mod verificam tipos do mod sem mais configuração.
Os eventos e métodos podem mudar entre releases, então confie nesses arquivos sobre qualquer página, inclusive esta, quando discordarem.
claude-code/index.d.ts é a referência mais completa para sua compilação, com um comentário e um exemplo para cada método da API de mods. Para procurar algo, pesquise o arquivo por seu nome, como 'tool.call'.
Verifique o que o Claude Code lê do seu mod
Para ver seu mod da maneira que o Claude Code o vê, sem executar seu código ou iniciar uma sessão, useclaude plugin validate. Ele verifica o manifest e executa a mesma análise estática no código-fonte do hooks module que o Claude Code executa quando carrega um mod. Em seu shell, execute-o no diretório do mod:
first-mod, a saída inclui estas linhas.
hooks: lista os eventos que seu módulo conecta, cada um com seu filtro entre chaves. A linha calls: lista cada método da API de mods que ele chama. Um módulo que lê ou define variáveis de ambiente também obtém linhas env reads: e env writes:, e um que usa $.state obtém state reads: e state writes:.
Se um evento que você pretendia conectar está faltando na primeira linha, o Claude Code não chamará esse hook também. A causa usual é um nome de evento digitado incorretamente, que o comando relata como um erro como "tool.calls" is not an event.
Siga estas regras para que a análise estática possa encontrar cada hook e chamada:
- Soletra cada chamada da API de mods completamente:
$, o namespace, depois o método, como em$.store.get('notes'). Você pode passar$para uma função declarada no nível superior do mesmo arquivo, e para uma função sua chamadaloadNotes, a linhacalls:então lê$.store.get (via loadNotes). Passar$para um método, uma função definida dentro do hook, ou uma função que você importa de outro de seus arquivos falha na validação. As funçõesreadeupdateque$.stateusa são as importações que podem levá-lo. Não atribua$ou um de seus namespaces a uma variável, desestruture-o, ou indexe-o com um nome computado.const ui = $.uifalha com$.ui is used as a value. - Escreva o nome do evento em cada chamada
oncomo um literal de string, como'tool.call'. Uma variável, ou um loop sobre uma lista de nomes, falha comthe event name passed to on() is not a string literal. - Dentro de
register, não declare uma segunda variável ou parâmetro chamadoon. A validação falha com"on" is declared again (shadowed). - Importe apenas de arquivos dentro do diretório do plugin, por caminho relativo. A única importação nua permitida é
claude-code, para tipos e alguns auxiliares. - Use declarações
importno topo do arquivo, como emimport { name } from './file.js'. Umimport()dinâmico falha coma dynamic import(); a hooks module imports its own files with an import declaration. - Escreva cada arquivo como um módulo ES, com
importe nãorequire. A referência lista as extensões de arquivo que o Claude Code carrega.
Teste o mod
Você pode escrever testes automatizados para um mod e executá-los de seu shell comclaude plugin test, sem sessão, sign-in ou rede. Um teste levanta os eventos que seus hooks lidam e verifica o que os hooks fizeram.
Este teste levanta duas chamadas de ferramentas, executa /tally, e verifica que a resposta conta ambas. Salve-o como first-mod/tests/first-mod.test.ts:
first-mod/tests/first-mod.test.ts
first-mod:
Compartilhe seu mod
Um mod é um plugin, então você o versiona no manifest e as pessoas o instalam e atualizam com os comandos/plugin. Para dá-lo a outras pessoas, adicione-o a um marketplace.
Antes de fazer isso, verifique o name do plugin: claude plugin validate falha em um nome que parece um dos próprios da Anthropic, como um que começa com claude-. Os eventos e métodos podem mudar entre releases, então seu README é o lugar para dizer qual versão do Claude Code você testou.
Continue desenvolvendo contra o diretório com --plugin-dir, não contra uma cópia instalada. O Claude Code armazena em cache um plugin instalado por versão, então suas edições não chegam à cópia instalada até que você aumente a versão e instale novamente.
Próximos passos
- Desenhe na interface: abra um painel, desenhe acima do prompt, e adicione botões e campos de texto
- Reaja a eventos: conecte chamadas de ferramentas, prompts e rodadas
- Use a API de mods: adicione comandos e ferramentas, chame um modelo, e execute trabalho em um temporizador
- Teste um mod: stub do que o Claude Code responderia, e teste temporizadores e desenhos
- Solucione problemas de um mod: as razões pelas quais um mod não faz nada, e o log de depuração
- Leia a fonte de mods integrados: plugins completos, cada um com seu hooks module e testes