TL;DR
- Um Mod do Claude Code são três arquivos:
.claude-plugin/plugin.json,hooks/hooks.jsoncom{"modules":["./index.ts"]}, e um módulo TypeScript que exportaregister(on). Não é preciso mais nada para carregá-lo. - Na build 2.1.272, a superfície tipada que o
/plugin-typesescreve tem 11,783 linhas declaude-code.d.ts: 84 nomes de eventos ou chamadas distribuídos em 23 substantivos.fs.readFilesumiu, o substantivo éfs.readefs.write. - Um hook
tool.callde 42 linhas fez o modelo lerAPI_KEY=[REDACTED]no lugar da chave real, tanto na ferramenta Read quanto na Bash, a 27.9 ms por salto saudável e cerca de 0 token adicionado à sessão. - Um hook que dorme além do orçamento de 10 s ou lança uma exceção é ignorado e o comando logo abaixo roda. O log avisa, mas o efeito é um bypass: um Mod de guarda falha aberto.
- O caminho gerado funciona: uma frase produziu um Mod de 190 linhas mais 53 linhas de testes em cerca de 4 minutos e $1.23, passando em
claude plugin validatesem avisos e emclaude plugin testcom 4 pass / 0 fail. - Uma coisa não se reproduziu: o Mod carregou com
claude -p, mas ficou mudo em um REPL interativo conduzido por pty, em duas tentativas. Trate o carregamento no REPL como não verificado até testar em um terminal de verdade.
O que as medições dizem
Tudo abaixo foi executado no Claude Code 2.1.272 com CLAUDE_CODE_ENABLE_FUNCTION_HOOKS definido, em um Mod escrito à mão chamado redact-secrets e em três Mods descartáveis criados para quebrá-lo. A funcionalidade é acompanhada na issue de proposta de Function Hooks, que continua sendo o mais próximo de uma especificação oficial s3.
As ferramentas existem antes da documentação. A build 2.1.272 traz claude plugin validate, test, eval e details; o test funciona mesmo que plugin --help não o liste no bloco de comandos s3. Rodar /plugin-types dentro de uma sessão escreveu 11,783 linhas em .claude/types/claude-code.d.ts, mais um claude-code-mcp.d.ts de 3,438 linhas cobrindo 150 ferramentas MCP de 7 servidores s3. Contando os tipos gerados, são 84 nomes de eventos ou chamadas em 23 substantivos, e o arquivo renomeia algo que você pode ter lido em posts de setembro: fs.readFile não existe mais, a superfície é fs.read e fs.write s9. Os mesmos tipos dizem que um hook tool.call retorna { result, context? } ou { deny }; text e ref vêm do core e não fazem parte da resposta do próprio hook, então você reescreve result, não text s3.
O claude plugin validate imprime uma pegada antes de o Mod rodar: ./index.ts hooks: tool.call e ./index.ts calls: $.ui.toast, ou calls: nothing on $ quando o módulo não toca em nenhuma capacidade do host s4. Essa linha estática é a única checagem que um diretório como o awesome-claude-code-mods consegue automatizar hoje, o que importa para o próximo parágrafo.
A redação funciona no modo -p. O hook de 42 linhas interceptou tool.call, e o modelo recebeu API_KEY=[REDACTED] onde o arquivo e a saída do shell continham sk-test1234567890abcdef, tanto na ferramenta Read quanto na Bash s3. O log de debug cronometrou um salto saudável em 27.9 ms de ida e volta, incluindo o salto ao worker e o next() s3. O claude plugin details precificou o Mod em cerca de 0 token adicionado a cada sessão: um Mod é código no processo, não texto de prompt, que é o principal argumento de quem o defende contra hooks de shell e skills s7.
A guarda falha aberta. Um Mod slow-guard que dorme 15 s foi cortado no orçamento de 10 s com hook failed: slow-guard: exceeded 10000ms budget (tool.call; skipped; what is below it ran in its place), e o echo hi rodou mesmo assim s3. Um Mod throw-guard que lança exceção foi ignorado do mesmo jeito, hook failed: throw-guard: boom (tool.call; skipped; what is below it ran in its place), com 574.2 ms reportados s3. Barulhento no log, contornado na prática. Qualquer Mod cujo trabalho seja bloquear algo deve ser lido com isso em mente: um bug na guarda é um buraco, não um crash.
Gerar é barato. A partir de uma única frase, o modelo escreveu um Mod funcional de 190 linhas mais 53 linhas de testes em cerca de 4 minutos, 34 turnos e $1.23 (19,053 tokens de saída, 497,282 de leitura de cache, 8,357 de raciocínio) s3. Esse Mod passou em claude plugin validate sem avisos e em claude plugin test com 4 pass / 0 fail em 0.31 s, e escondeu as chaves ao vivo s3. No Mod escrito à mão, o claude plugin test rodou sem chave de API e sem chamada ao modelo: 1 pass em 0.25 s s3. Já existe um skill que ensina agentes a escrever Mods, se você quiser repetir isso com um template s12.
O que não se reproduziu: o $.ui.toast nunca apareceu porque o Mod não carregou no REPL conduzido por pty em 2 tentativas; no -p, o equivalente só surgiu como uma linha de debug. Observou-se o oposto da afirmação "só no REPL" que circula no X, e a causa raiz não foi isolada s8. O heartbeat de 5 s do worker travado também não foi testado; só o orçamento de espera de 10 s e o caminho da exceção foram medidos.
Medições
| Caso | O que o Mod faz | Resultado | Tempo |
|---|---|---|---|
| redact-secrets, ferramenta Read | Reescreve result em tool.call |
O modelo vê API_KEY=[REDACTED] |
27.9 ms por salto |
| redact-secrets, ferramenta Bash | Mesmo hook, saída do shell | O modelo vê API_KEY=[REDACTED] |
27.9 ms por salto |
| slow-guard | Dorme 15 s dentro de tool.call |
Ignorado, echo hi rodou |
cortado em 10000 ms |
| throw-guard | Lança boom dentro de tool.call |
Ignorado, comando rodou | 574.2 ms |
| Mod gerado | 190 linhas + 53 linhas de testes a partir de uma frase | validate: sem avisos; test: 4 pass / 0 fail | ~4 min, 34 turnos, $1.23 |
claude plugin test no redact-secrets |
Sem chave de API, sem chamada ao modelo | 1 pass | 0.25 s |
claude plugin details |
Custo do Mod por sessão | ~0 token adicionado | n/a |
Protocolo: Claude Code 2.1.272, function hooks ativados por variável de ambiente. Cada Mod é um diretório de plugin com plugin.json, hooks/hooks.json e um único index.ts. As execuções passaram por claude -p com log de debug ligado; um arquivo plantado e um comando de shell continham sk-test1234567890abcdef. Os casos de falha aberta foram conduzidos por um Mod que dorme 15 s e um Mod que lança exceção, com echo hi como comando sob guarda. O REPL interativo foi conduzido por um pty e não carregou o Mod em duas tentativas.
Faça isto na segunda-feira
- Rode
/plugin-typesem uma sessão e abra.claude/types/claude-code.d.ts: procurefs.readetool.callantes de confiar em qualquer snippet de um post de setembro. - Escreva o esqueleto de Mod de três arquivos (
plugin.json,hooks/hooks.jsoncom{"modules":["./index.ts"]},index.tsexportandoregister(on)) e rodeclaude plugin validatenele: leia as linhas de pegadahooks:ecalls:. - Porte seu hook de shell mais usado para um handler
tool.callque reescreveresult, e compare o tempo de salto no log de debug com a versão em shell. - Adicione um arquivo
claude plugin testao lado do Mod para que a guarda rode sem chave de API no CI. - Envolva cada handler de guarda em um try/catch que retorne
{ deny }em caso de falha: nesta build, uma exceção ou uma parada de 10 s ignora você e deixa o comando passar. - Teste o Mod com
claude -pe no seu terminal interativo de verdade separadamente, e anote qual deles o carregou. - Antes de instalar um Mod de terceiros, rode
claude plugin validatenele e rejeite qualquer um cuja linhacalls:cite capacidades do host que o Mod não tem motivo para usar.
Para ir além
- Leia a issue de proposta de ponta a ponta, incluindo o PDF de arquitetura anexado nos comentários: é o único contrato escrito para
register(on), os orçamentos e o salto ao worker s3. - Compare com o design dos Mods do Command Code, que executa TypeScript contra um
ModApino processo host: os dois sistemas compartilham o formato e o acesso antecipado restrito s2. - O preview do claudefa.st foi escrito enquanto a funcionalidade ainda era uma proposta: útil para ver o que mudou entre o texto de 3 de setembro e o binário 2.1.272 s9.
- A nota do Prathkum é a declaração curta mais clara de por que hooks no processo vencem hooks de shell em tokens e latência s7.
- O cc-mod-waitwhat é um bom primeiro Mod para ler: UI acima do prompt, nada escrito na transcrição s11.
- O cc-arcade mostra até onde o
$.uichega: jogos renderizados acima do prompt a partir de um Mod s5. - A referência de hooks ainda descreve o modelo de shell; deixe-a aberta para mapear cada evento antigo para o novo nome
noun.events1. - Céticos no X argumentam que os plugins já cobrem isso e que a superfície vai quebrar a cada release; o substantivo
fsrenomeado é um ponto a favor deles s23.
Fontes
- Function Hooks proposal (issue #91870), GitHub, anthropics/claude-code. Por que ler: o único texto parecido com uma especificação para Mods, com o PDF de arquitetura e o histórico de entrega nos comentários.
- Hooks reference, Claude Code docs. Por que ler: o modelo de hooks de shell do qual você está migrando, evento por evento.
- Command Code Mods documentation, Command Code. Por que ler: precedente com o mesmo formato de TypeScript no processo, útil para ver o que a Anthropic copiou ou evitou.
- awesome-claude-code-mods, GitHub, karanb192. Por que ler: diretório de Mods públicos escaneado automaticamente, com a pegada do validate como única checagem.
- cc-arcade, GitHub, sezaakgun. Por que ler: a demo que tornou a funcionalidade visível e um tour pelo
$.ui. - Boris Cherny announcement tweet, X, Boris Cherny. Por que ler: o anúncio de lançamento por um engenheiro da Anthropic, já que não existe post de blog.
- Prathkum: Function Hooks explained, X, Prathkum. Por que ler: a melhor explicação curta de hooks versus Mods para quem já escreve hooks de shell.
- shipnotesai reaction thread, X, shipnotesai. Por que ler: onde a afirmação "só no REPL" circulou, e que o nosso teste contradisse.
- Claude Code Function Hooks: Preview Behind a Flag, claudefa.st. Por que ler: explicação pré-lançamento, boa para comparar a proposta com o binário.
- cc-mod-waitwhat, GitHub, GGGODLIN. Por que ler: um Mod pequeno e legível que escreve na UI e não na transcrição.
- claude-mods-skill, GitHub, BeLazy167. Por que ler: um skill para gerar Mods, se você quiser repetir o experimento de uma frase.
- AxialisSoftware reaction, X, AxialisSoftware. Por que ler: o caso cético, em um único tweet.
FAQ
Um Mod substitui meus hooks de shell hoje?
Ainda não para nada que precise bloquear. Na 2.1.272, um hook que lança exceção ou trava por mais de 10 s é ignorado e o comando roda. Os hooks de shell continuam funcionando, então mantenha neles os que bloqueiam até chegar um catch declarado ou uma opção de falha fechada.
Por que o validate importa se o Mod roda bem?
Porque as linhas hooks: e calls: são a única visão estática do que um Mod toca em $. No seu próprio Mod, confirmam a pegada; num Mod de terceiros, são toda a revisão que você tem antes de o código rodar no seu processo.
Quanto um Mod custa por sessão?
O claude plugin details reportou cerca de 0 token adicionado. O Mod é código rodando no motor, não texto no prompt, que é a principal vantagem sobre um skill ou uma regra de CLAUDE.md.
Por que o Mod carregou no -p mas não no REPL?
Desconhecido. Duas tentativas conduzidas por pty ficaram mudas enquanto o claude -p carregava e aplicava o hook. A causa provável é o ambiente pty e não a funcionalidade, então teste no seu próprio terminal antes de confiar em qualquer um dos lados.
AIDive