Хуки FileChanged
Используйте FileChanged для отслеживания файлов, изменённых Qwen Code, командами оболочки, редакторами
или другими процессами. Работает в локальных неуправляемых сессиях. См.
руководство по хукам для настройки хуков, исполнителей и правил доверия.
Входные данные события
Входные данные включают общие поля хука и:
{
"file_path": "/home/me/work/demo/.envrc",
"event": "change"
}file_path — абсолютный путь. event принимает значение add, change или unlink для добавления,
изменения или удаления наблюдаемого файла. Общие session_id и cwd
принадлежат слушающей сессии; они не идентифицируют записывающего. Несколько
сессий, наблюдающих за общим каталогом, могут получать его изменения. Содержимое файла
не передаётся.
Доставляются только события файлов. События addDir и unlinkDir для самого каталога
не доставляются. Интеграции, отслеживающие жизненный цикл наблюдаемого корня, должны
проверять состояние файловой системы (например, с помощью stat) и выполнять сверку независимо;
unlink дочернего элемента не доказывает удаление корня.
Отслеживание имён файлов в рабочем каталоге
Добавьте хук FileChanged с буквальными именами файлов, разделёнными |:
{
"hooks": {
"FileChanged": [
{
"matcher": ".envrc|.env",
"hooks": [
{
"type": "command",
"name": "configuration-changed",
"command": "node \"$QWEN_PROJECT_DIR/.qwen/hooks/on-file-changed.mjs\""
}
]
}
]
}
}Это регистрирует .envrc и .env в cwd сессии. Статическая регистрация не
раскрывает glob-шаблоны и не сканирует каталоги рекурсивно. Пропущенные или пустые матчеры,
* и .* не регистрируют статических путей; такие хуки получают события из
наблюдаемых путей сессии, включая динамические пути. События фильтруются по
базовому имени файла с использованием
существующих правил матчера.
Regex-шаблоны фильтруют уже наблюдаемые пути; зарегистрируйте их файлы или каталоги
явно через watchPaths.
Статические корни принимают только буквенные имена файлов, включая скрытые файлы. Метасимволы regex/glob
и разделители путей не создают статических корней. Существующие
каталоги и пути, которые нельзя проверить, исключаются; отсутствующие файлы могут отслеживаться
на создание. Статическое обнаружение файлов наблюдает за их родительским каталогом, исключая
несвязанные записи перед обходом. Используйте явные watchPaths для рекурсивных каталогов. Изменение
рабочего каталога сессии перемещает статические корни до завершения перемещения;
явные абсолютные динамические корни остаются неизменными.
Отслеживание каталогов и путей вне cwd
Успешный синхронный хук SessionStart может регистрировать абсолютные файлы или каталоги
через hookSpecificOutput.watchPaths. Каталоги наблюдаются рекурсивно,
включая дочерние элементы, созданные позже. Рекурсивное обнаружение пропускает поддеревья .git и
node_modules. Для наблюдения за путём внутри них зарегистрируйте этот файл или
каталог явно. Специальные типы файлов игнорируются, обычные каталоги
не имеют ограничения по глубине. Начальная регистрация ожидает готовности наблюдателя
перед возвратом из SessionStart.
Рекурсивное обнаружение игнорирует временные файлы атомарной записи с именами
<target>.<12 lowercase hex characters>.tmp, включая отложенные переименования и
сироты. Явная регистрация такого файла всё равно наблюдает за ним. Каталоги с
этим суффиксом остаются обходимыми, другие .tmp файлы наблюдаются обычно.
Например, зарегистрируйте папки памяти:
{
"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\""
}
]
}
]
}
}Заставьте watch-memory.mjs вывести этот JSON в stdout. Замените примерные пути на
фактические абсолютные папки, показанные /memory:
{
"hookSpecificOutput": {
"hookEventName": "SessionStart",
"watchPaths": [
"/home/me/.qwen/projects/demo/memory",
"/home/me/.qwen/memories"
]
}
}Хук FileChanged не имеет матчера, поэтому получает изменения во всех тех
зарегистрированных каталогах. Его обработчик читает JSON события из stdin. Выберите
назначение лога или синхронизации вне наблюдаемых путей, чтобы не запускать
обработчик собственными записями.
Обновление динамических путей
Для нескольких рабочих пространств в одной файловой системе зарегистрируйте все их фактические каталоги
памяти в одном списке. Маршрутизируйте уведомления используя file_path и ваше собственное
сопоставление каталогов с рабочими пространствами, а не cwd слушающей сессии.
Независимые сессии могут наблюдать за одним общим корнем, поэтому дедуплицируйте работу
в бизнес-обработчике. Корни в другом контейнере или удалённом экземпляре требуют
наблюдателя в владельце той файловой системы; регистрация их путей на хосте не
наблюдает за ними.
Успешный синхронный вывод SessionStart и FileChanged может устанавливать watchPaths. Включите
соответствующий hookEventName в hookSpecificOutput.
| Вывод | Влияние на динамические пути |
|---|---|
| Список абсолютных файлов или каталогов | Заменяет предыдущий динамический список |
[] | Очищает динамический список |
Пропущенный или невалидный watchPaths | Сохраняет предыдущий динамический список |
| Вывод асинхронного хука | Не регистрирует и не изменяет пути |
Когда несколько хуков возвращают списки, побеждает последний валидный, явно предоставленный список в порядке выполнения хуков. Все записи должны быть абсолютными путями; одна невалидная запись делает список невалидным. Статические регистрации имён файлов остаются активными после динамической замены или очистки.
Для очистки динамических путей из обработчика FileChanged верните:
{
"hookSpecificOutput": {
"hookEventName": "FileChanged",
"watchPaths": []
}
}Ограничения наблюдения
Начальное сканирование каталога не воспроизводится. Нативные события файловой системы от недавней записи могут поступить после регистрации. Явно зарегистрированные файлы-символические ссылки и корни каталогов наблюдают за их целями, включая ссылки в путях предков. Уведомления используют настроенный алиас; регистрация нескольких алиасов на одну цель создаёт уведомление для каждого алиаса. Обновите регистрацию после перенацеливания ссылки. Символические ссылки, обнаруженные внутри рекурсивного корня, не обходятся. События сообщаются после завершения записей. Наблюдение выполняется по мере возможности (best-effort): коалесцинг файловой системы, недоступные пути, простой процесса и переконфигурация путей могут создавать пробелы. Интеграции, требующие полной синхронизированной копии, должны обрабатывать начальные сканирования, сверку и повторы. Сбои наблюдателя или хука логируются и не изменяют исходную файловую операцию.
FileChanged не может отклонить или отменить запись или добавить контекст модели. Наблюдаются только явно
зарегистрированные пути: папки памяти не регистрируются автоматически,
и нет специального события включения/отключения автопамяти. Хук, записывающий
наблюдаемый файл, может запустить сам себя; избегайте таких записей или дедуплицируйте работу.
Среды выполнения SSH, воркеры песочницы оболочки и управляемые диспетчеры не запускают локальный наблюдатель файловой системы. Обычные правила включения хуков и доверия всё ещё применяются. Наблюдение прекращается при завершении владеющей сессии.