Repository navigation
Releases
OrbitFM v0.21.0-rc.3
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
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_RULES14→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
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в jobpackagingпокрывает новый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
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.0drv_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
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 (только аудио-радио, mpvload-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
Сборка под 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
Патч вывода после живой приёмки 0.20.0-rc.2 на машине владельца. Команды,
схемы файлов и раскладка страницы «Интеграции» не меняются: перестают
расходиться с реальностью только сообщения установщика и статуса.
Исправлено
orbitfm integration status <цель>больше не печатает строкукаталог:там,
где каталога нет: цельnoctaliaне создаёт файлов, и путь вела в
несуществующий~/.config/omarchy/orbitfm/targets/noctaliainstall 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
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) - Отказ внешней оболочки не превращается в тихий успех:
installnoctalia
валится на причине, а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
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
Локальная статистика прослушивания (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 языках каталога
Руководство пользователя — в вики проекта.