Перейти к содержимому

Уведомления

Нативные desktop-уведомления, срабатывающие при завершении долгих операций DWE (успех или провал). Уведомления — это пользовательская забота: настройки лежат в файле пользовательского конфига вне проекта (с опциональным переопределением на уровне проекта), а не в workspace.yml.

См. также: Локализация (i18n) — про перевод описаний пользовательских команд и UI-строк.

ОперацияСрабатывает?Условие на операцию
dwe deployдаnotify_deploy_enabled
dwe runдаnotify_run_enabled
dwe restartнет (внутренняя фаза run подавлена через SkipNotify)
dwe stopнет
dwe resetнет
dwe commands <id> (top-level, с notify: true на CommandDef)даnotify_commands_enabled
dwe commands <id> (без notify: true)нет
Под-шаг workflow (последовательный или параллельный)нет — всегда подавляется в рантайме независимо от собственного поля notify:
Действие пайплайна деплоя, вызывающее командунет — то же правило
Daemon-команды (.start / .logs / .stop / .restart)notify: true отвергается на этапе валидации

Правило: уведомление срабатывает для команды, которую вы набрали, а не для любой команды, которую она запускает внутри. У команды, помеченной notify: true и вызванной транзитивно (под-шаг workflow или действие пайплайна), уведомление подавляется рантайм-проверкой SkipNotify.

Валидатор выдаёт info-диагностику, когда может статически обнаружить команду с notify: true, помещённую прямым под-шагом внутри блока parallel: — чисто как раннее предупреждение. Реальное подавление происходит в рантайме и покрывает транзитивные случаи, которые валидатор не видит.

Каждая команда, способная вызвать уведомление, принимает флаг --silent, который подавляет desktop-уведомление для этого одного вызова. Полезно для скриптовых / CI-запусков, где пользователя нет за рабочим местом и он не увидит попап.

Флаг доступен у: dwe deploy run, dwe run, dwe snapshot create, dwe snapshot restore, dwe snapshot rollback, dwe snapshot remove и dwe commands <id>. Это разовое переопределение — пользовательский конфиг и условия на операцию не меняются.

Два файла читаются в следующем порядке приоритета (ниже → выше):

  1. Глобальный пользовательский конфиг в ~/.config/dwe/config на каждой ОС (Linux, macOS, Windows). Никакого нативного для платформы расположения, никакого XDG-отката — один путь везде. Отсутствие файла молча трактуется как пустота. Если DWE когда-нибудь его пишет, режим — 0600.

  2. Переопределение на уровне проекта в <project>/.dwe/config. Директория .dwe/ уже игнорируется DWE через gitignore. Отсутствие файла молча трактуется как пустота.

  3. Переменные окружения переопределяют оба файла (высший приоритет).

Ошибка разбора в любом из файлов всплывает наружу и отключает уведомления для этого запуска (предупреждение логируется через slog); сама операция никогда не блокируется подсистемой уведомлений.

Плоские строки key = value:

  • Только #-комментарии на всю строку — inline #-комментарии вызывают ошибку разбора.
  • Пустые строки игнорируются.
  • Ключи используют строчные буквы, цифры и подчёркивания; точечные ключи отвергаются (notify_telegram_token, не notify.telegram.token).
  • Булевы: true / false.
  • Списки: через запятую.
  • Неизвестные ключи — предупреждения, а не ошибки.
КлючТипПо умолчаниюНазначение
notify_enabledbooltrueГлавный выключатель — когда false, ни одно уведомление не срабатывает
notify_run_enabledbooltrueГейт для dwe run
notify_deploy_enabledbooltrueГейт для dwe deploy
notify_commands_enabledbooltrueГейт для пользовательских команд с notify: true
notify_channelslistnativeСписок backend-имён через запятую; в MVP подключён только native

Каждый ключ имеет соответствующую env-переменную DWE_<UPPER_SNAKE>, которая переопределяет всё, что задано в файлах:

Env-переменнаяПереопределяет
DWE_NOTIFY_ENABLEDnotify_enabled
DWE_NOTIFY_RUN_ENABLEDnotify_run_enabled
DWE_NOTIFY_DEPLOY_ENABLEDnotify_deploy_enabled
DWE_NOTIFY_COMMANDS_ENABLEDnotify_commands_enabled
DWE_NOTIFY_CHANNELSnotify_channels

Булевы env-значения: 1 / true / yes — истинные; 0 / false / no — ложные.

Уведомление срабатывает, только если все следующие условия истинны:

  1. notify_enabled = true (главный выключатель).
  2. Соответствующий per-op ключ равен true (notify_deploy_enabled, notify_run_enabled или notify_commands_enabled).
  3. notify_channels непуст и содержит хотя бы один известный backend (native в MVP).
  4. Окружение интерактивное (см. следующую секцию).
  5. Для dwe commands: CommandDef имеет notify: true и команда — top-level вызов (SkipNotify == false).

Любой промах → молчаливый no-op.

Уведомления короткозамыкаются, когда верно любое из:

  • Переменная окружения CI задана в любое непустое значение.
  • DWE_NONINTERACTIVE задан ровно в 1 или true (чувствительно к регистру; TRUE/True/YES НЕ отключают).
  • stdin не подключён к терминалу (stdout намеренно не проверяется — пайп вывода с сохранённым интерактивным stdin — это ровно тот сценарий, где пассивное toast-уведомление наиболее ценно).

Это означает, что CI-запуски, piped-вывод и скриптовые вызовы никогда не порождают desktop-уведомление, независимо от конфига.

Нативный backend ограничен одним уведомлением одновременно на CLI-процесс. Если демон ОС-нотификатора зависает на предыдущем уведомлении (редко, но наблюдалось на некоторых Linux-сетапах), последующие уведомления внутри этой операции молча отбрасываются и логируются на debug-уровне. Backend применяет внутренний 2-секундный таймаут; вызывающая операция никогда не задерживается в ожидании нотификатора.

macOS использует terminal-notifier, когда он есть в PATH (установка через brew install terminal-notifier), и откатывается на osascript в противном случае. Логотип DWE передаётся как -contentImage, чтобы он рендерился как thumbnail внутри карточки уведомления — современный macOS пин’ит маленький слот app-иконки на bundle-иконку самого terminal-notifier и молча игнорирует override’ы -appIcon. Откат на osascript вообще не может нести кастомную иконку и показывает иконку Script Editor.

Если на macOS уведомления перестают появляться как баннеры, несмотря на то что terminal-notifier -list DWE показывает их как доставленные, демон Notification Center на macOS застрял. Чинится так:

Окно терминала
killall NotificationCenter

Linux использует libnotify через dbus (или notify-send как откат); иконка проходит напрямую как PNG-payload.

Windows использует нативные toast-уведомления со встроенным PNG.

Типичная настройка: уведомлять о деплое и ad-hoc командах, но молчать про inner-loop цикл dwe run.

# ~/.config/dwe/config (одинаково на каждой ОС)
notify_enabled = true
notify_deploy_enabled = true
notify_run_enabled = false # тихо во время inner-loop разработки
notify_commands_enabled = true
notify_channels = native

Заглушить всё глобально, не трогая per-op флаги:

notify_enabled = false

Заглушить только для одного проекта (per-project override в <project>/.dwe/config):

notify_run_enabled = false

Нативный backend рендерит фиксированный, брендированный формат. Имя проекта (когда известно) появляется в заголовке; тело несёт тайминг и, при провале, однострочное усечённое сообщение об ошибке.

ИсходЗаголовокТело
Успех✓ DWE · <project>: <op> succeeded<duration>
Провал✗ DWE · <project>: <op> failed<duration> + (с новой строки) усечённое сообщение об ошибке

Когда у события нет связанного проекта (редко — обычно только синтетические тестовые события), сегмент · <project> опускается и заголовок схлопывается в ✓ DWE: <op> succeeded / ✗ DWE: <op> failed.

Примеры:

✓ DWE · acme-api: deploy succeeded
1m 42s
✗ DWE · acme-api: run failed
3.2s
exit status 1: migration aborted: relation "users" does not exist

Сообщения об ошибках обрезаются до первой строки и усекаются до 200 рун (хвостовое означает усечение). Корзины форматирования длительности: <1sXms, <60sX.Xs, <1hXm Ys, ≥1hXh Ym.

На macOS иконка DWE и имя приложения DWE в баннере уведомления требуют установленного terminal-notifier:

brew install terminal-notifier

Когда terminal-notifier присутствует, beeep делегирует ему, и встроенная иконка DWE и AppName = "DWE" соблюдаются.

Без него beeep откатывается на AppleScript (osascript), который в свежих релизах macOS показывает отправителя как Script Editor и игнорирует иконку. Функциональность не страдает — деградирует только визуальное представление. Текст заголовка (который и так несёт префикс DWE · <project>) остаётся правильным в любом пути.

Linux (libnotify) и Windows (toast) соблюдают встроенную иконку и имя приложения без дополнительной настройки.