Skip to content

Releases

OrbitFM v0.21.0-rc.3

OrbitFM v0.21.0-rc.3 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 10 Nov 01:31

PATCH: исправления после приёмки rc.2. Новых настроек нет, схема статуса и IPC
не меняются; правки касаются окон предупреждения и настроек, лока сна и CI.

Изменено

  • Окно предупреждения — самостоятельная поверхность. RootSurface::Warning
    с заголовком OrbitFM · Sleep Warning, размером 420×320 (минимум 360×280),
    без рамки и прозрачностью; UiIntent::Warn, ParkOutcome::Warn,
    WindowState::request_warning и is_open. При припаркованном процессе
    предупреждение открывается отдельным прогоном, а не модалкой стола; Esc и
    закрытие окна — «Отменить» (ADR-0058).
  • Семантика корня настроек. Esc и закрытие окна настроек закрывают только
    настройки и не показывают стол; смена режима из настроек сначала закрывает
    их; вложенные настройки и предупреждение не создаются, когда корень уже
    Settings/Warning (ADR-0053).
  • Единый отсчёт остатка. sleep.remaining_secs в status --json и
    подписи трея берут display_seconds — те же секунды, что кнопка часов
    (ADR-0057), без расхождения на последней минуте.

Исправлено

  • macOS: caffeinate -t получает остаток таймера (вверх до секунды, минимум 1)
    вместо 0, который означал «без таймаута»; при смене таймера лок
    перевзводится (ADR-0054).
  • Лок сна: отказ acquire и смерть носителя кэшируются до смены таймера,
    настройки или состояния эфира — повторных попыток на каждом тике нет;
    quit() снимает лок.
  • CI и release: установка MSYS2-пакетов вынесена из msys2/setup-msys2 в шаг
    с pacman --noconfirm --needed --disable-download-timeout и повтором —
    флейк «Operation too slow» больше не валит сборку.

Руководство пользователя — в вики проекта.

OrbitFM v0.21.0-rc.2

OrbitFM v0.21.0-rc.2 Pre-release
Pre-release

Choose a tag to compare

@code-warlord-dev code-warlord-dev released this 06 Nov 18:29

MINOR: настройки стали настоящим отдельным окном, добавлен полноценный ритуал сна
(ингибирование ОС, отсчёт, действие, предупреждение, фейд). Меняется IPC, схема
статуса, структура окон, аудио-воркер и правила WM, поэтому минор.

Добавлено

  • ADR-0053…0058 — окно настроек как отдельное окно, запрет сна на время таймера,
    действие по истечении, затухание звука, отсчёт оставшегося времени, экран предупреждения.
  • Окно настроек как immediate viewport поверх стола (show_viewport_immediate):
    три размера авто-подбора (Compact 420×560, Medium 760×544, Wide 1040×720), заголовок
    несёт вариант для правил WM, геометрия не персистится. Убраны scrim/Area/
    settings_rect/blocks_point — настройки не блокируют глобус.
  • Ритуал сна: systemd-inhibit (Linux, дочерний процесс), caffeinate (macOS),
    SetThreadExecutionState (Windows), ORBITFM_POWER_DRY_RUN=1 для диагностики без
    spawn. Действие по истечении: nothing/suspend/power-off через busctl/loginctl
    (Linux), pmset/osascript (macOS), SetSuspendState/InitiateSystemShutdownExW
    (Windows).
  • Фейд звука перед стопом: линейно в дБ (D=45, по умолчанию 300 с, шаг ~20 Hz),
    конфликт с ручной громкостью разрешён в пользу пользователя.
  • Экран предупреждения за минуту до действия: кольцо SEGMENTS=96, рампы
    жёлтый→зелёный / красный→жёлтый, кнопка «Отменить» (отменяет действие, не таймер),
    Esc = Cancel.
  • IPC: подкоманды sleep action|fade|inhibit|warning, ответы ok sleep ….
  • status --json: sleep.{inhibited,action,warning,fade_seconds} +
    settings_open, схема 1 сохранена.
  • Правила WM: HYPRLAND_RULES 14→18 (три size под настройки + Sleep Warning),
    зеркало в wm-configs/orbitfm-hyprland.conf и wm-configs/orbitfm-niri.kdl,
    тесты на зеркальность и дрейф сниппета.

Изменено

  • src/session/window.rs: RootSurface { Desk(WindowMode), Settings(SettingsSize) },
    UiIntent::Settings, open_settings(origin) (Desk → потомок, Parked → intent).
  • src/ui/layout.rs: убраны SETTINGS_MODAL, settings из DeskLayout и
    blocks_point, функция settings_rect().
  • src/ui/settings_panel.rs: убран крестик и Esc из шапки (окно теперь отдельное).
  • src/audio/worker.rs: AudioCommand::StartFade/CancelFade, рабочий фейд
    AudioWorker (~20 Hz, fade_gain).
  • src/power/* (новый модуль): InhibitBackend, InhibitionGuard (Drop),
    PowerInhibit::acquire/perform, бэкенды linux/macos/windows/fake.

Исправлено

  • draw_settings при EmbeddedWindow — старая модалка + warn! (бэкенд без
    мультивьюпортности не ломается).

Руководство пользователя — в вики проекта.

OrbitFM v0.21.0-rc.1

OrbitFM v0.21.0-rc.1 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 06 Nov 03:05

MINOR: поддержка macOS пересобрана как заявка, которую можно проверить, — Intel и Apple
Silicon на равных условиях. Меняется код приложения (диагностика рендера), упаковка и CI,
поэтому минор, а не патч. Нотаризации по-прежнему нет, артефактов по-прежнему шесть.

Добавлено

  • ADR-0052 «Матрица поддержки macOS» — единственный источник истины про macOS: пол
    macOS 13.0 Ventura для обеих арок, аппаратная нижняя граница MacBookAir8,2
    (MacBook Air Retina 13″ 2019, Intel UHD Graphics 617, 8 ГБ), два per-arch DMG с
    обоснованным отказом от universal2, ad-hoc подпись без нотаризации, libmpv
    0.40.0_4 на Intel как заморозка с названной датой пересмотра (август 2027 или
    выход macOS 13 из бутылочной матрицы Homebrew) и таблица «чем обеспечено / чем
    подтверждено на живом железе / не проверено».
  • src/render: структура AdapterReport (только строки и скаляры, без wgpu-типов) и её
    Display — одна строка orbitfm render: … с выбранным адаптером, драйвером,
    target_format, двумя лимитами, флагом анизотропии и списком всех доступных
    GPU
    . src/app.rs пишет её на info сразу после того, как cc.wgpu_render_state
    оказался Some, — до создания GlobeRenderer, чтобы строки остались в логе и если
    создание глобуса упадёт на неподдерживаемом лимите. Ветка None вместо молчания
    получает warn! с причиной. Строка — диагностика, а не контракт: status --json и
    docs/interfaces/ не менялись.
  • packaging/macos/check-app-arch.sh — гейт архитектуры как отдельный проверяемый
    инструмент: каждый Mach-O в Contents/MacOS и Contents/Frameworks обязан иметь
    ровно объявленную арку по lipo -archs. Ловит fat-бинарник, Rosetta-подмену и
    чужеродный dylib из машины сборки; падает, если не проверено ни одного файла.
  • CI: job macos-intel на macos-15-intel — fmt, clippy --all-targets -D warnings, cargo test --all-targets и cargo build --release --locked на Intel.
    Раньше x86_64 только собирал DMG и не исполнял ни одного теста.
  • CI и release: два новых негативных fixture у новых гейтов — вызов
    check-app-arch.sh с аркой, которой в бандле нет (обязан упасть на arch FAIL), и
    Info.plist с LSMinimumSystemVersion=12.0 при Mach-O, требующем 13.0 (обязан
    упасть на «требует macOS»). Оба печатают маркер («… fixture отработал»), чтобы
    зелёный шаг нельзя было спутать с пропущенным.
  • README: бейдж macOS 13+ · x86_64 · arm64 и секция «Матрица поддержки macOS».

Изменено

  • packaging/macos/build-dmg.sh: архитектура — обязательный параметр
    --arch x86_64|arm64 вместо uname -m; без него или с неизвестным значением скрипт
    печатает usage и выходит с кодом 2. Имя DMG, путь бинарника и гейт арки выводятся из
    объявленного значения.
  • packaging/macos/check-min-os.py: предел по умолчанию читается из
    Contents/Info.plist → LSMinimumSystemVersion, --max остаётся явным
    переопределением для разбора чужих артефактов. Проверка становится односторонней:
    если plist обещает 13.0, а хоть один Mach-O требует 14.x — сборка падает. Обход
    Frameworks теперь рекурсивный, как у audit-app-dylibs.sh; в вывод печатается
    источник предела.
  • Число 13.0 живёт в одном месте — packaging/macos/Info.plist.in: оттуда же
    -mmacosx-version-min для VapourSynth-заглушки (раньше оно было зашито в скрипте
    отдельно, и заглушка могла потребовать macOS новее, чем обещает бандл).
  • CI и release: MACOSX_DEPLOYMENT_TARGET=13.0 в шагах сборки Rust на обеих арках — minos
    основного бинарника становится следствием решения проекта, а не дефолтом целевой
    тройки; check-min-os.py вызывается без жёсткого --max, а строка «самая новая
    минимальная macOS» попадает в job summary релиза.
  • Вики: --arch в разделах сборки из исходников, ловушка uname -m под Rosetta,
    протокол съёма orbitfm-render.log, убран потолок «M1, M2, M3, M4».
  • packaging/linux/org.modernbyte.OrbitFM.metainfo.xml: <release> догнал релизы —
    было застревание на 0.20.0-rc.4.

Исправлено

  • README утверждал то, чего не было. Строка «Собрано и протестировано в CI … приёмки
    на живом железе не было: MSI, DMG, Now Playing на macOS» противоречила docs/ROADMAP.md:
    именно живые отчёты с MacBookAir8,2 (macOS 14.8.9) вскрыли дефекты rc.3, rc.4 и rc.5.
    Введён уровень «Подтверждено на живом железе macOS» — с явной границей: что та машина
    доказала (бандл там реально запускали, и это увидело дефекты графа зависимостей) и чего
    она не доказывает (успешный старт исправленного бандла и первый кадр на UHD 617).
  • Оборванная фраза о платформенных требованиях в orbitfm_srs.md заменена ссылкой на
    ADR-0052 как единственный источник таких требований.
  • Сборка релиза встала на AppImage. appimagetool качался из канала continuous,
    который перезаписывается под прежним URL: пересборка upstream в 00:47 UTC разминулась
    с зафиксированным дайджестом, и гейт остановил публикацию. Инструмент переведён на
    неизменяемый релизный тег 1.9.1 (ассет не менялся с 2025-12-04), дайджест
    перепринят; linuxdeploy остаётся на continuous с дайджестом — обоснование и цена
    решения в ADR-0011, «Уточнение (2026-11-06): пиннинг appimagetool на релизный тег».

Тесты

  • Три unit-теста на формат диагностической строки: полный снимок при одном адаптере,
    два адаптера печатаются оба, без DownlevelFlags::ANISOTROPIC_FILTERING — no.
    Исполняются на Linux, защищают разбор строки, а не выбор GPU.
  • bash -n в job packaging покрывает новый check-app-arch.sh.
  • cargo test --all-targets: 674 passed, 0 failed.

Документация

  • docs/modules/04-render-globe.md: §2.1 «Наблюдаемость: какой GPU реально выбран» и
    найденная при проектировании деталь — в wgpu 30 анизотропная фильтрация это не бит
    Features, а DownlevelFlags::ANISOTROPIC_FILTERING, и для глобуса это единственная
    downlevel-зависимость.
  • Уточнения в ADR-0002 (пол платформы наследуется от eframe/wgpu, glow-fallback нет),
    ADR-0011 (DMG и пол — по ADR-0052, гейт арки) и ADR-0026 (чем подтверждён Now Playing).
  • docs/CONTRIBUTING.md: тесты исполняются и на Intel-раннере; docs/ROADMAP.md,
    docs/VERSIONMAP.md, вики и README приведены в согласие с фактами.
  • .agents/skills/orbitfm-gui/SKILL.md: правило «при проблемах с прозрачностью допустим
    fallback на glow» противоречило принятому ADR-0002 (уточнение 2026-11-06) — исправлено
    в той же задаче, как требует docs/AGENTS.md § 2.2; туда же добавлены ссылка на
    ADR-0052 и способ снимать выбранный GPU.

Руководство пользователя — в вики проекта.

OrbitFM v0.20.0-rc.6

OrbitFM v0.20.0-rc.6 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 04 Nov 22:10

PATCH-пакет: OrbitFM.app для macOS всё ещё не запускался — 0.20.0-rc.5 заменил один
dyld-аборт другим. Код приложения не менялся, чинится упаковка и CI-гейты.

Исправлено

  • macOS: краш запуска EXC_CRASH (SIGABRT), Namespace DYLD, Code 4 Symbol missing,
    Symbol not found: _getVSScriptAPI, Referenced from: .../Contents/Frameworks/libmpv.2.dylib,
    Expected in: .../liborbitfm-vsscript-stub.0.dylib (MacBookAir8,2, macOS 14.8.9; nm по
    опубликованным DMG показывает ту же картину на arm64). Заглушка
    0.20.0-rc.5 экспортировала выдуманное orbitfm_vsscript_stub_init, тогда как Mach-O с
    two-level namespace связывает импорт с конкретной библиотекой из load-команды, и dyld ищет
    именно _getVSScriptAPI.
  • build-dmg.sh больше не зашивает имя символа: набор выгрузок выводится из самого артефакта —
    пересечение неразрешённых импортов всех Mach-O бандла (nm -u) с экспортами удаляемых
    libvapoursynth* (nm -g) — и заглушка собирается ровно с этим набором (на текущих бутылках
    Homebrew это одна getVSScriptAPI). Сборка падает, если заглушка не покрывает хотя бы одно
    вычисленное имя, если символ выгружен не как функция (T) или если имя нельзя определить из C.
    getVSScriptAPI возвращает NULL: в mpv 0.40.0 drv_vss_init трактует NULL как
    «VapourSynth недоступен» (MP_FATAL + отказ инициализации фильтра), а вызов происходит только
    при создании фильтра vapoursynth (vf_vapoursynth_create). OrbitFM — только аудио-радио, mpv
    с load-scripts=no — этот фильтр не создаёт.
  • build-dmg.sh не предполагает единственную VapourSynth-ссылку в libmpv: install_name_tool -change ретаргетит фактическую load-команду, а при нескольких libvapoursynth* в бандле
    сборка падает, вместо того чтобы выбрать первую наугад.

Добавлено

  • packaging/macos/smoke-launch.sh — проверка запуска .app: orbitfm --version обязан
    завершиться с кодом 0 и напечатать версию из Info.plist. --version завершает процесс до GUI
    и IPC, а dyld разрешает граф зависимостей до main() — этого достаточно, чтобы отличить
    рабочий бандл от аборта. Вызывается из build-dmg.sh после codesign, из smoke-теста
    DMG в CI и из release smoke-теста перед публикацией DMG.

Тесты

  • CI (macos (DMG, …)) и release: артефакт проверяется не только аудитом путей, но и запуском.
  • Регресс-гард launch-гейта: negative fixture, повторяющий ровно состояние 0.20.0-rc.5 —
    заглушка пересобирается без VapourSynth-экспортов, и smoke-launch.sh обязан на ней упасть с
    Symbol not found. Если гейт это пропускает, он ничего не проверяет.
  • Шаг «Check macOS packaging scripts syntax» покрывает bash -n новый скрипт.

Документация

  • В шапке audit-app-dylibs.sh зафиксировано ограничение: аудит сверяет только load-команды и
    не проверяет наличие связанных символов — 0.20.0-rc.5 этот аудит прошёл и abort'ился.
  • Версия поднята до 0.20.0-rc.6 (схема vMAJOR.MINOR.PATCH[-rc.N]); release notes собираются из
    секции [0.20.0-rc.6] в docs/CHANGELOG.md.

Руководство пользователя — в вики проекта.

OrbitFM v0.20.0-rc.5

OrbitFM v0.20.0-rc.5 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 04 Nov 00:00

PATCH-пакет: краш macOS при запуске OrbitFM.app (dyld / VapourSynth / Python.framework).
Код приложения не менялся — чинится упаковка macOS.

Исправлено

  • macOS: OrbitFM.app больше не крашится на старте (EXC_CRASH (SIGABRT), Namespace DYLD, Code 1 Library missing; Library not loaded: /tmp/*/Python.framework/Versions/3.13/Python,
    Referenced from: .../Contents/Frameworks/libvapoursynth-script.0.dylib). libmpv из бутылок
    Homebrew собирается с VapourSynth, а dylibbundler переносит туда же цепочку
    libmpv → libvapoursynth-script → Python.framework; на машине пользователя нет Python 3.13,
    поэтому dyld abort'ил до main(). OrbitFM (только аудио-радио, mpv load-scripts=no) VapourSynth
    не использует, поэтому ссылку libmpv → VapourSynth в build-dmg.sh заменяют на локальную no-op-заглушку
    (liborbitfm-vsscript-stub.0.dylib), реальный libvapoursynth* удаляют из Contents/Frameworks, и
    Python.framework в бандл не попадает и не требуется.

Добавлено

  • packaging/macos/audit-app-dylibs.sh — аудит .app: FAIL при абсолютных путях /tmp/, /Users/,
    /opt/homebrew/, /usr/local/, ссылках на Python.framework, нез разрешаемых @rpath-ссылках и
    наличии libvapoursynth* в Frameworks. Вызывается из smoke-теста DMG в CI/release и из
    build-dmg.sh перед codesign.

Тесты

  • CI/release (macos (DMG, …)): smoke-test прогоняет аудит на свежем артефакте (зелёный) и падает на
    специально сломанном fixture (ссылка через install_name_tool → /tmp/Python.framework/Versions/3.13/Python)
    — регресс-гард для краша запуска.

Документация

  • Версия поднята до 0.20.0-rc.5 (схема vMAJOR.MINOR.PATCH[-rc.N]); release notes собираются из
    секции [0.20.0-rc.5] в docs/CHANGELOG.md.

Руководство пользователя — в вики проекта.

OrbitFM v0.20.0-rc.4

OrbitFM v0.20.0-rc.4 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 03 Nov 22:35

Сборка под Intel Mac и возврат совместимости с macOS 13. Код приложения не
менялся: релиз нужен, чтобы опубликовать второй macOS-артефакт и проверять обе
архитектуры в CI.

Добавлено

  • OrbitFM-<версия>-macos-x86_64.dmg — нативная сборка под Intel Mac на
    раннере macos-15-intel; arm64-DMG остаётся для Apple Silicon. Universal2
    не публикуется: libmpv бандлится архитектурой раннера, а universal-сборка
    mpv/ffmpeg в CI не поддерживается.
  • Матрица macOS в ci.yml и release.yml: обе архитектуры собираются
    параллельно, smoke-тест проверяет file бинарника, codesign --deep --strict и отсутствие ссылок на Homebrew.
  • SHA256SUMS и релизный job принимают шесть артефактов вместо пяти.

Исправлено

  • macOS 13.0 и новее снова соответствует действительности. Раньше
    brew install mpv на раннере клал в DMG библиотеки, собранные под macOS
    раннера: у arm64-сборки 0.20.0-rc.3 все 49 dylib'ов требовали macOS 26.0,
    хотя LSMinimumSystemVersion обещал 13.0. Теперь libmpv и зависимости
    ставятся из закреплённых бутылок Homebrew, собранных под macOS 13
    (mpv 0.40.0), для обеих архитектур.
  • packaging/macos/check-min-os.py — гейт в CI и релизе: проверяет
    LC_BUILD_VERSION/LC_VERSION_MIN_MACOSX приложения и каждой библиотеки
    в Frameworks, архитектуру и предел 13.0, чтобы такая рассинхронизация не
    повторилась.

Документация

  • README и вики: отдельные страницы установки для Apple Silicon и Intel,
    таблица релизных файлов, проверка архитектуры и разбор ошибки
    «не поддерживается этим компьютером Mac».

Руководство пользователя — в вики проекта.

OrbitFM v0.20.0-rc.3

OrbitFM v0.20.0-rc.3 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 03 Nov 19:51

Патч вывода после живой приёмки 0.20.0-rc.2 на машине владельца. Команды,
схемы файлов и раскладка страницы «Интеграции» не меняются: перестают
расходиться с реальностью только сообщения установщика и статуса.

Исправлено

  • orbitfm integration status <цель> больше не печатает строку каталог: там,
    где каталога нет: цель noctalia не создаёт файлов, и путь вела в
    несуществующий ~/.config/omarchy/orbitfm/targets/noctalia
  • install niri при уже подключённом вручную конфиге больше не врёт: прежде он
    сообщал «добавлена ровно одна строка» и показывал резервную копию
    config.kdl.orbitfm.bak, которой установка не делала. Теперь вывод
    разветвляется по квитанции — обещать снятие строки и ссылаться на копию можно
    только когда строку include добавил установщик. Иначе печатается, кто
    владеет строкой, и что снятие уберёт файл правил, оставив нерабочий include
  • Заметка строки «Интеграции» для niri описывает оба файла — файл правил и
    его подключение, — и больше не предполагает, что строку include добавили мы

Тесты

  • cargo test --locked — 671 зелёный (5 игнорируемых): добавлен тест, что
    вывод обещает снятие строки include только когда строка есть в квитанции
    установки
  • cargo fmt --check, cargo clippy --all-targets -- -D warnings — чисто

Руководство пользователя — в вики проекта.

OrbitFM v0.20.0-rc.2

OrbitFM v0.20.0-rc.2 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 03 Nov 18:21

Noctalia и правила окон становятся целями установщика (ADR-0051): плагин и
оконные правила ставятся кнопкой на странице «Интеграции» той же командой, что
и остальные интеграции, — вместо двух команд noctalia msg и cp из README.
Целей 17. Схема status --json и events не меняется — остаётся 1; схема
квитанции тоже 1, поля аддитивные.

Добавлено

  • ADR-0051 и три новые цели orbitfm integration: noctalia (группа
    «Окружения»), niri и hyprland (новая группа «Правила окон»,
    TargetGroup::Windows); алиасы разбора hypr и hyprctl
  • src/integration/noctalia.rs — регистрация git-источника orbitfm
    (https://github.com/ModernByte/orbitfm) и включение виджета
    modernbyte/orbitfm фиксированным argv через CLI оболочки: файлов у цели нет,
    ничего не скачивается и не копируется. Перед установкой читаются
    plugins list и source list, чтобы не выдать за нашу работу то, что
    включал пользователь; снятие делает disable, убирает только наш источник и
    возвращает прежнюю включённость виджета
  • Цель niri — ~/.config/niri/cfg/orbitfm.kdl из wm-configs/ плюс ровно
    одна строка include "./cfg/orbitfm.kdl" в config.kdl: копия
    config.kdl.orbitfm.bak перед первой правкой, идемпотентность при
    переустановке, снятие убирает ровно свою целую строку. Это единственный
    чужой конфиг, который установщик правит (ADR-0042 §2, ADR-0051 §5)
  • Цель hyprland — ~/.config/hypr/orbitfm.conf и 14 фиксированных правил на
    текущий сеанс через hyprctl keyword windowrulev2 …; hyprland.conf не
    правится, готовую строку source = … показывает установщик и страница
    «Интеграции»
  • Квитанция схемы 1 дополнена аддитивными полями под #[serde(default)]:
    dirs[] (каталоги, созданные установщиком), lines[] (пары «файл + точная
    строка»), source_added и was_enabled; старые квитанции читаются без
    миграции
  • Строка «Правила окон» в группе заголовков страницы и заметка о ручных шагах
    цели в её строке; подпись группы — во всех 16 языках каталога i18n

Исправлено

  • Обнаружение цели больше не кормится собственным следом: снятие цели срезает
    только опустевшие каталоги, которые создал установщик, поэтому
    ~/.config/omarchy, ~/.local/share/gnome-shell и другие каталоги-обманки
    после integration uninstall не держат цель в состоянии «обнаружено»
    (следствие закрыто кодом, пустые каталоги на машине приёмки были убраны
    вручную в rc.1)
  • Отказ внешней оболочки не превращается в тихий успех: install noctalia
    валится на причине, а uninstall кладёт её в заметку расписки
  • Снятие niri не оставляет висячий include без слова: если строку добавили
    не мы (ручное подключение до установки), она остаётся в config.kdl, файл
    правил убирается, а uninstall и строка «Интеграции» сообщают, что строку
    нужно убрать или подключить к своему файлу — иначе niri не разберёт конфиг

Тесты

  • cargo test --locked — 670 зелёных (5 игнорируемых): разбор и алиасы новых
    целей, обнаружение по бинарнику и по каталогу оболочки, срез созданных
    каталогов, одна строка include с копией и полный возврат конфига niri,
    заметка об оставшейся чужой строке, цикл noctalia без файлов,
    фиксированный argv без shell-символов
  • cargo fmt --check, cargo clippy --all-targets -- -D warnings — чисто

Руководство пользователя — в вики проекта.

OrbitFM v0.20.0-rc.1

OrbitFM v0.20.0-rc.1 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 03 Nov 16:32

URL-алиасы станций (ADR-0050) — последний приоритет B ритуалов слушания: если
каталожный адрес станции мёртв, эфир подставляется вручную командой alias, а
станция помечается «ручная ссылка». Плюс честная страница «Интеграции»: подпись
цели строится по автообнаружению, а не только по квитанции. Схема status --json
и events не меняются — остаётся 1.

Добавлено

  • ADR-0050 и интерфейс docs/interfaces/18-aliases.md: алиасы URL станций —
    локальная подмена адреса эфира для stationuuid с пометкой «ручная ссылка».
    Поле aliases в library.json без смены схемы файла, единственная точка
    подмены — StationLibrary::launch_url, куда обращается
    Session::start_station, та же проверка публичности (ярус 1), что у
    каталожного адреса. Экспорт библиотеки и status --json алиасы не содержат;
    ECO не подменяет алиасную станцию
  • Реализация алиасов: хранение в библиотеке (до 200 записей, адрес до 2048
    байт, http/https, отклонение приватных целей с причиной яруса 1),
    применение при запуске, publish gate и sync_media; станция не
    переписывается — статистика, история и click-трекинг остаются по
    stationuuid
  • IPC/CLI alias <uuid> / alias <uuid> <url> / alias <uuid> remove /
    alias list (интерфейс 05) с ответами alias none, ok alias <хост> и
    ok alias removed; браузерный native host команды alias запрещает
    (ADR-0038)
  • Пометка «ручная ссылка» с хостом адреса в строке списка и карточке текущей
    станции — подпись добавлена в каталог i18n на всех 16 языках

Исправлено

  • Страница «Интеграции» в настройках (ADR-0042 §1, ред. 2): для целей, не
    обнаруженных в окружении, первичная подпись — приглушённое «не обнаружено»,
    а не зелёное «установлено»; квитанция на диске больше не выдаёт отсутствие
    оболочки за установленную интеграцию. Дубль заметки «не обнаружено» убран,
    кнопки установки/удаления и семантика квитанций прежние

Руководство пользователя — в вики проекта.

OrbitFM v0.19.0-rc.2

OrbitFM v0.19.0-rc.2 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 03 Nov 09:36

Локальная статистика прослушивания (ADR-0049): сбор, хранение, раздел
«Статистика» в настройках и команды CLI. Счётчики живут только на устройстве.
Схема status --json остаётся 1.

Добавлено

  • ADR-0049 и интерфейс docs/interfaces/17-stats.md: файл stats.json схемы 1,
    учёт только состояния Playing, лимиты списков, внешние потоки, приватность
    без сервера и без аккаунта; контракт разложен по интерфейсам 05/09/10/13 и
    модулю 11
  • Модуль src/stats/ — StatsStore: $XDG_DATA_HOME/orbitfm/stats.json
    (schema, updated_at, stations[], days), до 500 станций и 730 UTC-суток,
    свёртка дублей и доводка пустых countrycode/tags при загрузке, снимок с
    ранжированием топ-10 и окнами 7/30 суток
  • Накопление в Session: сегмент текущей станции, засчитываются только целые
    секунды эфира; сброс порога каждые 30 с, при уходе из Playing, при смене
    станции, при выключении учёта, при stats clear и при выходе процесса;
    в parked-режиме будильник Parked::Stats продолжает копить с закрытым окном
  • Внешний поток получает ключ external:<fnv1a64(url)> вместо безымянной
    станции; теги обрезаются до 128 байт по границе тега
  • IPC stats (строки stats total <seconds>, stats enabled <bool> и топ-5
    станций/стран/тегов), stats --json (сводка схемой 1 с локализованным
    блоком ui) и stats clear с ответом ok stats cleared; неизвестный
    аргумент — ошибка; native host браузера команды запрещает (ADR-0038)
  • Настройка stats_enabled по умолчанию true: старые settings.json без
    поля читаются как включённый учёт и не перезаписываются, set_stats_enabled
    сохраняет только при изменении
  • Категория «Статистика» в окне настроек: итоги «всего / 7 дней / 30 дней»,
    тумблер учёта, «Очистить» в два клика и топ-10 станций, стран и тегов с
    полосами доли; снимок обновляется не чаще раза в секунду и только пока
    открыт раздел
  • Уведомление stats_damaged: повреждённый файл остаётся нетронутым до первой
    успешной записи, счётчики начинаются с нуля и пользователя предупреждают
    один раз за запуск
  • Строки раздела и уведомление во всех 16 языках каталога

Руководство пользователя — в вики проекта.