From 450f9fe1eedf8764e1511ae0592099feb1adf0a0 Mon Sep 17 00:00:00 2001 From: "alexei.dolgolyov" Date: Tue, 19 May 2026 01:34:36 +0300 Subject: [PATCH] chore: release v0.2.7 --- RELEASE_NOTES.md | 26 ++++---------------------- package-lock.json | 4 ++-- package.json | 2 +- pyproject.toml | 2 +- 4 files changed, 8 insertions(+), 26 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index b7ca3e9..9c94404 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,25 +1,8 @@ -## v0.2.6 (2026-05-18) +## v0.2.7 (2026-05-19) -### Features +### Bug Fixes -- **Foreground-window tracker (cross-platform):** New `/api/foreground` endpoint plus live `foreground` / `foreground_update` messages on the existing WebSocket feed. Windows uses a ctypes `GetForegroundWindow` probe with HANDLE-correct `argtypes` so 64-bit window handles aren't truncated; macOS uses AppKit's `NSWorkspace.frontmostApplication`; Linux uses Xlib's `_NET_ACTIVE_WINDOW` (Wayland sessions return a structured "unavailable" so the UI can render gracefully). Each platform has a TTL cache and per-platform fallbacks. ([61cdce9](https://git.dolgolyov-family.by/alexei.dolgolyov/media-player-server/commit/61cdce9)) -- **Browser page-title surfacing:** When the foreground process is a recognised browser, the window title is stripped of the trailing browser-name suffix and exposed as `browser_page_title` alongside `is_browser`. Optional UIA-based URL extraction sits behind the `MEDIA_SERVER_BROWSER_UIA` env flag (off by default — Chromium browsers keep their accessibility tree dormant unless something asks, and enabling it has a measurable cost). ([61cdce9](https://git.dolgolyov-family.by/alexei.dolgolyov/media-player-server/commit/61cdce9)) -- **Foreground card in the Web UI:** New editorial card under the monitor list on the Display tab renders process name, window title, fullscreen / minimized / monitor chips, the browser block when applicable, exe path, PID, started-ago, geometry, and platform. 16px inter-section gap matches the Settings cadence. 25 new i18n keys added to both `en.json` and `ru.json`. ([61cdce9](https://git.dolgolyov-family.by/alexei.dolgolyov/media-player-server/commit/61cdce9)) -- **WebSocket integration:** The existing 1s status loop now polls foreground every tick, broadcasts `foreground` on connect, and emits `foreground_update` only when user-visible fields actually change — geometry deltas alone don't spam the channel. ([61cdce9](https://git.dolgolyov-family.by/alexei.dolgolyov/media-player-server/commit/61cdce9)) - -### Security - -- **Loopback-by-default in the shipped config:** `config.example.yaml` now defaults `host: 127.0.0.1`. The server still refuses to bind a non-loopback interface without either `api_tokens` configured or an explicit `allow_lan_without_auth: true` opt-in — this hardens fresh installs where a user copies the example config verbatim. ([0cf49de](https://git.dolgolyov-family.by/alexei.dolgolyov/media-player-server/commit/0cf49de)) - -### Reliability - -- **Diagnosable silent boot failures:** Pre-uvicorn fatal errors (config parse failures, port conflicts, missing dependencies on Windows) are now mirrored to `startup-errors.log` in the config directory. Previously, launches via `wscript`/`pythonw` (the hidden Startup-folder shortcut path) had no console attached, so any startup crash was effectively invisible — the user just saw "nothing happened". ([0cf49de](https://git.dolgolyov-family.by/alexei.dolgolyov/media-player-server/commit/0cf49de)) - ---- - -### Development / Internal - -- **Lint cleanup:** Sorted the Xlib import in `foreground_service.py` so `ruff check` is clean. Same module, no behaviour change. +- **Display tab sliders + accent picker now respond to clicks/drags:** Both the brightness and contrast sliders on the Display tab, and the accent-color picker in the header, were rendering dynamic HTML with inline `oninput` / `onchange` / `onclick` attributes — every one of which the server's strict `script-src 'self'` CSP silently dropped. The result: brightness and contrast couldn't be changed from the WebUI at all, and picking a custom accent did nothing. Replaced the inline attributes with `data-*` markers and wired proper `addEventListener` calls (delegated on the slider container, direct on the accent dropdown), so the controls work under the strict CSP without any `unsafe-inline` / `unsafe-hashes` relaxation. ([e1c8474](https://git.dolgolyov-family.by/alexei.dolgolyov/media-player-server/commit/e1c8474)) --- @@ -28,7 +11,6 @@ | Hash | Message | Author | |------|---------|--------| -| [61cdce9](https://git.dolgolyov-family.by/alexei.dolgolyov/media-player-server/commit/61cdce9) | feat(foreground): track topmost process + browser page title | alexei.dolgolyov | -| [0cf49de](https://git.dolgolyov-family.by/alexei.dolgolyov/media-player-server/commit/0cf49de) | fix(config): secure-by-default loopback bind and startup-error logging | alexei.dolgolyov | +| [e1c8474](https://git.dolgolyov-family.by/alexei.dolgolyov/media-player-server/commit/e1c8474) | fix(csp): wire display sliders and accent picker without inline on* | alexei.dolgolyov | diff --git a/package-lock.json b/package-lock.json index 1138594..3b2b820 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "media-server-frontend", - "version": "0.2.6", + "version": "0.2.7", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "media-server-frontend", - "version": "0.2.6", + "version": "0.2.7", "devDependencies": { "esbuild": "^0.27.4" } diff --git a/package.json b/package.json index af5ff12..abc8431 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "media-server-frontend", - "version": "0.2.6", + "version": "0.2.7", "private": true, "description": "Frontend build tooling for media server WebUI", "scripts": { diff --git a/pyproject.toml b/pyproject.toml index 35ca456..41216b7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "media-server" -version = "0.2.6" +version = "0.2.7" description = "REST API server for controlling system-wide media playback" readme = "README.md" license = { text = "MIT" }