First pre-release toward v0.12.0. Built from master; does not include the in-progress horizontal episode-rail work.
🧩 Headline: Plugin Platform
Mydia now has a WebAssembly plugin platform — extend your instance with sandboxed plugins instead of waiting for features to land in core.
- Sandboxed by default. Plugins are WASM components (wasmtime via Wasmex), each run in a fresh, isolated instance with no filesystem, network, or stdio unless you explicitly grant it. Network egress is SSRF-gated against a per-plugin exact-hostname allowlist (no wildcards).
- Capability-gated. Grants live server-side, not in the plugin manifest — you install, review, approve, and revoke from the admin UI. Capabilities include: react to library/playback/download events, read curated library + watch data, make allowlisted HTTP calls, persist key/value state, run on a schedule, hold per-user OAuth connections (tokens are injected by the host — the plugin never sees them), and write back watched state.
- Two plugins ship in the box:
- Webhook Notifier — posts when media is added or a download completes, to Discord, ntfy, or any custom webhook (templated body, headers, query params).
- Simkl Sync — two-way watched-state sync with Simkl: pulls your Simkl history in and pushes what you watch in Mydia back out, via per-user OAuth device-flow, on playback and every 30 minutes.
- Write your own in Rust today via the
#[mydia::plugin]SDK; the platform is WASM-component-based and language-agnostic by design, with more languages planned. - Admin tooling: install/approve/revoke, per-plugin settings, live activity-log timeline with network activity and a Test button.
See docs/plugins/ for authoring, manifest, and cookbook guides.
🎯 Unified release ranking with soft penalties
Automatic movie search, automatic TV search, and the manual search dialog now share one ranking engine — so the "best" release you see in the manual dialog is exactly what automatic search would grab. Previously the three paths built options separately and could even read settings from different places (movie vs. TV searches could rank the same release differently).
- Hard filters became soft penalties. Size, seeder, and ratio limits no longer silently delete releases — they push weak releases down the list but keep them selectable. Fewer "no releases found" dead-ends: e.g. an episode search where every result is a season pack can now grab the penalized pack instead of giving up.
- Identity stays decisive. A wrong season/episode (or a TV pattern in a movie search) gets a large tier-separating penalty, so a correct match always wins — but the mismatch remains a selectable last resort instead of vanishing.
- Transparency. Releases that were penalized-but-kept show a distinct "Penalized" state in the Activity view, with a per-release breakdown of the size/seeder/identity deductions, so you can see why something ranked low.
- Genuinely bad/fake/malicious releases, user-blocked tags, and wrong-show title mismatches are still hard-rejected.
Note: a quality profile that set
min_ratioonly under the legacyruleskey no longer affects ranking —min_ratiois now read fromquality_standards.
🎉 Other New Features
- Player UI revamp: liquid-glass depth + token-driven glass chrome (#213, #215)
- Watched-status actions: season-unwatched, mark-up-to-watched, overflow menus (#214)
- Download path mapping for remote/debrid clients (#198)
- Per-library TV metadata source selection (#183)
- Download match correction (#182)
- Downloads list sorting and deletion (#172); delete buttons now remove files from disk (#191)
- Crash-report widget revamp (#193)
- Unified FlareSolverr configuration UI (#185)
🐛 Bug Fixes
- Playback progress for partial-duration HLS streams (#206); stall-detection resilience (#207)
- macOS appcast auto-update (#209)
- Long metadata truncation (#211)
- Download progress rounding (#204)
- Surface import failures and dedupe grabs (#200); cross-season duplicate downloads (#184)
- Cardigann expired FlareSolverr session handling (#195)
- TVDB Portuguese translation code + TV metadata language (#196, #197)
- OIDC user role updates (#170)
- Relay crash-report fingerprinting (#188)
🔧 Technical Changes
- Migrate local development to devenv; drop the Docker dev path (#216)
- Elixir 1.20 upgrade (#181); LiveView 1.2 upgrade (#205); Iroh upgrade to 1.0.0 (#203)
- Enforce quality gates; release-parser consolidation (#186, #187)
- Harden CI test jobs against transient Nix/cargo flakes (#218)
- Fix iOS TestFlight upload on prerelease tags (CFBundleShortVersionString) (#220)
🚀 Deployment Notes
- Pre-release: Docker images are tagged
beta, notlatest. - Dev workflow now uses devenv (
./dev ...); seedocs/development/setup.md.
Full Changelog: v0.11.1...v0.12.0-beta.3