Polynya

Активная разработка

Меню документации

Уведомления, ИИ-агенты и терминал

В Polynya один общий стек уведомлений для всех источников: встроенных индикаторов ядра, ИИ-агентов, фоновых команд терминала, внешних скриптов (polynya push), сторонних модулей и системных уведомлений самой Windows.


1. Как устроены очередь, серии и стопка "+N"

Правая зона острова работает по строгим правилам, чтобы частые обновления статусов не перекрывали новые уведомления и не устраивали мелькание на экране:

  • Первое место и минимальное удержание (3 секунды). Любое новое уведомление (или обновление существующего по тому же ключу key) стремится встать первым - ближе всего к основному блоку острова. Каждое уведомление, вставшее на первое место, удерживает его минимум 3 секунды. Если в это время приходит уведомление от другого источника, оно ждет своей очереди невидимым.
  • Умные серии (source). Уведомления от одного и того же источника (source; для системных тостов Windows это связка "приложение + заголовок", то есть конкретная беседа в мессенджере) не ждут друг друга в очереди:
    • Новое сообщение из той же серии сразу встает первым, а предыдущее мгновенно сдвигается в стек.
    • Если уведомление этого источника уже стояло в невидимой очереди ожидания, новое занимает его место в очереди, а прежнее сразу уходит в стек.
    • Частые обновления первого чипа (например, ИИ-агент быстро меняет статус с "Читает файл" на "Редактирует") не продлевают его 3-секундное удержание, если в очереди уже ждет другой источник.
  • Честный отсчет времени жизни (ttl_ms). Таймер до исчезновения чипа запускается только в тот момент, когда уведомление реально вышло на первое место. Пока курсор мыши наведен на чип или открыта его выпадашка - таймер стоит на паузе, а после ухода курсора взводится заново на полный срок.
  • Чип, раскрытие и стопка "+N":
    • В обычном виде чип показывает иконку и короткий заголовок. При наведении подробный текст едет бегущей строкой (многострочный текст склеивается через ·).
    • По клику на чип открывается выпадашка с полным текстом, источником, временем и кнопкой закрытия.
    • Все чипы, которые не поместились в свободную ширину панели задач, сворачиваются в компактный счетчик "+N" с кружками иконок. Наведение на "+N" прокручивает заголовки скрытых уведомлений, а клик открывает полный список.

2. ИИ-агенты (Claude Code, Codex, Cursor, Kimi Code)

Встроенный модуль agents выводит статус работы локальных ИИ-агентов прямо в панель задач. Вы видите, что делает агент, пока переключились в браузер или другое окно: "Думает…", "Редактирует main.rs", "Ожидание…", "Готово" или "Ошибка". Пока агент работает, иконка на чипе анимирована (фирменный глиф для Claude или вращающийся рывками по 60° знак Polynya).

Как это работает без ручной настройки

При включении модуля agents ядро один раз вызывает polynya-agents.exe register (при выключении - unregister). Модуль сам аккуратно прописывает свои хуки в конфигурационные файлы агентов, не затирая ваши существующие настройки и сохраняя порядок ключей:

  1. Claude Code (~/.claude/settings.json): прописываются хуки на события UserPromptSubmit, PreToolUse, PostToolUse, Notification, Stop и SessionEnd. Путь к бинарнику записывается с прямыми слэшами (/), так как Claude Code вызывает хуки через окружение bash.
  2. Codex (~/.codex/config.toml): прописывается обработчик в поле notify.
  3. Cursor (~/.cursor/hooks.json): прописываются хуки на beforeSubmitPrompt, afterFileEdit, afterShellExecution, stop и sessionEnd.
  4. Kimi Code (~/.kimi-code/config.toml): записи [[hooks]] для TurnStarted, UserPromptSubmit, PreToolUse, PostToolUse, PermissionRequest, Stop, StopFailure, Interrupt и SessionEnd, включая фоновые ходы и ожидание разрешений.

Сам polynya-agents.exe не висит в памяти постоянно: агент вызывает его на событии, бинарник за пару миллисекунд кидает JSON в канал острова и сразу закрывается (если остров не запущен - сразу выходит, причем всегда с кодом успеха: ошибка модуля не должна мешать агенту).


3. Долгие команды терминала и клавиши Lock

  • Долгие команды в терминале. Если вы запустили долгую сборку или скрипт в Windows Terminal или встроенном терминале VS Code и переключились в другое окно, по завершении команды остров покажет чип с названием процесса, временем выполнения и результатом (галочка или крестик), например: cargo build · 48 с.
    • Не требует установки плагинов в PowerShell / bash / zsh: отслеживание включается автоматически в момент ухода фокуса из окна терминала через дерево дочерних процессов ConPTY (RegisterWaitForSingleObject). Цепочка вроде cargo build && cargo test даст одно итоговое уведомление.
    • Если команда завершилась, пока вы смотрели в само окно терминала, уведомление не дублируется.
    • Порог срабатывания настраивается в меню (Выкл. / 10 / 30 / 60 с) или ключом terminal_notify в config.ini (по умолчанию 10 с).
  • Caps Lock и Num Lock. Переключение режимов отслеживается через низкоуровневый Raw Input (без глобальных клавиатурных хуков, которые задерживают ввод в системе) и выводит короткий чип состояния.

4. Системные уведомления Windows (экспериментальный модуль notify)

Модуль notify перехватывает системные тосты всех приложений через UserNotificationListener, добавляет их в общий стек острова (до 5 системных уведомлений одновременно, срок жизни чипа - 10 с) и показывает новое уведомление компактной выпадашкой из панели задач (на 5 с) вместо стандартного громоздкого баннера Windows.

Модуль намеренно помечен как экспериментальный и по умолчанию выключен из-за двух фундаментальных ограничений самой ОС Windows 11:

Ограничение 1. Идентичность пакета (зачем нужен UAC при установке)

В Windows API UserNotificationListener доступен только процессам, у которых есть Package Identity (идентичность пакета MSIX).

  • Чтобы не заставлять пользователя покупать сертификаты подписи кода или включать режим разработчика, Polynya использует неподписанный sparse-пакет ("паспорт") Polynya.Notify (~25 КБ, вшит в ядро), который ссылается на бинарник модуля во внешней папке.
  • В Windows 11 регистрация неподписанного пакета с исполняемым файлом требует разового подтверждения прав администратора (без него система возвращает ошибку 0x80073D2B).
  • При нажатии "Установить" в настройках (или вызове polynya notify-setup) запрашивается UAC только для регистрации пакета, а сам остров продолжает работать от обычного пользователя. При выключении модуля пакет удаляется автоматически уже без прав админа.

Ограничение 2. Подавление дублирующих баннеров Windows (ShowBanner)

В публичном WinRT API нет документированного метода "скрыть всплывающий баннер чужого приложения, но оставить уведомление в Центре уведомлений" (SuppressPopup работает только для своих тостов, а RemoveNotification удаляет уведомление отовсюду). Если ничего не делать, каждое сообщение всплывет дважды: сначала стандартным окном Windows, и тут же - выпадашкой из острова.

Как это решено:

  • Модуль точечно ставит значение ShowBanner = 0 в пользовательской ветке реестра HKCU\Software\Microsoft\Windows\CurrentVersion\Notifications\Settings\<AUMID> - это ровно тот же тумблер "Показывать баннеры уведомлений", что и в системных Параметрах Windows. Системный звук уведомления при этом сохраняется, и само сообщение остается в Центре уведомлений.
  • Трогаются только те приложения, от которых реально приходили уведомления, а исходные значения сохраняются в бэкап (%APPDATA%\Polynya\banners.txt и banners-restore.reg). Если вы сами раньше отключили баннеры какому-то приложению в Windows, модуль его не трогает (покажет только тихий чип без выпадашки). Если вы вернете баннеры приложению в Параметрах Windows во время работы модуля - ваш выбор уважается, модуль отпускает это приложение.
  • 4 уровня защиты и автоматического отката:
    1. При штатном закрытии модуля или выключении его в настройках все значения ShowBanner сразу возвращаются как было.
    2. Модуль следит за процессом ядра: если закрыть polynya.exe, модуль сам откатит реестр и завершится.
    3. Если упадет сам модуль, откат выполнит ядро.
    4. На случай внезапного отключения питания или жесткого убийства обоих процессов через Диспетчер задач: в HKCU\...\RunOnce\PolynyaBanners прописывается команда reg import бэкапа - при следующем входе в систему сама Windows восстановит все баннеры даже без запуска Polynya.
  • Если вы не хотите, чтобы модуль менял ShowBanner, выключите в настройках переключатель "Скрыть системные баннеры" (notify_banners = system в config.ini) - тогда стандартные тосты Windows останутся на месте, а остров будет просто дублировать их компактными чипами в панели задач.