Skip to Content
Guia do UsuárioRecursoshooks FileChanged

hooks FileChanged

Use FileChanged para observar arquivos alterados pelo Qwen Code, comandos shell, editores ou outros processos. Ele é executado em sessões locais e não gerenciadas. Consulte o guia de Hooks para configuração de hooks, executores e regras de confiança.

Entrada do evento

A entrada inclui os campos comuns de hook e:

{ "file_path": "/home/me/work/demo/.envrc", "event": "change" }

file_path é absoluto. event é add, change ou unlink para adição, modificação ou exclusão de um arquivo observado. O session_id e cwd comuns pertencem à sessão de escuta; eles não identificam o escritor. Múltiplas sessões observando um diretório compartilhado podem receber suas alterações. O conteúdo do arquivo não é incluído.

Somente eventos de arquivo são entregues. Eventos addDir e unlinkDir do próprio diretório não são entregues. Integrações que rastreiam o ciclo de vida da raiz observada devem verificar o estado do sistema de arquivos (por exemplo, com stat) e reconciliar de forma independente; o unlink de um filho não prova que a raiz foi removida.

Observar nomes de arquivos no diretório de trabalho

Adicione um hook FileChanged com nomes de arquivos literais separados por |:

{ "hooks": { "FileChanged": [ { "matcher": ".envrc|.env", "hooks": [ { "type": "command", "name": "configuration-changed", "command": "node \"$QWEN_PROJECT_DIR/.qwen/hooks/on-file-changed.mjs\"" } ] } ] } }

Isso registra .envrc e .env no cwd da sessão. O registro estático não expande globs nem varre diretórios recursivamente. Matchers omitidos ou vazios, * e .* não registram caminhos estáticos; esses hooks recebem eventos dos caminhos observados da sessão, incluindo caminhos dinâmicos. Os eventos são filtrados pelo nome base do arquivo usando as regras de matcher existentes.

Padrões regex filtram caminhos já observados; registre seus arquivos ou diretórios explicitamente através de watchPaths.

Raízes estáticas aceitam apenas nomes de arquivos literais simples, incluindo dotfiles. Metacaracteres regex/glob e separadores de caminho não criam raízes estáticas. Diretórios existentes e caminhos que não podem ser inspecionados são excluídos; arquivos ausentes podem ser observados para criação. A descoberta estática de arquivos observa seu diretório pai enquanto exclui entradas não relacionadas antes da travessia. Use watchPaths explícitos para diretórios recursivos. Alterar o diretório de trabalho da sessão realoca as raízes estáticas antes que a realocação termine; raízes dinâmicas absolutas explícitas permanecem inalteradas.

Observar diretórios e caminhos fora do cwd

Um hook síncrono SessionStart bem-sucedido pode registrar arquivos ou diretórios absolutos através de hookSpecificOutput.watchPaths. Os diretórios são observados recursivamente, incluindo filhos criados posteriormente. A descoberta recursiva ignora as subárvores .git e node_modules. Para observar um caminho dentro deles, registre esse arquivo ou diretório explicitamente. Tipos de arquivo especiais são ignorados, e diretórios comuns não têm limite de profundidade. O registro inicial aguarda a prontidão do watcher antes que SessionStart retorne.

A descoberta recursiva ignora arquivos temporários de escrita atômica nomeados <target>.<12 lowercase hex characters>.tmp, incluindo renomeações atrasadas e órfãos. Registrar explicitamente tal arquivo ainda o observa. Diretórios com este sufixo permanecem atravessáveis, e outros arquivos .tmp são observados normalmente.

Por exemplo, registre pastas de memória:

{ "hooks": { "SessionStart": [ { "hooks": [ { "type": "command", "name": "watch-memory-folders", "command": "node \"$QWEN_PROJECT_DIR/.qwen/hooks/watch-memory.mjs\"" } ] } ], "FileChanged": [ { "hooks": [ { "type": "command", "name": "memory-file-changed", "command": "node \"$QWEN_PROJECT_DIR/.qwen/hooks/on-file-changed.mjs\"" } ] } ] } }

Faça com que watch-memory.mjs imprima este JSON no stdout. Substitua os caminhos de exemplo pelas pastas absolutas reais mostradas por /memory:

{ "hookSpecificOutput": { "hookEventName": "SessionStart", "watchPaths": [ "/home/me/.qwen/projects/demo/memory", "/home/me/.qwen/memories" ] } }

O hook FileChanged não tem matcher, então recebe alterações em todos os diretórios registrados. Seu handler lê o JSON do evento do stdin. Escolha um destino de log ou sincronização fora dos caminhos observados para evitar acionar o handler com suas próprias escritas.

Atualizar caminhos dinâmicos

Para vários workspaces no mesmo sistema de arquivos, registre todos os seus diretórios de memória reais em uma lista. Encaminhe notificações usando file_path e seu próprio mapeamento de diretório para workspace, em vez do cwd da sessão de escuta. Sessões independentes podem observar a mesma raiz compartilhada, então deduplique o trabalho no handler de negócio. Raízes em outro contêiner ou instância remota precisam de um watcher no proprietário desse sistema de arquivos; registrar seus caminhos no host não os observa.

Saídas síncronas bem-sucedidas de SessionStart e FileChanged podem definir watchPaths. Inclua o hookEventName correspondente em hookSpecificOutput.

SaídaEfeito nos caminhos dinâmicos
Uma lista de arquivos ou diretórios absolutosSubstitui a lista dinâmica anterior
[]Limpa a lista dinâmica
watchPaths omitido ou inválidoMantém a lista dinâmica anterior
Saída de um hook assíncronoNão registra nem altera caminhos

Quando vários hooks retornam listas, a última lista válida e explicitamente fornecida na ordem de execução dos hooks prevalece. Todas as entradas devem ser caminhos absolutos; uma entrada inválida torna a lista inválida. Registros de nomes de arquivo estáticos permanecem ativos após uma substituição ou limpeza dinâmica.

Para limpar caminhos dinâmicos de um handler FileChanged, retorne:

{ "hookSpecificOutput": { "hookEventName": "FileChanged", "watchPaths": [] } }

Limites de observação

A varredura inicial do diretório não é repetida. Eventos nativos do sistema de arquivos de uma escrita recente podem chegar após o registro. Arquivos de link simbólico e raízes de diretório registrados explicitamente observam seus alvos, incluindo links em caminhos ancestrais. As notificações usam o alias configurado; registrar múltiplos aliases para um alvo produz uma notificação para cada alias. Atualize o registro após redirecionar um link. Links simbólicos descobertos dentro de uma raiz recursiva não são atravessados. Eventos são relatados após as escritas estabilizarem. A observação é no melhor esforço: coalescimento do sistema de arquivos, caminhos inacessíveis, tempo de inatividade do processo e reconfiguração de caminho podem deixar lacunas. Integrações que requerem uma cópia sincronizada completa devem lidar com varreduras iniciais, reconciliação e nova tentativa. Falhas de watcher ou hook são registradas em log e deixam a operação de arquivo originadora inalterada.

FileChanged não pode vetar ou desfazer uma escrita nem adicionar contexto de modelo. Somente caminhos registrados explicitamente são observados: pastas de memória não são registradas automaticamente, e não há um evento dedicado de ativação/desativação de memória automática. Um hook que escreve um arquivo observado pode acionar a si mesmo; evite essas escritas ou deduplique o trabalho.

Ambientes de execução SSH, workers de sandbox shell e dispatchers gerenciados não iniciam um watcher de sistema de arquivos local. As regras normais de ativação e confiança de hooks ainda se aplicam. A observação para quando sua sessão proprietária é encerrada.

Last updated on