Mapa da trilha
🗺️ O mapa de eventos
Escolha o evento antes do código
⛓️ A cadeia: next, reescrever e responder
Quem chama next decide
💾 Estado que sobrevive
Variável some no reload
⏱️ Trabalho fora do dispatch
session.start acende, clock mantém
Conteúdo detalhado
🗺️ O mapa de eventos
Os eventos agrupados por noun, a volta completa de um turno, matchers, streams e os hooks clássicos dentro do mod.
Cada evento é noun.ação; agrupar por noun mostra o que o mod pode tocar: ferramentas, tela, sessão, turno, prompt, estado.
Ver o mapa inteiro evita escrever em ui.render o que deveria ser um tool.call.
evento, noun, tool, ui, session, turn, prompt.
A ordem em que os eventos disparam: prompt.submit, turn.start, turn.step, tool.call, session.append e turn.complete.
Saber onde você está na volta diz o que já aconteceu e o que ainda dá para mudar.
turno, prompt.submit, turn.start, turn.step, turn.complete.
O matcher filtra quais eventos chegam ao hook, como { tool: 'Read' } ou { command: 'readcount' }.
Hook sem matcher roda em tudo e gasta orçamento à toa.
matcher, filtro, on(evento, matcher, hook).
Dois eventos são stream: o hook é um async generator, e yield* next(e) repassa os pedaços.
Hook comum nesses eventos não carrega; o erro só aparece no --debug.
stream, async function*, yield* next(e), for await.
Os hooks clássicos do settings.json aparecem para o mod como classic.<Nome>, com a mesma entrada que o hook receberia.
Você aproveita o que já conhece de hooks clássicos sem sair do mod.
classic.PreToolUse, classic.Stop, hook clássico.
Procurar qualquer evento, entrada e resultado no arquivo de tipos da sua instalação, .claude-plugin/types/claude-code/index.d.ts.
A API está em acesso antecipado e muda: o arquivo da sua versão é a autoridade, não a memória.
declaração de tipos, index.d.ts, grep, versão.
⛓️ A cadeia: next, reescrever e responder
A cadeia de plugins: observar, reescrever com next, responder sem next, .catch e o orçamento de cada dispatch.
Os hooks de todos os plugins e o comportamento do próprio Claude Code formam uma cadeia ligada por next.
Seu mod não está sozinho: o que você devolve é o que os outros e o engine recebem.
cadeia, ordem, engine, plugins vizinhos.
O hook mais simples olha o evento, registra algo e devolve next(e) sem mudar nada.
É o padrão seguro: medir sem interferir.
observar, next(e), efeito colateral.
Chamar next com um evento alterado muda o que o resto da cadeia vê, dentro do que aquele evento permite.
É como um mod corrige um caminho, acrescenta contexto ou troca um modelo.
reescrever, spread, campos permitidos.
Um hook que retorna sem chamar next responde pelo evento, e a cadeia abaixo dele não roda.
É o poder de negar uma ferramenta ou responder um comando, e também o maior risco do mod.
responder, deny, curto-circuito.
O .catch encadeado no on responde no lugar do hook que falhou; sem ele, o hook é pulado e a cadeia segue.
Falha silenciosa num mod de segurança deixa passar o que devia barrar.
.catch, hook pulado, padrão seguro.
Cada hook tem orçamento de tempo dentro do dispatch, e next.signal aborta quando o dispatch é abandonado.
Trabalho longo dentro do hook é cortado; o que precisa durar vai para fora.
dispatch, orçamento, next.signal, abort.
💾 Estado que sobrevive
Por que a variável de módulo some, como declarar o contrato de estado e quando usar $.state ou $.store.
Cada hot-reload roda o register num ambiente novo; a variável de módulo volta ao valor inicial.
O contador que zera do nada é o sintoma número um de estado no lugar errado.
variável de módulo, hot-reload, ambiente novo.
Declarar o formato do estado do plugin em types/index.d.ts e apontar o arquivo em "types" no plugin.json.
Com o contrato, o editor e o tsc conferem cada leitura e escrita de estado.
types/index.d.ts, PluginState, "types", contrato.
atom, read e update vêm de import { ... } from "claude-code" e leem e gravam $.state com controle de versão.
update não perde clique: dois toques antes do redesenho contam os dois.
atom, read, update, $.state.get, $.state.set, ifVersion.
O $.store guarda valores entre sessões com get, set, delete e keys.
$.state vale para a sessão; o que precisa voltar amanhã vai para o store.
$.store.get, $.store.set, persistência.
O engine dá o relógio do mod: now para a hora e timers que o teste pode controlar.
Usar o relógio do engine deixa o mod testável sem esperar tempo real.
$.clock.now, relógio controlado, teste.
A regra de decisão: constante no módulo, estado da sessão em $.state, o que sobrevive entre sessões em $.store.
Cada dado no lugar certo evita perda no reload e lixo acumulado no disco.
decisão, escopo do dado, sessão, persistência.
⏱️ Trabalho fora do dispatch
session.start, relógio do engine, arquivos, processos locais, acordar a sessão e decidir se o mod gasta modelo.
O session.start dispara uma vez, quando a sessão fica pronta, e é aguardado antes do primeiro prompt.
É o lugar de registrar comandos e ferramentas e de acender o que roda em segundo plano.
session.start, inicialização, $.command.register, $.tool.register.
clock.every repete e clock.after agenda uma vez; os timers duram até serem cancelados ou o módulo recarregar.
Trabalho periódico fora do dispatch não tem orçamento cortando no meio.
$.clock.every, $.clock.after, cancelamento, reload.
O $.fs lê texto ou bytes, escreve, lista e dá stat de caminhos, com realPath para guardas robustas.
Sem Node, o $.fs é a única forma de o mod tocar arquivos.
$.fs.read, $.fs.write, $.fs.stat, realPath.
O $.process.run roda um comando do sistema por argv, e $.process.spawn entrega a saída em pedaços.
git status, contagem de linhas, scripts locais: tudo por argv, sem shell montado em string.
$.process.run, $.process.spawn, argv.
O $.prompt.submit põe um prompt na fila que começa um turno quando a sessão fica ociosa.
Deixa um mod de segundo plano chamar o modelo na hora certa, sem atropelar o turno em curso.
$.prompt.submit, fila, sessão ociosa.
O $.model.complete e o $.model.fork chamam o modelo pelo cliente da sessão e consomem uso.
Mod que gasta modelo escondido surpreende quem usa; a regra é avisar e deixar desligar.
$.model.complete, $.model.fork, uso, consentimento.