Entenda o que é um mod do Claude Code
Nos vídeos que circularam sobre mods do Claude Code apareceram duas proteções: uma guarda de colisão (dois agentes no mesmo arquivo) e uma de "raio de explosão" (o tamanho do estrago de um comando que apaga).
A ideia é ótima. O kit faz a versão própria, só com recursos oficiais: os hooks do Claude Code. A divisão é simples: a regra fica no script, a tela fica no mod.
🆕 Novo aqui? Quatro palavras deste módulo
- Hook (gancho) — um comando que o Claude Code roda sozinho num momento fixo.
PreToolUseroda antes de uma ferramenta (editar, rodar Bash);PostToolUseroda depois. - Plugin — um pacote oficial que acrescenta hooks, comandos ou telas ao Claude Code. Tem um
.claude-plugin/plugin.jsoncom nome e versão. - Mod — o apelido que os vídeos deram aos plugins. No kit, os mods ficam em
runtime/mods/. - Worktree — uma segunda cópia de trabalho do mesmo repositório Git, numa pasta separada. Dois agentes, duas cópias, nenhum pisa no outro.
Como ler o desenho: a caixa âmbar é o ponto de controle. Toda edição e todo comando passam por ela antes de acontecer. Sem risco, segue pela seta azul. Com risco, a guarda não bloqueia nem libera: ela devolve a pergunta para você (N2).
.claude/settings.json do kit (a guarda já vem ligada)"PreToolUse": [
{
"matcher": "Edit|Write|MultiEdit|NotebookEdit",
"hooks": [ { "type": "command",
"command": "node \"$CLAUDE_PROJECT_DIR/runtime/mods/runtime-guarda/hooks/colisao.mjs\" pre",
"timeout": 10 } ]
},
{
"matcher": "Bash",
"hooks": [ { "type": "command",
"command": "node \"$CLAUDE_PROJECT_DIR/runtime/mods/runtime-guarda/hooks/raio.mjs\"",
"timeout": 15 } ]
}
]
…
"PostToolUse": [ … colisao.mjs pos … ]
matcher diz em que ferramenta o gancho dispara. Edição chama a colisão; Bash chama o raio.roda antes ou depois
o "mod" oficial
colisao.mjs · raio.mjs
o painel
Veja a guarda de colisão em ação
A dor é real. Aconteceu num projeto nosso: uma sessão esvaziou um arquivo que outra estava editando. Nenhuma das duas errou sozinha. Cada uma achava que o arquivo era só dela.
A colisão resolve isso com memória. Depois de cada edição, ela anota "esta sessão mexeu neste arquivo agora". Antes da próxima edição, confere a anotação e a data do arquivo.
Como ler o desenho: a seta azul é a edição normal da sessão A, que fica anotada. A seta vermelha é a sessão B chegando dentro da janela de 30 minutos. Quem responde à pergunta da caixa âmbar é você.
Depois de editar: anota
colisao.mjs pos grava o caminho do arquivo, o id da sessão e a hora em toques.json. A gravação é atômica: duas sessões não corrompem o registro.
Antes de editar: confere
colisao.mjs pre olha se outra sessão tocou no arquivo, ou se a data do arquivo mudou por fora, nos últimos 30 minutos.
Se houver risco: pergunta
O texto montado pelo script é: Guarda de colisão: Outra sessão (<id>) editou <arquivo> há <N> min. Seguir mesmo assim, usar outra cópia (worktree) ou cancelar?
✓ Pergunta quando
- ✓ Outra sessão do Claude editou o arquivo há menos de 30 min
- ✓ O arquivo mudou por fora: Codex, editor ou outra pessoa
✗ Fica quieta quando
- ✗ O arquivo é novo (não há nada a proteger)
- ✗ Foi a mesma sessão que editou por último
- ✗ A última mudança tem mais de 30 min
Provado no CHANGELOG 0.3.0: com 5 casos (arquivo velho, alterado por fora, mesma sessão, outra sessão, inexistente), a colisão só pergunta nos casos de outra sessão e de alteração por fora. Dentro do Claude, um Edit em arquivo de outra sessão foi barrado e o arquivo ficou intacto.
⚠️ Limite do Codex
O Codex ainda não tem um gancho "antes de editar" equivalente. A guarda protege as sessões do Claude e detecta edições feitas pelo Codex pela data do arquivo. Ela não impede o Codex de editar. Se o Codex e o Claude vão mexer na mesma pasta, dê a cada um uma worktree.
💡 Ajuste a janela
Se o seu time trabalha devagar, aumente a janela: INEMA_COLISAO_MIN=60 faz a guarda considerar a última hora em vez de 30 minutos.
Prove o raio antes de apagar
O raio entra antes de um rm ou git clean. Ele conta quantos arquivos existentes seriam apagados, soma o tamanho e lista os primeiros caminhos. Depois pergunta: "Tem backup? Confirme para seguir."
O raio não apaga nada: só lê o disco. E se o comando não apagaria nenhum arquivo existente, ele fica quieto. Você pode testar o script sozinho, sem abrir o Claude, mandando para ele o mesmo pedido que o Claude mandaria.
rm -rNo terminal. Troque /caminho/do/kit pela pasta onde você clonou o kit:
mkdir -p /tmp/teste-raio/x && echo a > /tmp/teste-raio/x/a && cd /tmp/teste-raio
printf '{"cwd":"%s","tool_name":"Bash","tool_input":{"command":"rm -r x"}}' "$PWD" \
| node /caminho/do/kit/runtime/mods/runtime-guarda/hooks/raio.mjs
Resultado provado no CHANGELOG 0.3.0 / esperado pela receita R7:
a saída traz "permissionDecision":"ask" e o texto Raio: este comando apaga 1 arquivo(s)
x continua lá. O comando acima só perguntou ao raio; não apagou nada.🆕 Novo aqui? O que o printf … | faz
O printf monta um texto no formato que o Claude Code entrega ao hook: a pasta (cwd), a ferramenta (Bash) e o comando (rm -r x). A barra | joga esse texto para dentro do raio.mjs. É um ensaio: o hook responde como responderia ao Claude.
| Caso testado (CHANGELOG 0.3.0) | O raio… |
|---|---|
rm -r, rm -f *.txt, git clean -fd | conta exatamente os arquivos que seriam apagados e pergunta |
rm de arquivo inexistente, ls | nada a apagar: não pergunta |
Claude no modo que libera tudo, pedindo rm -r pasta | barra pelo "Raio"; pasta intacta |
💡 Duas camadas, não uma
O .claude/settings.json já nega rm -rf de vez (módulo 4.1). O raio cobre o resto: rm -r, rm com curinga, git clean. A negação é um muro; o raio é uma porta que só abre com o seu sim.
tamanho do estrago
arquivos e tamanho
nunca apaga
a pergunta final
Leve a guarda para outro projeto
Na pasta do kit a guarda já está ligada. Mas a Sônia tem outra pasta, a dos fechamentos mensais, onde também roda agentes. Ela quer a mesma proteção lá.
A receita R7 dá dois jeitos. Escolha um, não os dois.
Jeito 1 · Só nesta sessão
Abre o Claude carregando a guarda como plugin. Fechou a sessão, acabou.
Bom para testar ou para um projeto passageiro.
Jeito 2 · Fixo no projeto
Copie o bloco hooks do .claude/settings.json do kit para o .claude/settings.json do outro projeto, trocando o caminho.
Bom para a pasta que você usa todo dia.
No terminal, dentro da pasta do outro projeto (troque /caminho/do/kit):
claude --plugin-dir /caminho/do/kit/runtime/mods/runtime-guarda
Resultado provado no CHANGELOG 0.3.0:
com --plugin-dir runtime-guarda e o modo que libera tudo, rm -r pasta foi barrado pelo "Raio" e a pasta ficou intacta; Edit em arquivo editado por outra sessão foi barrado pela "colisão".
rm -r. Ele tem de parar e mostrar a pergunta do Raio. Responda "não".💡 Por que o caminho muda
No kit, o settings usa $CLAUDE_PROJECT_DIR/runtime/mods/…, ou seja, "a pasta deste projeto". No outro projeto não existe runtime/. Por isso, no jeito 2, o caminho tem de apontar para onde o kit está de verdade.
só nesta sessão
fixo no projeto
nunca os dois
aponta para o kit
Abra o painel do time
No módulo 3.3 você soltou sessões com claude --bg e acompanhou pelo observar.mjs, em outro terminal. O painel traz essa lista para dentro do Claude Code. É opcional.
Ele mostra cada sessão em segundo plano com nome, estado e minutos, um botão Atualizar e um botão Parar nas que estão rodando. Só o seu clique para uma sessão.
No terminal, dentro da pasta do kit. Depois, já na sessão, digite /painel:
claude --plugin-dir runtime/mods/runtime-painel
Para conferir o mod antes de usar:
claude plugin validate runtime/mods/runtime-painel claude plugin test runtime/mods/runtime-painel
Resultado provado no CHANGELOG 0.3.0:
validate: passa test: 1 pass
/painel abre um painel com as sessões do claude --bg desta pasta e os botões Atualizar e Parar.Como ler o desenho: é uma ilustração, não um print. A linha r4-revisor · done · 7 é a mesma sessão que o observar.mjs mostrou no módulo 3.3. O botão vermelho só aparece em sessão que ainda está rodando.
| observar.mjs | /painel | |
|---|---|---|
| Onde roda | outro terminal | dentro da sessão do Claude |
| Parar sessão | você digita claude stop <id> | botão Parar |
| Precisa instalar | não, já vem no kit | carregar o mod com --plugin-dir |
O que olhar na tabela: os dois leem a mesma lista de sessões. Escolha pelo conforto, não pela função.
o comando novo
lê de novo
só com seu clique
teste do mod
Leia o código antes de instalar um mod
Mods e plugins rodam com as mesmas permissões do Claude Code. Um hook pode ler seus arquivos, rodar comandos e acessar a rede, sem perguntar. É por isso que ele protege bem e é por isso que um mod mal-intencionado estraga bem.
A regra da receita R7: leia o código de qualquer mod de terceiro antes de instalar. Você não precisa programar para isso. Peça ao agente para ler e explicar, sem rodar nada.
Abra claude na pasta do kit e cole (para um mod de terceiro, troque os caminhos):
Leia runtime/mods/runtime-guarda/.claude-plugin/plugin.json, runtime/mods/runtime-guarda/hooks/hooks.json, colisao.mjs e raio.mjs. Me diga em linguagem simples: em que momento cada hook roda, o que ele lê, o que ele grava e se acessa a rede. Não instale nem rode nada.
toques.json; nenhum dos dois chama a rede.✓ Sinais de mod saudável
- ✓
plugin.jsoncom autor, licença e endereço do código - ✓
hooks.jsoncurto: dá para ver cada gancho - ✓ Grava só num lugar conhecido
- ✓ Pergunta em vez de decidir sozinho
✗ Sinais de alerta
- ✗ Código embaralhado que ninguém consegue ler
- ✗ Lê credenciais, tokens ou a pasta de configuração de outra ferramenta
- ✗ Manda dados para um endereço da internet
- ✗ Aprova permissões sozinho
Teste rápido (opcional): a guarda encontra risco numa edição. O que ela faz?
as do Claude Code
todo mod de terceiro
sem rodar nada
a pergunta-chave
🎓 Resumo do módulo
Próximo módulo:
4.4 — Laboratório e projeto final