Разработчик сделал маскота для Claude Code, который топает, пока ассистент ждёт ответа
Длинная задача в Claude Code нередко заканчивается тем, что агент минут десять ждёт вопроса «можно выполнить команду?», а уведомление Windows мигнуло пять секунд и пропало. Автор сделал открытый маскот на Electron: он выглядывает из угла экрана, а при игнорировании краснеет и топает по панели задач. Сигнал берётся из хуков Claude Code и из базы уведомлений Windows.
AI-обработка оригинала Habr AI; редакция Hamidun News
Знакомая ситуация: даёшь Claude Code большую задачу, переключаешься на соседнее окно, а через четверть часа обнаруживаешь, что агент давно остановился на вопросе «можно выполнить эту команду?». Системное уведомление Windows, конечно, было, но показалось на пять секунд в углу экрана, пока ты смотрел в другую сторону. Автор разбора на Habr решил эту проблему радикально: сделал маскота, которого невозможно не заметить.
Маскот — маленький оранжевый человечек. Сначала он выглядывает из правого нижнего угла. Если его игнорировать, выходит целиком, краснеет и топает по панели задач, пока вы не вернётесь. Забавная обёртка, но самое полезное здесь — инженерная часть: как надёжно узнать, что ассистент чего-то ждёт.
Как поймать момент ожидания
В терминальной версии Claude Code всё просто благодаря хукам. В ~/.claude/settings.json можно описать команду, которая запустится на нужном событии, а JSON с деталями придёт ей на stdin. Для этой задачи подходит событие Notification. Команда отправляет stdin через curl на локальный HTTP-сервер маскота (127.0.0.1:47821). Хвост || exit 0 нужен, чтобы при незапущенном маскоте хук молча завершался с нулём, а Claude Code не показывал ошибку на каждом событии. Сервер ещё отбрасывает запросы с заголовком Origin, чтобы случайная веб-страница не могла дёргать локальный порт.
С десктопным приложением Claude (вкладка Code) сложнее: когда оно просит разрешение или задаёт вопрос, событие Notification не отправляется. В терминале всё работало, на десктопе маскот молчал. Пришлось подписаться ещё на PermissionRequest и на PreToolUse с matcher AskUserQuestion|ExitPlanMode, чтобы ловить вопросы и утверждение плана. Опционально есть Stop, срабатывающий после каждого ответа. Хуки маскот прописывает сам, предварительно делая бэкап settings.json (хранятся пять последних копий) и не трогая чужие записи.
Есть нюанс: уже открытые сессии могут не подхватить новые хуки до перезапуска. Поэтому добавлен второй источник сигнала — база уведомлений Windows. Система пишет каждую плашку в SQLite-файл wpndatabase.db. Раз в секунду маскот открывает его на чтение и ищет записи приложения вида Claude_*!Claude. Встроенный в Node модуль node:sqlite избавляет от нативных зависимостей, а работает способ даже с уже запущенным Claude, ничего в него не внедряя.
Окно, которое видно, но не мешает
Вторая задача — нарисовать оверлей. Он должен быть прозрачным, лежать поверх всех окон (включая полноэкранные), не появляться в панели задач, не красть фокус и пропускать клики мимо себя. В Electron это почти целиком настройки BrowserWindow: frame: false, transparent: true, skipTaskbar, alwaysOnTop, focusable: false.
Интересный трюк — setIgnoreMouseEvents(true, { forward: true }). Окно становится прозрачным для кликов, но страница всё равно получает события движения мыши. Когда курсор заходит на маскота (mouseenter), клики включаются обратно, при уходе курсора выключаются. Вручную вычислять форму окна не нужно.
Для определения, активно ли окно Claude, и возврата его на передний план автор использует koffi: он вызывает функции user32.dll без node-gyp. Активное окно опрашивается каждые 300 мс, нагрузка незаметна.
Мелочи, которые стоит позаимствовать
Если маскот и штатная плашка Windows появляются одновременно, получается дубль. Для этого есть опция, отключающая баннеры только для Claude через ShowBanner = 0 в реестре. Записи в центре уведомлений остаются, поэтому база продолжает пополняться и маскот их видит. Прежнее значение настройки сохраняется и восстанавливается при выключении опции, выходе, завершении сеанса и даже после аварийного падения при следующем старте.
Из упомянутых в разборе подводных камней сборки: electron-builder загружает файлы параллельно и иногда создаёт дубли релиза, поэтому в GitHub Actions релиз сначала создаётся через gh release create, а потом наполняется. У portable-версии process.execPath указывает на временную папку, поэтому для автозапуска путь берут из переменной PORTABLE_EXECUTABLE_FILE.
Что с этим делать
Проект бесплатный, лицензия MIT, под Windows. Если вы не собираетесь ставить маскота, сам паттерн всё равно полезен: хук Notification плюс локальный HTTP-приёмник — минимальный способ связать Claude Code с любым внешним сигналом, будь то звук, телефон или умная лампа. Главное ограничение: решение завязано на Windows и на внутренний формат базы уведомлений, который Microsoft не документирует как API. Для десктопного Claude этот источник служит запасным, и он может сломаться с обновлением системы. Для терминальной версии хуков достаточно.
- 12 нояб. 2026 г.Дженсен Хуанг ушёл с поста CEO Nvidia: компания потеряла $1,4 трлн за две недели
- 12 нояб. 2026 г.Claude in Chrome требует разрешать каждый клик на сайтах с категорией 3
- 12 нояб. 2026 г.AWS Quick получил шесть агентов для продактов: от жалоб клиентов до спеки
- 12 нояб. 2026 г.Anthropic с 12 ноября закрывает Claude для компаний России, даже с юрлицом за рубежом
Вопросы и ответы по материалу
Что известно по теме: как поймать момент ожидания?
В терминальной версии Claude Code всё просто благодаря хукам. В ~/.claude/settings.json можно описать команду, которая запустится на нужном событии, а JSON с деталями придёт ей на stdin. Для этой задачи подходит событие Notification. Команда отправляет stdin через curl на локальный HTTP-сервер маскота (127.0.0.1:47821). Хвост || exit 0 нужен, чтобы при незапущенном маскоте хук молча завершался с нулём, а Claude Code не показывал ошибку на каждом событии.
Что известно по теме: окно, которое видно, но не мешает?
Вторая задача — нарисовать оверлей. Он должен быть прозрачным, лежать поверх всех окон (включая полноэкранные), не появляться в панели задач, не красть фокус и пропускать клики мимо себя. В Electron это почти целиком настройки BrowserWindow: frame: false, transparent: true, skipTaskbar, alwaysOnTop, focusable: false. Интересный трюк — setIgnoreMouseEvents(true, { forward: true }). Окно становится прозрачным для кликов, но страница всё равно получает события движения мыши.
Что известно по теме: мелочи, которые стоит позаимствовать?
Если маскот и штатная плашка Windows появляются одновременно, получается дубль. Для этого есть опция, отключающая баннеры только для Claude через ShowBanner = 0 в реестре. Записи в центре уведомлений остаются, поэтому база продолжает пополняться и маскот их видит. Прежнее значение настройки сохраняется и восстанавливается при выключении опции, выходе, завершении сеанса и даже после аварийного падения при следующем старте.
Соберите рабочего ИИ-агента или сервис своими руками без ручного кода
В Академии Жемала Хамидуна (academy.hamidun.com) открыт бесплатный 72-часовой тест-драйв: интерактивные скетч-уроки по Claude Code и Cursor, живой Tech Radar и готовые шаблоны агентов.
Главное из мира ИИ — раз в неделю
7 ключевых событий недели, отобранных вручную. Без шума, репостов и пресс-релизов.
Готово! Проверьте почту — мы отправили подтверждение.